Project64-input: Be able to load/save controller

This commit is contained in:
zilmar 2020-07-01 13:07:55 +09:30
parent acd835cfc4
commit ba2ea24274
11 changed files with 304 additions and 1 deletions

View File

@ -1,4 +1,5 @@
#include "CProject64Input.h"
#include "InputSettings.h"
CProject64Input * g_InputPlugin = nullptr;
@ -16,11 +17,17 @@ CProject64Input::~CProject64Input()
void CProject64Input::InitiateControllers(CONTROL_INFO * ControlInfo)
{
CGuard guard(m_CS);
if (m_DirectInput.get() == NULL)
{
m_DirectInput.reset(new CDirectInput(m_hinst));
}
m_DirectInput->Initiate(ControlInfo);
for (size_t i = 0, n = sizeof(m_Controllers) / sizeof(m_Controllers[0]); i < n; i++)
{
g_Settings->LoadController(0, m_Controllers[i]);
m_DirectInput->MapControllerDevice(m_Controllers[i]);
}
}
void CProject64Input::StartScanDevices(int32_t DisplayCtrlId)
@ -53,3 +60,13 @@ std::wstring CProject64Input::ButtonAssignment(BUTTON & Button)
}
return L"Unknown";
}
bool CProject64Input::SaveController(uint32_t ControlIndex)
{
if (ControlIndex >= sizeof(m_Controllers) / sizeof(m_Controllers[0]))
{
return false;
}
g_Settings->SaveController(ControlIndex, m_Controllers[ControlIndex]);
return true;
}

View File

@ -2,6 +2,7 @@
#include "ControllerSpec1.1.h"
#include "DirectInput.h"
#include "N64Controller.h"
#include <Common\CriticalSection.h>
#include <memory>
class CProject64Input
@ -15,6 +16,7 @@ public:
void EndScanDevices(void);
CDirectInput::ScanResult ScanDevices(BUTTON & Button);
std::wstring ButtonAssignment(BUTTON & Button);
bool SaveController(uint32_t ControlIndex);
inline HINSTANCE hInst(void) const { return m_hinst; }
inline bool IsScanning(void) const { return m_Scanning; }
@ -26,6 +28,7 @@ private:
CProject64Input(const CProject64Input&);
CProject64Input& operator=(const CProject64Input&);
CriticalSection m_CS;
N64CONTROLLER m_Controllers[4];
std::unique_ptr<CDirectInput> m_DirectInput;
HINSTANCE m_hinst;

View File

@ -50,6 +50,44 @@ void CDirectInput::Initiate(CONTROL_INFO * ControlInfo)
m_hWnd = (HWND)ControlInfo->hwnd;
}
void CDirectInput::MapControllerDevice(N64CONTROLLER & Controller)
{
BUTTON * Buttons[] =
{
&Controller.U_DPAD,
&Controller.D_DPAD,
&Controller.L_DPAD,
&Controller.R_DPAD,
&Controller.A_BUTTON,
&Controller.B_BUTTON,
&Controller.U_CBUTTON,
&Controller.D_CBUTTON,
&Controller.L_CBUTTON,
&Controller.R_CBUTTON,
&Controller.START_BUTTON,
&Controller.Z_TRIG,
&Controller.R_TRIG,
&Controller.L_TRIG,
&Controller.U_ANALOG,
&Controller.D_ANALOG,
&Controller.L_ANALOG,
&Controller.R_ANALOG,
};
for (size_t i = 0, n = sizeof(Buttons) / sizeof(Buttons[0]); i < n; i++)
{
DEVICE_MAP::iterator itr = m_Devices.find(Buttons[i]->DeviceGuid);
if (itr != m_Devices.end())
{
Buttons[i]->Device = &itr->second;
}
else
{
Buttons[i]->Device = nullptr;
}
}
}
BOOL CDirectInput::stEnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
return ((CDirectInput *)pvRef)->EnumMakeDeviceList(lpddi);

View File

@ -1,6 +1,7 @@
#pragma once
#include "ControllerSpec1.1.h"
#include "Button.h"
#include "N64Controller.h"
#define DIRECTINPUT_VERSION 0x0800
#include <Windows.h>
#include <dinput.h>
@ -21,6 +22,7 @@ public:
~CDirectInput();
void Initiate(CONTROL_INFO * ControlInfo);
void MapControllerDevice(N64CONTROLLER & Controller);
ScanResult ScanDevices(BUTTON & Button);
std::wstring ButtonAssignment(BUTTON & Button);

View File

@ -109,7 +109,7 @@ HBRUSH CControllerSettings::OnCtlColorStatic(CDCHandle dc, CWindow wndStatic)
bool CControllerSettings::OnApply()
{
return true;
return g_InputPlugin->SaveController(m_ControllerNumber);
}
void CControllerSettings::ButtonChannged(void)

View File

@ -12,6 +12,7 @@
#include "InputConfigUI.h"
#include "Version.h"
#include "CProject64Input.h"
#include "InputSettings.h"
#include <stdio.h>
/******************************************************************
@ -23,6 +24,7 @@ output: none
*******************************************************************/
EXPORT void CALL CloseDLL(void)
{
CleanupInputSettings();
}
/******************************************************************
@ -190,6 +192,7 @@ EXPORT void CALL WM_KeyUp(uint32_t /*wParam*/, uint32_t /*lParam*/)
EXPORT void CALL PluginLoaded(void)
{
SetupInputSettings();
}
#include <Windows.h>

View File

@ -0,0 +1,173 @@
#include <Settings/Settings.h>
#include <Common\StdString.h>
#include "InputSettingsID.h"
#include "InputSettings.h"
CInputSettings * g_Settings = nullptr;
CInputSettings::CInputSettings()
{
RegisterSettings();
}
CInputSettings::~CInputSettings()
{
}
void CInputSettings::LoadController(uint32_t ControlIndex, N64CONTROLLER & Controller)
{
struct {
BUTTON & Button;
InputSettingID SettingId;
uint32_t ControlIndex;
}
Buttons[] =
{
{ Controller.U_DPAD, Set_Control0_U_DPAD, 0 },
{ Controller.D_DPAD, Set_Control0_D_DPAD, 0 },
{ Controller.L_DPAD, Set_Control0_L_DPAD, 0 },
{ Controller.R_DPAD, Set_Control0_R_DPAD, 0 },
{ Controller.A_BUTTON, Set_Control0_A_BUTTON, 0 },
{ Controller.B_BUTTON, Set_Control0_B_BUTTON, 0 },
{ Controller.U_CBUTTON, Set_Control0_U_CBUTTON, 0 },
{ Controller.D_CBUTTON, Set_Control0_D_CBUTTON, 0 },
{ Controller.L_CBUTTON, Set_Control0_L_CBUTTON, 0 },
{ Controller.R_CBUTTON, Set_Control0_R_CBUTTON, 0 },
{ Controller.START_BUTTON, Set_Control0_START_BUTTON, 0 },
{ Controller.Z_TRIG, Set_Control0_Z_TRIG, 0 },
{ Controller.R_TRIG, Set_Control0_R_TRIG, 0 },
{ Controller.L_TRIG, Set_Control0_L_TRIG, 0 },
{ Controller.U_ANALOG, Set_Control0_U_ANALOG, 0 },
{ Controller.D_ANALOG, Set_Control0_D_ANALOG, 0 },
{ Controller.L_ANALOG, Set_Control0_L_ANALOG, 0 },
{ Controller.R_ANALOG, Set_Control0_R_ANALOG, 0 },
};
char Buffer[400];
for (size_t i = 0, n = sizeof(Buttons) / sizeof(Buttons[0]); i < n; i++)
{
if (Buttons[i].ControlIndex != ControlIndex)
{
continue;
}
Buttons[i].Button = StrToButton(GetSettingSz((short)Buttons[i].SettingId, Buffer, sizeof(Buffer) / sizeof(Buffer[0])));
}
}
void CInputSettings::SaveController(uint32_t ControlIndex, const N64CONTROLLER & Controller)
{
struct {
const BUTTON & Button;
InputSettingID SettingId;
uint32_t ControlIndex;
}
Buttons[] =
{
{ Controller.U_DPAD, Set_Control0_U_DPAD, 0 },
{ Controller.D_DPAD, Set_Control0_D_DPAD, 0 },
{ Controller.L_DPAD, Set_Control0_L_DPAD, 0 },
{ Controller.R_DPAD, Set_Control0_R_DPAD, 0 },
{ Controller.A_BUTTON, Set_Control0_A_BUTTON, 0 },
{ Controller.B_BUTTON, Set_Control0_B_BUTTON, 0 },
{ Controller.U_CBUTTON, Set_Control0_U_CBUTTON, 0 },
{ Controller.D_CBUTTON, Set_Control0_D_CBUTTON, 0 },
{ Controller.L_CBUTTON, Set_Control0_L_CBUTTON, 0 },
{ Controller.R_CBUTTON, Set_Control0_R_CBUTTON, 0 },
{ Controller.START_BUTTON, Set_Control0_START_BUTTON, 0 },
{ Controller.Z_TRIG, Set_Control0_Z_TRIG, 0 },
{ Controller.R_TRIG, Set_Control0_R_TRIG, 0 },
{ Controller.L_TRIG, Set_Control0_L_TRIG, 0 },
{ Controller.U_ANALOG, Set_Control0_U_ANALOG, 0 },
{ Controller.D_ANALOG, Set_Control0_D_ANALOG, 0 },
{ Controller.L_ANALOG, Set_Control0_L_ANALOG, 0 },
{ Controller.R_ANALOG, Set_Control0_R_ANALOG, 0 },
};
for (size_t i = 0, n = sizeof(Buttons) / sizeof(Buttons[0]); i < n; i++)
{
if (Buttons[i].ControlIndex != ControlIndex)
{
continue;
}
SetSettingSz((short)Buttons[i].SettingId, ButtonToStr(Buttons[i].Button).c_str());
}
FlushSettings();
}
BUTTON CInputSettings::StrToButton(const char * Buffer)
{
BUTTON Button = { 0 };
GUID &guid = Button.DeviceGuid;
uint32_t ButtonOffset = 0, ButtonAxisID = 0, ButtonType = 0;
sscanf(Buffer,
"{%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx} %x %u %u",
&guid.Data1, &guid.Data2, &guid.Data3,
&guid.Data4[0], &guid.Data4[1], &guid.Data4[2], &guid.Data4[3],
&guid.Data4[4], &guid.Data4[5], &guid.Data4[6], &guid.Data4[7],
&ButtonOffset, &ButtonAxisID, &ButtonType);
Button.Offset = (uint8_t)(ButtonOffset & 0xFF);
Button.AxisID = (uint8_t)(ButtonAxisID & 0xFF);
Button.BtnType = (BtnType)ButtonType;
return Button;
}
std::string CInputSettings::ButtonToStr(const BUTTON & Button)
{
return stdstr_f("%s %02X %u %u", GUIDtoString(Button.DeviceGuid).c_str(), Button.Offset, Button.AxisID, Button.BtnType);
}
std::string CInputSettings::GUIDtoString(const GUID & guid)
{
return stdstr_f("{%08.8lX-%04.4hX-%04.4hX-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
}
void CInputSettings::RegisterSettings(void)
{
SetModuleName("Input");
RegisterSetting(Set_Control0_U_DPAD, Data_String_General, "DPadUp", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 17 0 5");
RegisterSetting(Set_Control0_D_DPAD, Data_String_General, "DPadDown", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 25 0 5");
RegisterSetting(Set_Control0_L_DPAD, Data_String_General, "DPadLeft", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 24 0 5");
RegisterSetting(Set_Control0_R_DPAD, Data_String_General, "DPadRight", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 26 0 5");
RegisterSetting(Set_Control0_A_BUTTON, Data_String_General, "ButtonA", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 2D 0 5");
RegisterSetting(Set_Control0_B_BUTTON, Data_String_General, "ButtonB", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 2E 0 5");
RegisterSetting(Set_Control0_U_CBUTTON, Data_String_General, "CButtonUp", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} C7 0 5");
RegisterSetting(Set_Control0_D_CBUTTON, Data_String_General, "CButtonDown", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} CF 0 5");
RegisterSetting(Set_Control0_L_CBUTTON, Data_String_General, "CButtonLeft", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} D1 0 5");
RegisterSetting(Set_Control0_R_CBUTTON, Data_String_General, "CButtonRight", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} D3 0 5");
RegisterSetting(Set_Control0_START_BUTTON, Data_String_General, "ButtonStart", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 1C 0 5");
RegisterSetting(Set_Control0_Z_TRIG, Data_String_General, "ButtonZ", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 2C 0 5");
RegisterSetting(Set_Control0_R_TRIG, Data_String_General, "ButtonR", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 1F 0 5");
RegisterSetting(Set_Control0_L_TRIG, Data_String_General, "ButtonL", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} 1E 0 5");
RegisterSetting(Set_Control0_U_ANALOG, Data_String_General, "AnalogUp", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} C8 0 5");
RegisterSetting(Set_Control0_D_ANALOG, Data_String_General, "AnalogDown", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} D0 0 5");
RegisterSetting(Set_Control0_L_ANALOG, Data_String_General, "AnalogLeft", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} CB 0 5");
RegisterSetting(Set_Control0_R_ANALOG, Data_String_General, "AnalogRight", "Controller 1", 0, "{6F1D2B61-D5A0-11CF-BFC7-444553540000} CD 0 5");
}
void SetupInputSettings(void)
{
if (g_Settings == nullptr)
{
g_Settings = new CInputSettings;
}
}
void CleanupInputSettings(void)
{
if (g_Settings)
{
delete g_Settings;
g_Settings = nullptr;
}
}
#ifdef _WIN32
#include <Windows.h>
#endif
extern "C" void UseUnregisteredSetting(int /*SettingID*/)
{
#ifdef _WIN32
DebugBreak();
#endif
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <Common\stdtypes.h>
#include <string>
#include "N64Controller.h"
class CInputSettings
{
public:
CInputSettings();
~CInputSettings();
void LoadController(uint32_t ControlIndex, N64CONTROLLER & Controller);
void SaveController(uint32_t ControlIndex, const N64CONTROLLER & Controller);
private:
CInputSettings(const CInputSettings&);
CInputSettings& operator=(const CInputSettings&);
static BUTTON StrToButton(const char * Buffer);
static std::string ButtonToStr(const BUTTON & Button);
static std::string GUIDtoString(const GUID & guid);
void RegisterSettings(void);
};
extern CInputSettings * g_Settings;
void SetupInputSettings(void);
void CleanupInputSettings(void);

View File

@ -0,0 +1,23 @@
#pragma once
enum InputSettingID
{
Set_Control0_U_DPAD,
Set_Control0_D_DPAD,
Set_Control0_L_DPAD,
Set_Control0_R_DPAD,
Set_Control0_A_BUTTON,
Set_Control0_B_BUTTON,
Set_Control0_U_CBUTTON,
Set_Control0_D_CBUTTON,
Set_Control0_L_CBUTTON,
Set_Control0_R_CBUTTON,
Set_Control0_START_BUTTON,
Set_Control0_Z_TRIG,
Set_Control0_R_TRIG,
Set_Control0_L_TRIG,
Set_Control0_U_ANALOG,
Set_Control0_D_ANALOG,
Set_Control0_L_ANALOG,
Set_Control0_R_ANALOG,
};

View File

@ -61,11 +61,14 @@
<ClCompile Include="InputConfigUI.cpp" />
<ClCompile Include="InputMain.cpp" />
<ClCompile Include="CProject64Input.cpp" />
<ClCompile Include="InputSettings.cpp" />
<ClCompile Include="wtl-BitmapPicture.cpp" />
<ClCompile Include="wtl-ScanButton.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Button.h" />
<ClInclude Include="InputSettings.h" />
<ClInclude Include="InputSettingsID.h" />
<ClInclude Include="N64Controller.h" />
<ClInclude Include="DirectInput.h" />
<ClInclude Include="InputConfigUI.h" />
@ -89,5 +92,8 @@
<ProjectReference Include="..\Common\Common.vcxproj">
<Project>{b4a4b994-9111-42b1-93c2-6f1ca8bc4421}</Project>
</ProjectReference>
<ProjectReference Include="..\Settings\Settings.vcxproj">
<Project>{8b9961b1-88d9-4ea3-a752-507a00dd9f3d}</Project>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -33,6 +33,9 @@
<ClCompile Include="wtl-ScanButton.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="InputSettings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ControllerSpec1.1.h">
@ -65,6 +68,12 @@
<ClInclude Include="N64Controller.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InputSettings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InputSettingsID.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Version.h.in">