This commit is contained in:
pcca-matrix 2025-05-29 19:50:02 +09:30 committed by GitHub
commit a8d32d180c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 652 additions and 210 deletions

View File

@ -149,7 +149,6 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
*pdwData = 0;
WORD w_Buttons = 0;
// WORD w_Axes = 0;
LPCONTROLLER pcController = &g_pcControllers[indexController]; // Still needs to be here, but not as important (comment by rabid)
bool b_Value;
@ -157,11 +156,9 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
long lAxisValueX = ZEROVALUE;
long lAxisValueY = ZEROVALUE;
// Take this info from the N64 controller struct, regardless of input devices
float d_ModifierX = (float)pcController->bStickRange / 100.0f;
float d_ModifierY = (float)pcController->bStickRange / 100.0f;
float d_ModifierX = 0;
float d_ModifierY = 0;
int i;
// Do N64-Buttons / modifiers
@ -210,8 +207,8 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
case MDT_MOVE:
{
LPMODSPEC_MOVE args = (LPMODSPEC_MOVE)&pcController->pModifiers[i].dwSpecific;
d_ModifierX *= args->XModification / 100.0f;
d_ModifierY *= args->YModification / 100.0f;
d_ModifierX = args->XModification / 100.0f;
d_ModifierY = args->YModification / 100.0f;
}
break;
case MDT_MACRO:
@ -228,7 +225,7 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
if(!args->fPrevFireState) // This round, a firing is needed
{
w_Buttons |= args->aButtons;
if( args->fAnalogRight )
if( args->fAnalogRight )
lAxisValueX += MAXAXISVALUE;
else if( args->fAnalogLeft )
lAxisValueX -= MAXAXISVALUE;
@ -324,9 +321,6 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
w_Buttons |= (((WORD)b_Value) << i);
} // End N64 buttons for
long lDeadZoneValue = pcController->bPadDeadZone * RANGERELATIVE / 100;
float fDeadZoneRelation = (float)RANGERELATIVE / (float)( RANGERELATIVE - lDeadZoneValue );
// Do N64 joystick axes
for ( i = 0; i < 4; i++ )
{
@ -350,21 +344,16 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
case DT_JOYSLIDER:
case DT_JOYAXE:
l_Value = plRawState[btnButton.bOffset] - ZEROVALUE;
if( btnButton.bAxisID ) // Negative range
{
fNegInput = !fNegInput;
b_Value = ( l_Value <= -lDeadZoneValue );
if( b_Value )
l_Value = (long) ((float)(l_Value + lDeadZoneValue ) * fDeadZoneRelation );
b_Value = ( l_Value <= -ZEROVALUE );
}
else
{
b_Value = ( l_Value >= lDeadZoneValue );
if( b_Value )
l_Value = (long) ((float)(l_Value - lDeadZoneValue ) * fDeadZoneRelation );
b_Value = ( l_Value >= ZEROVALUE );
}
break;
case DT_JOYPOV:
@ -517,44 +506,18 @@ bool GetNControllerInput ( const int indexController, LPDWORD pdwData )
}
}
if( pcController->fRealN64Range && ( lAxisValueX || lAxisValueY ))
if( ( lAxisValueX || lAxisValueY ) )
{
long lAbsoluteX = ( lAxisValueX > 0 ) ? lAxisValueX : -lAxisValueX;
long lAbsoluteY = ( lAxisValueY > 0 ) ? lAxisValueY : -lAxisValueY;
float LX, LY;
float modX = lAxisValueX * (d_ModifierX == 0 ? d_ModifierX = 1 : d_ModifierX);
float modY = lAxisValueY * (d_ModifierY == 0 ? d_ModifierY = 1 : d_ModifierY);
lAxisValueX = (min<long>( max<long>( MINAXISVALUE, modX), MAXAXISVALUE));
lAxisValueY = (min<long>( max<long>( MINAXISVALUE, modY), MAXAXISVALUE));
processStickInput(pcController, lAxisValueX , lAxisValueY, LX, LY);
long lRangeX;
long lRangeY;
if( lAbsoluteX > lAbsoluteY )
{
lRangeX = MAXAXISVALUE;
lRangeY = lRangeX * lAbsoluteY / lAbsoluteX;
}
else
{
lRangeY = MAXAXISVALUE;
lRangeX = lRangeY * lAbsoluteX / lAbsoluteY;
}
// TODO: We should optimize this (comment by rabid)
double dRangeDiagonal = sqrt((double)(lRangeX * lRangeX + lRangeY * lRangeY));
// __asm{
// fld fRangeDiagonal
// fsqrt
// fstp fRangeDiagonal
// fwait
// }
double dRel = MAXAXISVALUE / dRangeDiagonal;
*pdwData = MAKELONG(w_Buttons,
MAKEWORD( (BYTE)(min<long>( max<long>( MINAXISVALUE, (long)(lAxisValueX * d_ModifierX * dRel )), MAXAXISVALUE) / N64DIVIDER ),
(BYTE)(min<long>( max<long>( MINAXISVALUE, (long)(lAxisValueY * d_ModifierY * dRel )), MAXAXISVALUE) / N64DIVIDER )));
}
else
{
*pdwData = MAKELONG(w_Buttons,
MAKEWORD( (BYTE)(min<long>( max<long>( MINAXISVALUE, (long)(lAxisValueX * d_ModifierX )), MAXAXISVALUE) / N64DIVIDER ),
(BYTE)(min<long>( max<long>( MINAXISVALUE, (long)(lAxisValueY * d_ModifierY )), MAXAXISVALUE) / N64DIVIDER )));
*pdwData = MAKELONG(w_Buttons, MAKEWORD( LX * pcController->bN64Range / MAXAXISVALUE, LY * pcController->bN64Range / MAXAXISVALUE) );
}else{
*pdwData = MAKELONG(w_Buttons, MAKEWORD(ZEROVALUE, ZEROVALUE));
}
return true;

View File

@ -307,6 +307,18 @@ bool ProcessKey( DWORD dwKey, DWORD dwSection, LPCSTR pszLine, LPTSTR pszFFDevic
if (pController)
pController->bPadDeadZone = atoi(pszLine);
break;
case CHK_SENSITIVITY:
if (pController)
pController->bPadSensitivity = atoi(pszLine);
break;
case CHK_VIRTUALCORNERS:
if (pController)
pController->bVirtualCorners = atoi(pszLine);
break;
case CHK_N64RANGE:
if (pController)
pController->bN64Range = atoi(pszLine);
break;
case CHK_MOUSESENSITIVITYX:
if (pController)
pController->wMouseSensitivityX = atoi(pszLine);
@ -1501,6 +1513,8 @@ void DumpControllerSettings(FILE * fFile, int i, bool bIsINI)
fprintf(fFile, STRING_INI_RAPIDFIREENABLED "=%u\n", g_ivConfig->Controllers[i].bRapidFireEnabled);
fprintf(fFile, STRING_INI_RAPIDFIRERATE "=%u\n", g_ivConfig->Controllers[i].bRapidFireRate);
fprintf(fFile, STRING_INI_STICKRANGE "=%u\n", g_ivConfig->Controllers[i].bStickRange);
fprintf(fFile, STRING_INI_N64RANGE "=%u\n", g_ivConfig->Controllers[i].bN64Range);
fprintf(fFile, STRING_INI_VIRTUALCORNERS "=%u\n", g_ivConfig->Controllers[i].bVirtualCorners);
fprintf(fFile, STRING_INI_MOUSEMOVEX "=%u\n", g_ivConfig->Controllers[i].bMouseMoveX);
fprintf(fFile, STRING_INI_MOUSEMOVEY "=%u\n", g_ivConfig->Controllers[i].bMouseMoveY);
fprintf(fFile, STRING_INI_AXISSET "=%u\n", g_ivConfig->Controllers[i].bAxisSet);
@ -1512,6 +1526,7 @@ void DumpControllerSettings(FILE * fFile, int i, bool bIsINI)
fprintf(fFile, STRING_INI_RUMBLETYPE "=%u\n", g_ivConfig->Controllers[i].bRumbleTyp);
fprintf(fFile, STRING_INI_RUMBLESTRENGTH "=%u\n", g_ivConfig->Controllers[i].bRumbleStrength);
fprintf(fFile, STRING_INI_VISUALRUMBLE "=%u\n", g_ivConfig->Controllers[i].fVisualRumble);
fprintf(fFile, STRING_INI_SENSITIVITY "=%u\n", g_ivConfig->Controllers[i].bPadSensitivity);
if (bIsINI)
{

View File

@ -101,6 +101,9 @@ unsigned long djbHash(const char *str);
#define STRING_INI_KEYABSOLUTEX "KeyAbsoluteX"
#define STRING_INI_KEYABSOLUTEY "KeyAbsoluteY"
#define STRING_INI_PADDEADZONE "PadDeadZone"
#define STRING_INI_SENSITIVITY "PadSensitivity"
#define STRING_INI_N64RANGE "N64Range"
#define STRING_INI_VIRTUALCORNERS "VirtualCorners"
#define STRING_INI_MOUSESENSX "MouseSensitivityX"
#define STRING_INI_MOUSESENSY "MouseSensitivityY"
#define STRING_INI_RUMBLETYPE "RumbleType"
@ -171,6 +174,9 @@ unsigned long djbHash(const char *str);
#define CHK_KEYABSOLUTEX 958566277UL
#define CHK_KEYABSOLUTEY 958566278UL
#define CHK_PADDEADZONE 2913910084UL
#define CHK_SENSITIVITY 3759052741UL
#define CHK_VIRTUALCORNERS 4174758280UL
#define CHK_N64RANGE 868748074UL
#define CHK_MOUSESENSITIVITYX 1513071697UL
#define CHK_MOUSESENSITIVITYY 1513071698UL
#define CHK_RUMBLETYPE 3440038446UL

View File

@ -67,6 +67,10 @@ INTERFACEVALUES *g_ivConfig = NULL; // This structure holds all
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
short inputX = 0;
short inputY = 0;
ANALOGWIN AnalogW = {0};
// Main dialog control handler
BOOL CALLBACK MainDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
@ -400,7 +404,6 @@ BOOL CALLBACK ControllerTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
// Call routine to show content (recursive call)
ControllerTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE; // Don't give it focus
case WM_NOTIFY:
@ -529,6 +532,7 @@ BOOL CALLBACK ControllerTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
pcController->fXInput = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
if( hTabControl )
DestroyWindow( hTabControl );
TabCtrl_SetCurSel(GetDlgItem(hDlg, IDC_CONTROLLERTAB), TAB_CONTROLS); // select the right tab !
if( pcController->fXInput )
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_XCONTROLS), hDlg, (DLGPROC)XControlsTabProc);
else
@ -591,6 +595,7 @@ BOOL CALLBACK ControllerTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
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 );
TabCtrl_SetCurSel(GetDlgItem(hDlg, IDC_CONTROLLERTAB), TAB_CONTROLS); // select the right tab !
}
// Call child dialog(s) to update their content as well
@ -619,12 +624,6 @@ BOOL CALLBACK ControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
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 ));
@ -640,10 +639,6 @@ BOOL CALLBACK ControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
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;
@ -760,14 +755,6 @@ BOOL CALLBACK ControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
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;
@ -784,16 +771,11 @@ BOOL CALLBACK ControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
if( wParam == 0 )
{
CheckDlgButton( hDlg, IDC_N64RANGE, g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRealN64Range ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_N64REALRANGE, 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;
@ -857,6 +839,18 @@ BOOL CALLBACK XControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_COMMAND:
switch( LOWORD( wParam ))
{
case IDC_XC_INVERT_LX:
gController->stAnalogs.iInvertLX = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_XC_INVERT_LY:
gController->stAnalogs.iInvertLY = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_XC_INVERT_RX:
gController->stAnalogs.iInvertRX = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_XC_INVERT_RY:
gController->stAnalogs.iInvertRY = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_XC_USE:
StoreXInputControllerKeys( hDlg, gController );
{
@ -870,6 +864,7 @@ BOOL CALLBACK XControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
return TRUE;
}
return FALSE;
default:
return FALSE;
}
@ -884,12 +879,16 @@ BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
switch(uMsg)
{
case WM_INITDIALOG:
{
SetTimer( hDlg, 999, 33, NULL );
// TrackBars
hDlgItem = GetDlgItem( hDlg, IDC_DEADZONE );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 100 ));
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 50 ));
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM) 10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
@ -907,11 +906,242 @@ BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
for( i = 0; i < (sizeof(sTics) / sizeof(short)); ++i )
SendMessage( hDlgItem, TBM_SETTIC, 0, sTics[i] );
}
// TrackBars End
hDlgItem = GetDlgItem( hDlg, IDC_CTRRANGE );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 10, 100 ));
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM) 10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
hDlgItem = GetDlgItem( hDlg, IDC_SENSITIVITY );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(1, 100) );
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM)10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM)0, 1 );
hDlgItem = GetDlgItem( hDlg, IDC_N64RANGE );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(10, 127) );
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM)10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM)0, 1 );
hDlgItem = GetDlgItem( hDlg, IDC_VIRTUALCORNERS );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 45) );
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM)10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM)0, 1 );
// TrackBars End
DevicesTabProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Setting values
return FALSE; // Don't give it focus
}
case WM_SIZE:
{
RECT rect;
GetClientRect(hDlg, &rect);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
RECT rcLast;
HWND hLastCtrl = GetDlgItem(hDlg, IDC_VIRTUALCORNERS);
if (hLastCtrl && GetWindowRect(hLastCtrl, &rcLast))
{
MapWindowPoints(NULL, hDlg, (LPPOINT)&rcLast, 2);
AnalogW.Y = rcLast.bottom + 5;
AnalogW.SIZE_W = height - rcLast.bottom - 10;
AnalogW.SIZE_H = height - rcLast.bottom - 10;
AnalogW.X = (width * 0.75) - (AnalogW.SIZE_W) / 2;
}
AnalogW.CENTER_X = AnalogW.SIZE_W / 2.0f;
AnalogW.CENTER_Y = AnalogW.SIZE_H / 2.0f;
AnalogW.RADIUS = AnalogW.SIZE_W * 0.49f;
AnalogW.TRIANGLE_HEIGHT = 3.0f;
return FALSE;
}
case WM_TIMER:
if (wParam == 999)
{
if (pcController->fXInput && pcController->fPlugged){
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
DWORD result = XInputGetState(pcController->xiController.nControl, &state);
if (result == ERROR_SUCCESS) {
if (pcController->xiController.stAnalogs.iLXAxis == 0x4000){
inputX = state.Gamepad.sThumbLX;
inputY = state.Gamepad.sThumbLY;
}else{
inputX = state.Gamepad.sThumbRX;
inputY = state.Gamepad.sThumbRY;
}
}
} else {
if(pcController->fPlugged)
{
LPDEVICE lpDevice = nullptr;
for (int i = 0; i < 14 + PF_AXESETS * 4; i++)
if (pcController->aButton[i].bBtnType == DT_JOYAXE)
lpDevice = pcController->aButton[i].parentDevice;
if (lpDevice != nullptr) {
HRESULT hr = lpDevice->didHandle->Poll();
if (FAILED(hr)) {
hr = lpDevice->didHandle->Acquire();
}
if (SUCCEEDED(hr)) {
hr = lpDevice->didHandle->GetDeviceState(sizeof(DIJOYSTATE), &lpDevice->stateAs.joyState);
if (hr == DI_OK) {
inputX = lpDevice->stateAs.joyState.lX;
inputY = -lpDevice->stateAs.joyState.lY;
}
}
}
}
}
RECT rectToInvalidate = {AnalogW.X, AnalogW.Y, AnalogW.X + AnalogW.SIZE_W, AnalogW.Y + AnalogW.SIZE_H};
InvalidateRect(hDlg, &rectToInvalidate, TRUE);
}
break;
case WM_PAINT:
{
const float OCTAGON_RADIUS = AnalogW.RADIUS * (pcController->bStickRange / 100.0f);
const float ANGLE_THRESHOLD = pcController->bVirtualCorners / 100.0f;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hDlg, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmMem = CreateCompatibleBitmap(hdc, AnalogW.SIZE_W, AnalogW.SIZE_H);
HBITMAP hbmOrigin = (HBITMAP)SelectObject(hdcMem, hbmMem);
HPEN hOldPen = nullptr;
HBRUSH hOldBrush = nullptr;
HBRUSH hBrushBackground = CreateSolidBrush(RGB(240, 240, 240));
RECT rect = {0, 0, AnalogW.SIZE_W, AnalogW.SIZE_H};
FillRect(hdcMem, &rect, hBrushBackground);
DeleteObject(hBrushBackground);
// Gamepad Range
HPEN outhPen = CreatePen(PS_SOLID, 1, RGB(55, 55, 55));
HBRUSH outhBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
hOldPen = (HPEN)SelectObject(hdcMem, outhPen);
hOldBrush = (HBRUSH)SelectObject(hdcMem, outhBrush);
RoundRect(hdcMem, AnalogW.CENTER_X - AnalogW.RADIUS, AnalogW.CENTER_Y - AnalogW.RADIUS, AnalogW.CENTER_X + AnalogW.RADIUS, AnalogW.CENTER_Y + AnalogW.RADIUS, AnalogW.RADIUS, AnalogW.RADIUS);
SelectObject(hdcMem, hOldPen);
SelectObject(hdcMem, hOldBrush);
DeleteObject(outhPen);
// Octagon
if (pcController->fRealN64Range)
{
HBRUSH hGrayBrush = CreateSolidBrush(RGB(215, 215, 215));
hOldBrush = (HBRUSH)SelectObject(hdcMem, hGrayBrush);
POINT octagon[8];
for (int i = 0; i < 8; ++i) {
double angle = i * OCTAGON_ANGLE;
double cosA = cos(angle);
double sinA = sin(angle);
octagon[i].x = AnalogW.CENTER_X + OCTAGON_RADIUS * cosA;
octagon[i].y = AnalogW.CENTER_Y - OCTAGON_RADIUS * sinA;
}
Polygon(hdcMem, octagon, 8);
SelectObject(hdcMem, hOldBrush);
DeleteObject(hGrayBrush);
// Virtual Corners
HBRUSH hTriangleBrush = CreateSolidBrush(RGB(255, 100, 0));
hOldBrush = (HBRUSH)SelectObject(hdcMem, hTriangleBrush);
for (int i = 0; i < 8; ++i) {
double angle = i * OCTAGON_ANGLE;
double cosA = cos(angle);
double sinA = sin(angle);
double cosM = cos(angle - ANGLE_THRESHOLD);
double sinM = sin(angle - ANGLE_THRESHOLD);
double cosP = cos(angle + ANGLE_THRESHOLD);
double sinP = sin(angle + ANGLE_THRESHOLD);
POINT triangle[3] = {
{AnalogW.CENTER_X + OCTAGON_RADIUS * cosA, AnalogW.CENTER_Y - OCTAGON_RADIUS * sinA},
{AnalogW.CENTER_X + (OCTAGON_RADIUS - AnalogW.TRIANGLE_HEIGHT) * cosM, AnalogW.CENTER_Y - (OCTAGON_RADIUS - AnalogW.TRIANGLE_HEIGHT) * sinM},
{AnalogW.CENTER_X + (OCTAGON_RADIUS - AnalogW.TRIANGLE_HEIGHT) * cosP, AnalogW.CENTER_Y - (OCTAGON_RADIUS - AnalogW.TRIANGLE_HEIGHT) * sinP}
};
Polygon(hdcMem, triangle, 3);
}
SelectObject(hdcMem, hOldBrush);
DeleteObject(hTriangleBrush);
}
// DeadZone
float DEADZONE_RADIUS = pcController->bPadDeadZone * AnalogW.RADIUS / 100.0f;
HBRUSH hBrushHatched = CreateHatchBrush(HS_BDIAGONAL, RGB(50, 50, 50));
hOldBrush = (HBRUSH)SelectObject(hdcMem, hBrushHatched);
HPEN deadZonePen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
hOldPen = (HPEN)SelectObject(hdcMem, deadZonePen);
Ellipse(hdcMem, AnalogW.CENTER_X - DEADZONE_RADIUS, AnalogW.CENTER_Y - DEADZONE_RADIUS, AnalogW.CENTER_X + DEADZONE_RADIUS, AnalogW.CENTER_Y + DEADZONE_RADIUS);
SelectObject(hdcMem, hOldBrush);
SelectObject(hdcMem, hOldPen);
DeleteObject(hBrushHatched);
DeleteObject(deadZonePen);
//Stick Position
float outputX = 0.0f, outputY = 0.0f;
processStickInput(pcController, inputX, inputY, outputX, outputY);
POINT position = {AnalogW.CENTER_X, AnalogW.CENTER_Y};
POINT real_pos = {AnalogW.CENTER_X, AnalogW.CENTER_Y};
position.x = AnalogW.CENTER_X + (outputX / (float)XC_ANALOG_MAX) * OCTAGON_RADIUS;
position.y = AnalogW.CENTER_Y - (outputY / (float)XC_ANALOG_MAX) * OCTAGON_RADIUS;
if (!pcController->xiController.stAnalogs.iInvertLX)
real_pos.x = AnalogW.CENTER_X + (inputX / (float)XC_ANALOG_MAX) * AnalogW.RADIUS;
else
real_pos.x = AnalogW.CENTER_X + (-inputX / (float)XC_ANALOG_MAX) * AnalogW.RADIUS;
if (!pcController->xiController.stAnalogs.iInvertLY)
real_pos.y = AnalogW.CENTER_Y - (inputY / (float)XC_ANALOG_MAX) * AnalogW.RADIUS;
else
real_pos.y = AnalogW.CENTER_Y - (-inputY / (float)XC_ANALOG_MAX) * AnalogW.RADIUS;
// Points
HBRUSH pointBrush = CreateSolidBrush(RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdcMem, pointBrush);
Ellipse(hdcMem, position.x - 3, position.y - 3, position.x + 3, position.y + 3);
SelectObject(hdcMem, hOldBrush);
DeleteObject(pointBrush);
HBRUSH pointBrush2 = CreateSolidBrush(RGB(0, 0, 0));
hOldBrush = (HBRUSH)SelectObject(hdcMem, pointBrush2);
Ellipse(hdcMem, real_pos.x - 3, real_pos.y - 3, real_pos.x + 3, real_pos.y + 3);
SelectObject(hdcMem, hOldBrush);
DeleteObject(pointBrush2);
BitBlt(hdc, AnalogW.X, AnalogW.Y, AnalogW.SIZE_W, AnalogW.SIZE_H, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOrigin);
DeleteObject(hbmMem);
DeleteDC(hdcMem);
EndPaint(hDlg, &ps);
return 0;
}
case WM_ERASEBKGND:
{
HDC hdc = (HDC)wParam;
RECT rc;
GetClientRect(hDlg, &rc);
HBRUSH hbr = CreateSolidBrush(RGB(240, 240, 240));
FillRect(hdc, &rc, hbr);
DeleteObject(hbr);
return 1;
}
case WM_DESTROY:
KillTimer( hDlg, TIMER_BUTTON );
return 0;
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
@ -950,6 +1180,9 @@ BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
case IDC_ACCELERATEY:
pcController->fKeyAbsoluteY = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_N64REALRANGE:
pcController->fRealN64Range = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
default:
return FALSE;
@ -980,11 +1213,41 @@ BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
wsprintf( szBuffer, szTemp, pcController->bPadDeadZone );
SendMessage( GetDlgItem( hDlg, IDT_DEADZONE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_SENSITIVITY:
pcController->bPadSensitivity = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_SENSITIVITY, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bPadSensitivity );
SendMessage( GetDlgItem(hDlg, IDT_SENSITIVITY), WM_SETTEXT, 0, (LPARAM)szBuffer );
return TRUE;
case IDC_CTRRANGE:
pcController->bStickRange = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_C_RANGE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bStickRange );
SendMessage( GetDlgItem( hDlg, IDT_RANGE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_N64RANGE:
pcController->bN64Range = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_N64RANGE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bN64Range );
SendMessage( GetDlgItem( hDlg, IDT_N64RANGE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_VIRTUALCORNERS:
pcController->bVirtualCorners = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_VIRTUALCORNERS, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bVirtualCorners );
SendMessage( GetDlgItem( hDlg, IDT_VIRTUALCORNERS ), 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
@ -1017,6 +1280,7 @@ BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
CheckDlgButton( hDlg, IDC_ACCELERATEX, pcController->fKeyAbsoluteX ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_ACCELERATEY, pcController->fKeyAbsoluteY ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_N64REALRANGE, pcController->fRealN64Range ? BST_CHECKED : BST_UNCHECKED );
// TrackBars
SendMessage( GetDlgItem( hDlg, IDC_DEADZONE ), TBM_SETPOS, TRUE, pcController->bPadDeadZone );
@ -1033,6 +1297,26 @@ BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
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 );
SendMessage( GetDlgItem( hDlg, IDC_SENSITIVITY), TBM_SETPOS, TRUE, pcController->bPadSensitivity );
LoadString( g_hResourceDLL, IDS_SENSITIVITY, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bPadSensitivity );
SendMessage( GetDlgItem( hDlg, IDT_SENSITIVITY), WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_CTRRANGE ), TBM_SETPOS, TRUE, pcController->bStickRange );
LoadString( g_hResourceDLL, IDS_C_RANGE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bStickRange );
SendMessage( GetDlgItem( hDlg, IDT_RANGE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_N64RANGE ), TBM_SETPOS, TRUE, pcController->bN64Range );
LoadString( g_hResourceDLL, IDS_N64RANGE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bN64Range );
SendMessage( GetDlgItem( hDlg, IDT_N64RANGE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_VIRTUALCORNERS ), TBM_SETPOS, TRUE, pcController->bVirtualCorners );
LoadString( g_hResourceDLL, IDS_VIRTUALCORNERS, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bVirtualCorners );
SendMessage( GetDlgItem( hDlg, IDT_VIRTUALCORNERS ), WM_SETTEXT , 0, (LPARAM)szBuffer );
// TrackBars End
return TRUE;
@ -3331,7 +3615,7 @@ BOOL CALLBACK FoldersDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
// This function is confusing, but not much I can do to fix it now. I'm sorry. (comment by rabid)
bool GetButtonID( LPDWORD ButtonID, const BYTE bIndex, const BYTE bButtonSet )
{
// TODO: Check this
// TODO: Check this
// TODO: make these constant, read from a resource or a define, or something...I don't know
LPDWORD ButtonTable = NULL;
int nEntries = 0;
@ -3809,7 +4093,9 @@ void SetControllerDefaults( LPCONTROLLER pcController )
pcController->bRapidFireEnabled = false;
pcController->bRapidFireRate = 3; // Set default rapid fire rate here
pcController->bStickRange = DEFAULT_STICKRANGE;
pcController->bN64Range = DEFAULT_N64RANGE;
pcController->bPadDeadZone = DEFAULT_DEADZONE;
pcController->bPadSensitivity = DEFAULT_SENSITIVITY;
pcController->bRumbleTyp = DEFAULT_RUMBLETYP;
pcController->bRumbleStrength = DEFAULT_RUMBLESTRENGTH;
pcController->wMouseSensitivityX = DEFAULT_MOUSESENSIVITY;

View File

@ -1305,3 +1305,95 @@ DWORD WINAPI DelayedShortcut(LPVOID lpParam)
P_free(lpParam);
return 0;
}
void OctagonProj(float& outputX, float& outputY, float CARDINAL_MAX, float ANGLE_THRESHOLD)
{
constexpr float DIAG_RATIO = 2.448f; //CARDINAL_MAX * 0.71f / (CARDINAL_MAX - CARDINAL_MAX * 0.71f); max 71% diagonal
const float C = CARDINAL_MAX * DIAG_RATIO;
float ax = fabs(outputX);
float ay = fabs(outputY);
float r = hypotf(ax, ay);
if (r > EPSILON)
{
float theta = atan2f(ay, ax);
float r_max = (theta <= OCTAGON_ANGLE)
? (C / (sinf(theta) + DIAG_RATIO * cosf(theta)))
: (C / (cosf(theta) + DIAG_RATIO * sinf(theta)));
if (r >= r_max)
{
float new_r = r_max;
float new_ax = new_r * cosf(theta);
float new_ay = new_r * sinf(theta);
outputX = (outputX < 0) ? -new_ax : new_ax;
outputY = (outputY < 0) ? -new_ay : new_ay;
}
if( ANGLE_THRESHOLD > 0)
{
float angles[8] = { 0.0f, OCTAGON_ANGLE, 2 * OCTAGON_ANGLE, 3 * OCTAGON_ANGLE, 4 * OCTAGON_ANGLE, 5 * OCTAGON_ANGLE, 6 * OCTAGON_ANGLE, 7 * OCTAGON_ANGLE };
if (r >= r_max)
{
for (int i = 0; i < 8; ++i)
{
float angle = angles[i];
float angleLowerBound = angle - ANGLE_THRESHOLD;
float angleUpperBound = angle + ANGLE_THRESHOLD;
// Check if we need to lock
if (theta >= angleLowerBound && theta < angleUpperBound)
{
outputX = (outputX < 0) ? -CARDINAL_MAX * cosf(angle) : CARDINAL_MAX * cosf(angle);
outputY = (outputY < 0) ? -CARDINAL_MAX * sinf(angle) : CARDINAL_MAX * sinf(angle);
break;
}
}
}
}
}
}
void processStickInput(CONTROLLER* pcController, short inputX, short inputY, float& outputX, float& outputY)
{
float DEADZONE = (XC_ANALOG_MAX * (pcController->bPadDeadZone / 100.f));
float ANGLE_THRESHOLD = pcController->bVirtualCorners / 100.f;
float stickRange = pcController->bStickRange / 100.f;
float magnitude = hypotf(static_cast<float>(inputX), static_cast<float>(inputY));
float SENSITIVITY = ((1.5f - 0.1f) * (pcController->bPadSensitivity - 1) / (100 - 1)) + 0.1f;
if (magnitude == 0.0f || magnitude <= DEADZONE)
{
outputX = 0.0f;
outputY = 0.0f;
return;
}
float adjustedMagnitude = magnitude - DEADZONE;
float normalizedMagnitude = adjustedMagnitude / (XC_ANALOG_MAX - DEADZONE);
if (normalizedMagnitude < stickRange)
normalizedMagnitude = normalizedMagnitude / stickRange;
else
normalizedMagnitude = 1.0f;
normalizedMagnitude *= 1.0f + (SENSITIVITY - 1.0f) * (1.0f - normalizedMagnitude);
//normalizedMagnitude = fmaxf(0.0f, fminf(1.0f, normalizedMagnitude * (1.0f + (SENSITIVITY - 1.0f) * (1.0f - normalizedMagnitude))));
outputX = (inputX / magnitude) * normalizedMagnitude * XC_ANALOG_MAX;
outputY = (inputY / magnitude) * normalizedMagnitude * XC_ANALOG_MAX;
if (pcController->fRealN64Range) {
OctagonProj(outputX, outputY, XC_ANALOG_MAX, ANGLE_THRESHOLD);
}
if (pcController->xiController.stAnalogs.iInvertLX)
outputX = -outputX;
if (pcController->xiController.stAnalogs.iInvertLY)
outputY = -outputY;
}

View File

@ -36,8 +36,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Maximum number of modifiers
#define MAX_MODIFIERS 256
#define DEFAULT_STICKRANGE 66
#define DEFAULT_STICKRANGE 100
#define DEFAULT_N64RANGE 88
#define DEFAULT_DEADZONE 5
#define DEFAULT_SENSITIVITY 50
#define DEFAULT_RUMBLETYP RUMBLE_EFF1
#define DEFAULT_RUMBLESTRENGTH 80
#define DEFAULT_MOUSESENSIVITY 100
@ -153,13 +155,13 @@ typedef struct _CONTROLLER // An N64 controller
unsigned bBackgroundInput; // Allow input while main window isn't focused?
unsigned XcheckTime; // Checks for newly connected gamepads timer
unsigned XcheckTime; // Checks for newly connected gamepads timer
BYTE bRumbleTyp; // What type of rumble effect? None, constant, ramp, or direct?
GUID guidFFDevice; // GUID of the device that rumble gets sent to
BYTE bStickRange; // Our "range modifier"
BYTE bStickRange; // Stick Range
long wAxeBuffer[4]; // Makes pseudo-relative movement possible through keyboard or buttons and also acts as a mouse buffer
@ -167,6 +169,9 @@ typedef struct _CONTROLLER // An N64 controller
WORD wMouseSensitivityY;
BYTE bPadDeadZone; // Our manual dead zone, set per N64 controller
BYTE bRumbleStrength; // Set per N64 controller
BYTE bPadSensitivity; // Analog Sensitivity
BYTE bN64Range; // N64 Stick Range
BYTE bVirtualCorners; // Octagon Virtual Corners
unsigned short nModifiers; // Number of modifiers
bool bRapidFireEnabled;
@ -391,4 +396,23 @@ void freeModifiers(CONTROLLER *pcController);
void CheckShortcuts();
bool ErrorMessage(UINT uID, DWORD dwError, bool fUserChoose);
// Analog Input Management
constexpr float PI = 3.14159265358979323846;
constexpr float EPSILON = 1e-6f;
constexpr float OCTAGON_ANGLE = PI / 4.0;
typedef struct _ANALOGWIN {
int SIZE_W;
int SIZE_H;
int X;
int Y;
int CENTER_X;
int CENTER_Y;
float RADIUS;
float TRIANGLE_HEIGHT;
} ANALOGWIN;
void OctagonProj(float& outputX, float& outputY, float CARDINAL_MAX, float ANGLE_THRESHOLD);
void processStickInput(CONTROLLER* pcController, short inputX, short inputY, float& outputX, float& outputY);
#endif

View File

@ -31,7 +31,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_MAINCFGDIALOG, DIALOG
BEGIN
@ -123,10 +123,8 @@ BEGIN
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 363
VERTGUIDE, 16
VERTGUIDE, 169
TOPMARGIN, 7
BOTTOMMARGIN, 173
BOTTOMMARGIN, 187
END
IDD_MOD_MOVE, DIALOG
@ -145,9 +143,9 @@ BEGIN
"IDD_MAINCFGDIALOG$(_DEBUG)", DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 389
RIGHTMARGIN, 390
TOPMARGIN, 7
BOTTOMMARGIN, 344
BOTTOMMARGIN, 312
END
END
#endif // APSTUDIO_INVOKED
@ -279,19 +277,16 @@ BEGIN
CTEXT "PLACEHOLDER",IDT_CRIGHT,219,43,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_CDOWN,219,54,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
GROUPBOX "Analog Stick",IDC_STATIC,188,70,175,97
CTEXT "R PLACEHOLDER",IDT_RANGE,194,81,110,8
CONTROL "PLACEHOLDER",IDC_CTRRANGE,"msctls_trackbar32",TBS_AUTOTICKS | WS_GROUP | WS_TABSTOP,194,89,113,11
CONTROL "Real N64 Range",IDC_N64RANGE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_GROUP | WS_TABSTOP,312,82,44,19
CONTROL "Config 1",IDC_CONFIG1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,194,103,42,10
CONTROL "Config 2",IDC_CONFIG2,"Button",BS_AUTORADIOBUTTON,254,103,42,10
PUSHBUTTON "Up",IDC_AUP,194,119,24,10,BS_NOTIFY | WS_GROUP
PUSHBUTTON "Left",IDC_ALEFT,194,130,24,10,BS_NOTIFY
PUSHBUTTON "Right",IDC_ARIGHT,194,141,24,10,BS_NOTIFY
PUSHBUTTON "Down",IDC_ADOWN,194,152,24,10,BS_NOTIFY
CTEXT "PLACEHOLDER",IDT_AUP,219,119,137,10,SS_CENTERIMAGE,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_ALEFT,219,130,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_ARIGHT,219,141,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_ADOWN,219,152,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
CONTROL "Config 1",IDC_CONFIG1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,232,79,40,10
CONTROL "Config 2",IDC_CONFIG2,"Button",BS_AUTORADIOBUTTON,283,79,40,10
PUSHBUTTON "Up",IDC_AUP,194,92,24,10,BS_NOTIFY | WS_GROUP
PUSHBUTTON "Left",IDC_ALEFT,194,103,24,10,BS_NOTIFY
PUSHBUTTON "Right",IDC_ARIGHT,194,114,24,10,BS_NOTIFY
PUSHBUTTON "Down",IDC_ADOWN,194,125,24,10,BS_NOTIFY
CTEXT "PLACEHOLDER",IDT_AUP,219,92,137,10,SS_CENTERIMAGE,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_ALEFT,219,103,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_ARIGHT,219,114,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
CTEXT "PLACEHOLDER",IDT_ADOWN,219,125,137,10,SS_CENTERIMAGE | NOT WS_GROUP,WS_EX_STATICEDGE
END
IDD_CONTROLLERPAK DIALOGEX 0, 0, 370, 180
@ -361,7 +356,7 @@ BEGIN
LTEXT "If you want to use regular DirectInput force-feedback, choose RumblePak instead.",IDC_STATIC,95,90,165,22
END
IDD_DEVICES DIALOGEX 0, 0, 370, 180
IDD_DEVICES DIALOGEX 0, 0, 370, 230
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
@ -379,9 +374,19 @@ BEGIN
GROUPBOX "Keyboard",IDC_STATIC,7,96,171,27
CONTROL "Absolute X",IDC_ACCELERATEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,107,50,10
CONTROL "Absolute Y",IDC_ACCELERATEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,92,107,50,10
GROUPBOX "GamePad",IDC_STATIC,7,124,171,38
CTEXT "Deadzone PLACEHOLDER",IDT_DEADZONE,16,134,153,8
CONTROL "PLACEHOLDER",IDC_DEADZONE,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,16,144,153,11
GROUPBOX "N64 Analog",IDC_STATIC,7,127,170,52
CTEXT "R PLACEHOLDER",IDT_N64RANGE,17,140,153,8
CONTROL "PLACEHOLDER",IDC_N64RANGE,"msctls_trackbar32",TBS_AUTOTICKS | WS_GROUP | WS_TABSTOP,15,151,153,11
CONTROL "Real Octa N64 Range",IDC_N64REALRANGE,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,17,160,100,19
GROUPBOX "Gamepad Analog",IDC_STATIC,190,7,171,172
CTEXT "Deadzone PLACEHOLDER",IDT_DEADZONE,199,17,153,8
CONTROL "PLACEHOLDER",IDC_DEADZONE,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,199,27,153,11
CTEXT "Sensitivity PLACEHOLDER",IDT_SENSITIVITY,199,37,153,8
CONTROL "PLACEHOLDER",IDC_SENSITIVITY,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,199,47,153,11
CTEXT "R PLACEHOLDER",IDT_RANGE,199,57,153,8
CONTROL "PLACEHOLDER",IDC_CTRRANGE,"msctls_trackbar32",TBS_AUTOTICKS | WS_GROUP | WS_TABSTOP,199,67,153,11
CTEXT "R PLACEHOLDER",IDT_VIRTUALCORNERS,199,77,153,8
CONTROL "PLACEHOLDER",IDC_VIRTUALCORNERS,"msctls_trackbar32",TBS_AUTOTICKS | WS_GROUP | WS_TABSTOP,199,87,153,11
END
IDD_PAK_TEXT DIALOGEX 0, 0, 356, 148
@ -573,12 +578,12 @@ IDR_SHORTCUTS_DEFAULT SHORTCUT "configs/Shortcuts.sc"
// TEXTINCLUDE
//
1 TEXTINCLUDE
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
2 TEXTINCLUDE
BEGIN
"#include ""WinResrc.h""\r\n"
"\r\n"
@ -589,7 +594,7 @@ BEGIN
"\0"
END
3 TEXTINCLUDE
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@ -603,14 +608,14 @@ END
// String Table
//
STRINGTABLE
STRINGTABLE
BEGIN
IDS_ERR_DINOTFOUND "dinput8.dll could not be found.\nPlease reinstall the latest version of DirectX."
IDS_ERR_DICREATE "Could not create DirectInput object."
IDS_DLG_MPCHOOSE "Choose a MemPak or type a new name to create one."
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_ERR_MPREAD "Couldn't read MemPak."
IDS_ERR_GBROM "Can't open GB ROM file!"
@ -630,10 +635,12 @@ BEGIN
IDS_ERR_PROFREAD "Couldn't read profile."
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_C_POLLING "...Awaiting Input %i..."
IDS_C_RANGE "Range: %i%%"
IDS_C_RANGE "Stick Range: %i%%"
IDS_N64RANGE "N64 Range: %i%"
IDS_VIRTUALCORNERS "Virtual Corners: %i%%"
IDS_D_MSX "Mouse Sensitivity X: %i%%"
IDS_D_MSY "Mouse Sensitivity Y: %i%%"
IDS_D_DEADZONE "Deadzone: %i%%"
@ -650,7 +657,12 @@ BEGIN
IDS_M_MACRO "Macro"
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_SENSITIVITY "Sensitivity: %i%%"
END
STRINGTABLE
BEGIN
IDS_M_CONFIG "Configuration"
IDS_M_ASSIGNED "Assigned to"
@ -670,7 +682,7 @@ BEGIN
IDS_P_ADAPTOID_NORAW "The AdaptoidPak needs RawMode to be activated."
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_P_NONE_RAWNORAW "No Pak inserted."
IDS_P_MEM_NOCHANGE "Can't change dir while running."
@ -690,7 +702,7 @@ BEGIN
IDS_DLG_SHORTCUTRESTORE "The shortcut configuration will be restored.\nAre you sure?"
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_DLG_SHORTCUTRESTORE_TITLE "Restore default"
IDS_C_GAMEPAD "Gamepad: "
@ -710,7 +722,7 @@ BEGIN
IDS_DLG_ABOUT "Help us translate N-Rage Input V2 into your language!"
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_DLG_ABOUT_TITLE "About N-Rage Input V2"
IDS_ERR_NOINIT "Plugin didn't get initialized!"
@ -727,11 +739,11 @@ BEGIN
IDS_ERR_MEM_NOSPEC "No MemPak specified; please configure plugin."
IDS_DLG_MEM_READONLY "Mempak %s opened with read-only access.\nAfter exiting the game, the MemPak will NOT be saved."
IDS_ERR_MEMOPEN "Unable to read or create MemPak file %s ; please configure plugin."
IDS_DLG_MEM_BADADDRESSCRC
IDS_DLG_MEM_BADADDRESSCRC
"Bad AddressCRC detected!\nThis usually indicates a bad ROM.\n\nIgnore it and continue?"
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_P_MEM_NOREGION "None"
IDS_P_MEM_BETA "Beta"
@ -751,7 +763,7 @@ BEGIN
IDS_ERR_MEMPAK_NONOTES "No free notes on MemPak (only 16 notes available per pak)."
END
STRINGTABLE
STRINGTABLE
BEGIN
IDS_ERR_NOTEEOF "Error reading note file: unexpected end of file or read error."
IDS_ERR_NOTEREAD "Couldn't read note file."
@ -785,7 +797,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_CHILE
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_XCONTROLS, DIALOG
BEGIN
@ -862,15 +874,26 @@ BEGIN
COMBOBOX IDC_XC_LT,143,112,39,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CTEXT "RT",IDC_STATIC,101,130,36,12,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
COMBOBOX IDC_XC_RT,143,130,39,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "D-Pad and Thumbsticks configuration",IDC_STATIC,188,27,175,115
CTEXT "Left Thumbstick",IDC_STATIC,194,65,62,12,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
CTEXT "Right Thumbstick",IDC_STATIC,194,89,62,12,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
CTEXT "D-Pad",IDC_STATIC,194,112,62,12,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
COMBOBOX IDC_XC_LTS,262,65,94,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_XC_RTS,262,88,94,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_XC_DPAD,262,112,94,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CTEXT "XControl",IDC_STATIC,194,45,62,8
CTEXT "N64",IDC_STATIC,262,45,94,8
GROUPBOX "D-Pad and Thumbsticks configuration",IDC_STATIC,188,7,175,160
CTEXT "XControl",IDC_STATIC,194,27,62,8
CTEXT "N64",IDC_STATIC,262,27,94,8
CTEXT "Left Thumbstick",IDC_STATIC,194,41,62,13,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
CONTROL "Invert X",IDC_XC_INVERT_LX,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,194,55,47,12
CONTROL "Invert Y",IDC_XC_INVERT_LY,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,242,55,47,12
CTEXT "Right Thumbstick",IDC_STATIC,194,69,62,13,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
CONTROL "Invert X",IDC_XC_INVERT_RX,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,194,83,47,12
CONTROL "Invert Y",IDC_XC_INVERT_RY,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,242,83,47,12
CTEXT "D-Pad",IDC_STATIC,194,97,62,13,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
COMBOBOX IDC_XC_LTS,262,41,94,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_XC_RTS,262,69,94,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_XC_DPAD,262,97,94,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "NOTE: LThSB and RThSB stands for Left/Right Thumbstick button respectively.",IDC_STATIC,14,155,349,18
CTEXT "XControl",IDC_STATIC,14,27,36,8
PUSHBUTTON "Save",IDC_XC_USE,306,159,50,14

View File

@ -145,34 +145,18 @@ LCleanup:
return bIsXinputDevice;
}
void AxisDeadzone( SHORT &AxisValue, long lDeadZoneValue, float fDeadZoneRelation )
{
short sign = AxisValue < 0 ? -1 : 1;
float value = (float)(AxisValue < 0 ? -AxisValue : AxisValue);
if(value < lDeadZoneValue)
value = 0;
else
{
value = (value - lDeadZoneValue) * fDeadZoneRelation;
value = value > 32767.0f ? 32767.0f : value;
}
AxisValue = (SHORT)(value * sign);
}
void GetXInputControllerKeys( const int indexController, LPDWORD Keys )
{
if (fnXInputGetState == NULL)
if (fnXInputGetState == NULL)
{
return;
}
using namespace N64_BUTTONS;
LPCONTROLLER pcController = &g_pcControllers[indexController];
LPXCONTROLLER gController = &g_pcControllers[indexController].xiController;
LPXCONTROLLER gController = &pcController->xiController;
*Keys = 0;
@ -183,44 +167,52 @@ void GetXInputControllerKeys( const int indexController, LPDWORD Keys )
XINPUT_STATE state;
ULONGLONG time = GetTickCount() / 1000;
if (g_pcControllers[indexController].XcheckTime != NULL && (time - g_pcControllers[indexController].XcheckTime) < 3)
if (pcController->XcheckTime != NULL && (time - pcController->XcheckTime) < 3)
return;
result = fnXInputGetState(gController->nControl, &state);
if (result == ERROR_DEVICE_NOT_CONNECTED) {
g_pcControllers[indexController].XcheckTime = time;
pcController->XcheckTime = time;
}
else {
g_pcControllers[indexController].XcheckTime = NULL;
pcController->XcheckTime = NULL;
}
if( result != ERROR_SUCCESS )
return;
DWORD wButtons = state.Gamepad.wButtons;
if( pcController->bPadDeadZone > 0 )
{
const int RANGERELATIVE = 32767;
long lDeadZoneValue = pcController->bPadDeadZone * RANGERELATIVE / 100;
float fDeadZoneRelation = (float)RANGERELATIVE / (float)( RANGERELATIVE - lDeadZoneValue );
float LX, LY, RX, RY;
short XAx, YAx;
float N64Range = (float)pcController->bN64Range;
AxisDeadzone(state.Gamepad.sThumbLX, lDeadZoneValue, fDeadZoneRelation);
AxisDeadzone(state.Gamepad.sThumbLY, lDeadZoneValue, fDeadZoneRelation);
AxisDeadzone(state.Gamepad.sThumbRX, lDeadZoneValue, fDeadZoneRelation);
AxisDeadzone(state.Gamepad.sThumbRY, lDeadZoneValue, fDeadZoneRelation);
if (gController->stAnalogs.iLXAxis == XAxis){
processStickInput(pcController, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LX , LY);
LX *= N64Range / (float)XC_ANALOG_MAX;
LY *= N64Range / (float)XC_ANALOG_MAX;
RY = state.Gamepad.sThumbRY * N64_ANALOG_MAX / XC_ANALOG_MAX;
RX = state.Gamepad.sThumbRX * N64_ANALOG_MAX / XC_ANALOG_MAX;
XAx = LX;
YAx = LY;
if (pcController->xiController.stAnalogs.iInvertRX)
RX = -RX;
if (pcController->xiController.stAnalogs.iInvertRY)
RY = -RY;
}else{
processStickInput(pcController, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RX, RY);
RX *= N64Range / (float)XC_ANALOG_MAX;
RY *= N64Range / (float)XC_ANALOG_MAX;
LY = state.Gamepad.sThumbLY * N64_ANALOG_MAX / XC_ANALOG_MAX;
LX = state.Gamepad.sThumbLX * N64_ANALOG_MAX / XC_ANALOG_MAX;
XAx = RX;
YAx = RY;
if (pcController->xiController.stAnalogs.iInvertLX)
LX = -LX;
if (pcController->xiController.stAnalogs.iInvertLY)
LY = -LY;
}
short LY = state.Gamepad.sThumbLY * N64_ANALOG_MAX / XC_ANALOG_MAX;
short LX = state.Gamepad.sThumbLX * N64_ANALOG_MAX / XC_ANALOG_MAX;
short RY = state.Gamepad.sThumbRY * N64_ANALOG_MAX / XC_ANALOG_MAX;
short RX = state.Gamepad.sThumbRX * N64_ANALOG_MAX / XC_ANALOG_MAX;
short XAx = 0, XAxc = 0;
short YAx = 0, YAxc = 0;
WORD valButtons = 0;
valButtons |= ( wButtons & gController->stButtons.iDRight ) ? DRight : 0;
valButtons |= ( wButtons & gController->stButtons.iDLeft ) ? DLeft : 0;
@ -258,32 +250,6 @@ void GetXInputControllerKeys( const int indexController, LPDWORD Keys )
if (RY <= -BUTTON_ANALOG_VALUE)
valButtons |= gController->stAnalogs.iRYAxis & (CDown | DDown) ? gController->stAnalogs.iRYAxis : 0;
if (gController->stAnalogs.iLXAxis == XAxis)
{
XAx += LX;
XAxc += LX > 0 ? 1 : 0;
}
if (gController->stAnalogs.iRXAxis == XAxis)
{
XAx += RX;
XAxc += RX > 0 ? 1 : 0;
}
if( XAxc )
XAx /= XAxc;
if (gController->stAnalogs.iLYAxis == YAxis)
{
YAx += LY;
YAxc += LY > 0 ? 1 : 0;
}
if (gController->stAnalogs.iRYAxis == YAxis)
{
YAx += RY;
YAxc += RY > 0 ? 1 : 0;
}
if( YAxc )
YAx /= YAxc;
*Keys = MAKELONG(valButtons, MAKEWORD(XAx, YAx));
}
@ -307,6 +273,10 @@ void DefaultXInputControllerKeys( LPXCONTROLLER gController)
gController->stAnalogs.iLXAxis = XAxis;
gController->stAnalogs.iLYAxis = YAxis;
gController->bConfigured = true;
gController->stAnalogs.iInvertLX = false;
gController->stAnalogs.iInvertLY = false;
gController->stAnalogs.iInvertRX = false;
gController->stAnalogs.iInvertRY = false;
}
void VibrateXInputController( DWORD nController, int LeftMotorVal, int RightMotorVal )
@ -387,7 +357,6 @@ bool InitiateXInputController( LPXCONTROLLER gController, int nControl )
TCHAR * GetN64ButtonNameFromButtonCode( int Button )
{
using namespace N64_BUTTONS;
static TCHAR btnName[10];
switch( Button )
@ -509,6 +478,12 @@ bool ReadXInputControllerKeys( HWND hDlg, LPXCONTROLLER gController )
SendDlgItemMessage( hDlg, IDC_XC_LTS, CB_SELECTSTRING, -1, (LPARAM)GetN64ButtonArrayFromXAnalog( gController, XC_LTBS ));
SendDlgItemMessage( hDlg, IDC_XC_RTS, CB_SELECTSTRING, -1, (LPARAM)GetN64ButtonArrayFromXAnalog( gController, XC_RTBS ));
SendDlgItemMessage(hDlg, IDC_XC_INVERT_LX, BM_SETCHECK, (gController->stAnalogs.iInvertLX ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hDlg, IDC_XC_INVERT_LY, BM_SETCHECK, (gController->stAnalogs.iInvertLY ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hDlg, IDC_XC_INVERT_RX, BM_SETCHECK, (gController->stAnalogs.iInvertRX ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hDlg, IDC_XC_INVERT_RY, BM_SETCHECK, (gController->stAnalogs.iInvertRY ? BST_CHECKED : BST_UNCHECKED), 0);
return true;
}
@ -536,8 +511,8 @@ int GetComboBoxXInputKey( int ComboBox )
}
int GetN64ButtonCode( TCHAR *btnName ) //esta wea esta muy fea, hay que buscar una mejor manera definitivamente..
{ // ^ This translated means "This wea is very ugly, we must definitely find a better way"
// I'm assuming there must be some perceived "better way to handle this, so maybe TODO: ?"
{ // ^ This translated means "This wea is very ugly, we must definitely find a better way"
// I'm assuming there must be some perceived "better way to handle this, so maybe TODO: ?"
using namespace N64_BUTTONS;
int value = 0;
@ -597,6 +572,11 @@ void ResetXInputControllerKeys( LPXCONTROLLER gController )
gController->stAnalogs.iRightTrigger = 0;
gController->stAnalogs.iRXAxis = 0;
gController->stAnalogs.iRYAxis = 0;
gController->stAnalogs.iInvertLX = false;
gController->stAnalogs.iInvertLY = false;
gController->stAnalogs.iInvertRX = false;
gController->stAnalogs.iInvertRY = false;
}
void StoreAnalogConfig( LPXCONTROLLER gController, int ComboBox, int index )
@ -663,6 +643,10 @@ void StoreXInputControllerKeys( HWND hDlg, LPXCONTROLLER gController )
{
LRESULT index = -1;
DWORD value = 0;
int invertLX = gController->stAnalogs.iInvertLX;
int invertLY = gController->stAnalogs.iInvertLY;
int invertRX = gController->stAnalogs.iInvertRX;
int invertRY = gController->stAnalogs.iInvertRY;
ResetXInputControllerKeys( gController );
@ -711,6 +695,10 @@ void StoreXInputControllerKeys( HWND hDlg, LPXCONTROLLER gController )
case 14: gController->stButtons.iDRight |= value; break;
}
}
gController->stAnalogs.iInvertLX = invertLX;
gController->stAnalogs.iInvertLY = invertLY;
gController->stAnalogs.iInvertRX = invertRX;
gController->stAnalogs.iInvertRY = invertRY;
gController->bConfigured = true;
}
@ -738,7 +726,11 @@ void SaveXInputConfigToFile( FILE *file, LPXCONTROLLER gController )
fprintf( file, "LeftXAxis=%lu\n", gController->stAnalogs.iLXAxis );
fprintf( file, "LeftYAxis=%lu\n", gController->stAnalogs.iLYAxis );
fprintf( file, "RightXAxis=%lu\n", gController->stAnalogs.iRXAxis );
fprintf( file, "RightYAxis=%lu\n\n", gController->stAnalogs.iRYAxis );
fprintf( file, "RightYAxis=%lu\n", gController->stAnalogs.iRYAxis );
fprintf( file, "InvertLX=%lu\n", gController->stAnalogs.iInvertLX );
fprintf( file, "InvertLY=%lu\n", gController->stAnalogs.iInvertLY );
fprintf( file, "InvertRX=%lu\n", gController->stAnalogs.iInvertRX );
fprintf( file, "InvertRY=%lu\n\n", gController->stAnalogs.iInvertRY );
}
void LoadXInputConfigFromFile( FILE *file, LPXCONTROLLER gController )
@ -783,6 +775,30 @@ void LoadXInputConfigFromFile( FILE *file, LPXCONTROLLER gController )
sscanf(buffer, "DRight=%lu", &gController->stButtons.iDRight); break;
}
break;
case 'I':
switch( buffer[6] )
{
case 'L':
switch( buffer[7] )
{
case 'X':
sscanf(buffer, "InvertLX=%lu", &gController->stAnalogs.iInvertLX);
break;
case 'Y':
sscanf(buffer, "InvertLY=%lu", &gController->stAnalogs.iInvertLY); break;
}
break;
case 'R':
switch( buffer[7] )
{
case 'X':
sscanf(buffer, "InvertRX=%lu", &gController->stAnalogs.iInvertRX); break;
case 'Y':
sscanf(buffer, "InvertRY=%lu", &gController->stAnalogs.iInvertRY); break;
}
break;
}
break;
case 'L':
switch( buffer[1] )
{

View File

@ -61,7 +61,7 @@ number, ie. first XInput controller is first N64 player, etc.
#include <xinput.h>
// Defines
#define N64_ANALOG_MAX 88
#define N64_ANALOG_MAX 127
#define XC_ANALOG_MAX 32767
#define BUTTON_ANALOG_VALUE 60
@ -95,6 +95,7 @@ typedef struct _XCONTROLLER // XInput controller struct
{
int iLeftTrigger, iRightTrigger;
unsigned int iRXAxis, iRYAxis, iLXAxis, iLYAxis;
unsigned int iInvertLX, iInvertLY, iInvertRX, iInvertRY;
}stAnalogs;
}XCONTROLLER;

View File

@ -4,13 +4,16 @@ PakType=1
RealN64Range=1
RapidFireEnabled=0
RapidFireRate=3
StickRange=66
StickRange=100
VirtualCorners=0
N64Range=88
MouseMoveX=0
MouseMoveY=0
AxisSet=0
KeyAbsoluteX=0
KeyAbsoluteY=0
PadDeadZone=5
PadSensitivity=50
MouseSensitivityX=100
MouseSensitivityY=100
RumbleType=1

View File

@ -209,7 +209,6 @@
#define IDC_RUMBLE3 1036
#define IDC_RUMBLESTRENGTH 1037
#define IDC_MSSENSITIVITY_X 1038
#define IDC_N64RANGE 1039
#define IDC_MSSENSITIVITY_Y 1039
#define IDC_PLUGGED 1040
#define IDC_CTRRANGE 1041
@ -363,6 +362,20 @@
#define IDC_XC_RTS 1195
#define IDC_N64MOUSE 1196
#define IDC_BACKGROUNDINPUT 1197
#define IDC_N64REALRANGE 1198
#define IDC_SENSITIVITY 1199
#define IDT_SENSITIVITY 1200
#define IDS_SENSITIVITY 1201
#define IDC_N64RANGE 1202
#define IDT_N64RANGE 1203
#define IDS_N64RANGE 1204
#define IDC_VIRTUALCORNERS 1205
#define IDT_VIRTUALCORNERS 1206
#define IDS_VIRTUALCORNERS 1207
#define IDC_XC_INVERT_LX 1208
#define IDC_XC_INVERT_LY 1209
#define IDC_XC_INVERT_RX 1210
#define IDC_XC_INVERT_RY 1211
// Next default values for new objects
//
@ -370,7 +383,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 149
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1198
#define _APS_NEXT_CONTROL_VALUE 1300
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif