Merge pull request #1737 from LukeUsher/xbox-controller-s

Add support for Xbox Controller S
This commit is contained in:
ergo720 2019-09-29 20:57:55 +02:00 committed by GitHub
commit 89e190977b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 267 additions and 238 deletions

View File

@ -20,7 +20,7 @@
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018 wutno (#/g/punk - Rizon)
// * (c) 2018 RadWolfie
// * (c) 2018 RadWolfie
// * (c) 2019 ergo720
// *
// * All rights reserved
@ -30,7 +30,7 @@
#include "Settings.hpp"
#include "core\kernel\support\Emu.h"
#include "EmuShared.h"
#include <filesystem>
#include <filesystem>
#include "common\input\InputManager.h"
#include "common\input\layout_xbox_controller.h"
@ -43,21 +43,21 @@ static_assert(false, "Please implement support for cross-platform's user profile
#include <QDir> // for create directory
#include <QFile> // for check file existance
#include <QStandardPaths> // for cross-platform's user profile support
#endif
std::string g_exec_filepath;
// Individual library version
uint16_t g_LibVersion_D3D8 = 0;
uint16_t g_LibVersion_DSOUND = 0;
#endif
// NOTE: Update settings_version when add/edit/delete setting's structure.
///////////////////////////
// * History:
// * 2: (RadWolfie), initial version
// * 3: (ergo720), added logging settings
// * 4: (LukeUsher), added network settings
// * 5: (ergo720), added new input gui settings and revision to core
std::string g_exec_filepath;
// Individual library version
uint16_t g_LibVersion_D3D8 = 0;
uint16_t g_LibVersion_DSOUND = 0;
// NOTE: Update settings_version when add/edit/delete setting's structure.
///////////////////////////
// * History:
// * 2: (RadWolfie), initial version
// * 3: (ergo720), added logging settings
// * 4: (LukeUsher), added network settings
// * 5: (ergo720), added new input gui settings and revision to core
///////////////////////////
const unsigned int settings_version = 5;
@ -81,13 +81,13 @@ static struct {
} sect_gui_keys;
static const char* section_core = "core";
static struct {
static struct {
const char* Revision = "Revision";
const char* FlagsLLE = "FlagsLLE";
const char* KrnlDebugMode = "KrnlDebugMode";
const char* KrnlDebugLogFile = "KrnlDebugLogFile";
const char* AllowAdminPrivilege = "AllowAdminPrivilege";
const char* LoggedModules = "LoggedModules";
const char* AllowAdminPrivilege = "AllowAdminPrivilege";
const char* LoggedModules = "LoggedModules";
const char* LogLevel = "LogLevel";
} sect_core_keys;
@ -98,7 +98,7 @@ static struct {
const char* Direct3DDevice = "Direct3DDevice";
const char* VSync = "VSync";
const char* FullScreen = "FullScreen";
const char* HardwareYUV = "HardwareYUV";
const char* HardwareYUV = "HardwareYUV";
const char* RenderResolution = "RenderResolution";
} sect_video_keys;
@ -110,8 +110,8 @@ static struct {
const char* codec_xadpcm = "XADPCM";
const char* codec_unknown = "UnknownCodec";
const char* mute_on_unfocus = "MuteOnUnfocus";
} sect_audio_keys;
} sect_audio_keys;
static const char* section_network = "network";
static struct {
const char* adapter_name = "adapter_name";
@ -119,20 +119,20 @@ static struct {
static const char* section_controller_dinput = "controller-dinput";
static const char* section_controller_port = "controller-port";
static const char* section_input = "input-port-";
static struct {
const char* type = "Type";
const char* device = "DeviceName";
const char* config = "ProfileName";
} sect_input;
static const char* section_input_profiles = "input-profile-";
static struct {
const char* type = "Type";
const char* config = "ProfileName";
const char* device = "DeviceName";
const char* control = "%s";
static const char* section_input = "input-port-";
static struct {
const char* type = "Type";
const char* device = "DeviceName";
const char* config = "ProfileName";
} sect_input;
static const char* section_input_profiles = "input-profile-";
static struct {
const char* type = "Type";
const char* config = "ProfileName";
const char* device = "DeviceName";
const char* control = "%s";
} sect_input_profiles;
static const char* section_hack = "hack";
@ -143,7 +143,7 @@ static struct {
} sect_hack_keys;
std::string GenerateExecDirectoryStr()
{
{
return g_exec_filepath.substr(0, g_exec_filepath.find_last_of("\\/"));
}
@ -167,31 +167,31 @@ std::string GenerateUserProfileDirectoryStr()
genDirectory.append(szSettings_cxbx_reloaded_directory);
return genDirectory;
}
std::string TrimQuoteFromString(const char* data)
{
// Safeguard before continue on.
if (data == nullptr) {
return "";
}
std::string trim_str = data;
size_t len = trim_str.size();
if (len > 0) {
// New method, in order to support spaces inside DeviceName value.
if (data[0] == '"') {
len--; // Let's decrement since it also can act as offset too.
if (trim_str.at(len) == '"') {
len--;
}
trim_str = trim_str.substr(1, len);
}
// Old method, don't do anything special.
}
}
std::string TrimQuoteFromString(const char* data)
{
// Safeguard before continue on.
if (data == nullptr) {
return "";
}
std::string trim_str = data;
size_t len = trim_str.size();
if (len > 0) {
// New method, in order to support spaces inside DeviceName value.
if (data[0] == '"') {
len--; // Let's decrement since it also can act as offset too.
if (trim_str.at(len) == '"') {
len--;
}
trim_str = trim_str.substr(1, len);
}
// Old method, don't do anything special.
}
return trim_str;
}
}
#define AppendQuoteToString(d) "\"" + std::string(d) + "\""
bool Settings::Init()
@ -212,11 +212,11 @@ bool Settings::Init()
int iRet = MessageBox(nullptr, szSettings_save_user_option_message, "Cxbx-Reloaded", MB_YESNOCANCEL | MB_ICONQUESTION);
if (iRet == IDYES) {
saveFile = GenerateExecDirectoryStr();
saveFile = GenerateExecDirectoryStr();
m_gui.DataStorageToggle = CXBX_DATA_EXECDIR;
}
else if (iRet == IDNO){
saveFile = GenerateUserProfileDirectoryStr();
saveFile = GenerateUserProfileDirectoryStr();
m_gui.DataStorageToggle = CXBX_DATA_APPDATA;
if (saveFile.size() == 0) {
return false;
@ -240,7 +240,7 @@ bool Settings::Init()
saveFile.append(szSettings_settings_file);
// Call LoadConfig, this will load the config, applying defaults for any missing fields
bRet = LoadConfig();
bRet = LoadConfig();
if (!bRet) {
MessageBox(nullptr, szSettings_setup_error, "Cxbx-Reloaded", MB_OK);
@ -298,7 +298,7 @@ bool Settings::LoadConfig()
int iStatus;
std::list<CSimpleIniA::Entry> si_list;
std::list<CSimpleIniA::Entry>::iterator si_list_iterator;
std::string trim_str;
std::string trim_str;
// ==== GUI Begin ===========
@ -350,7 +350,7 @@ bool Settings::LoadConfig()
// ==== GUI End =============
// ==== Core Begin ==========
m_core.Revision = m_si.GetLongValue(section_core, sect_core_keys.Revision, 4);
m_core.FlagsLLE = m_si.GetLongValue(section_core, sect_core_keys.FlagsLLE, /*Default=*/LLE_NONE);
m_core.KrnlDebugMode = (DebugMode)m_si.GetLongValue(section_core, sect_core_keys.KrnlDebugMode, /*Default=*/DM_NONE);
@ -363,27 +363,27 @@ bool Settings::LoadConfig()
std::strncpy(m_core.szKrnlDebug, si_data, MAX_PATH);
}
m_core.allowAdminPrivilege = m_si.GetBoolValue(section_core, sect_core_keys.AllowAdminPrivilege, /*Default=*/false);
m_core.LogLevel = m_si.GetLongValue(section_core, sect_core_keys.LogLevel, 1);
si_list.clear();
m_core.allowAdminPrivilege = m_si.GetBoolValue(section_core, sect_core_keys.AllowAdminPrivilege, /*Default=*/false);
m_core.LogLevel = m_si.GetLongValue(section_core, sect_core_keys.LogLevel, 1);
si_list.clear();
index = 0;
list_max = std::size(m_core.LoggedModules);
bRet = m_si.GetAllValues(section_core, sect_core_keys.LoggedModules, si_list);
if (bRet) {
si_list_iterator = si_list.begin();
list_max = std::size(m_core.LoggedModules);
bRet = m_si.GetAllValues(section_core, sect_core_keys.LoggedModules, si_list);
if (bRet) {
si_list_iterator = si_list.begin();
for (si_list_iterator; si_list_iterator != si_list.end(); si_list_iterator++) {
// Exit loop when the list has reached the limit.
if (index == list_max) {
break;
}
if (std::strncmp(si_list_iterator->pItem, "0x", 2) == 0) {
si_list_iterator->pItem += 2;
}
if (std::strncmp(si_list_iterator->pItem, "0x", 2) == 0) {
si_list_iterator->pItem += 2;
}
m_core.LoggedModules[index] = std::strtoul(si_list_iterator->pItem, nullptr, 16);
index++;
}
}
}
}
while (index < list_max) {
m_core.LoggedModules[index] = 0;
index++;
@ -415,7 +415,7 @@ bool Settings::LoadConfig()
m_video.direct3DDevice = m_si.GetLongValue(section_video, sect_video_keys.Direct3DDevice, /*Default=*/0);
m_video.bVSync = m_si.GetBoolValue(section_video, sect_video_keys.VSync, /*Default=*/false);
m_video.bFullScreen = m_si.GetBoolValue(section_video, sect_video_keys.FullScreen, /*Default=*/false);
m_video.bHardwareYUV = m_si.GetBoolValue(section_video, sect_video_keys.HardwareYUV, /*Default=*/false);
m_video.bHardwareYUV = m_si.GetBoolValue(section_video, sect_video_keys.HardwareYUV, /*Default=*/false);
m_video.renderScaleFactor = m_si.GetLongValue(section_video, sect_video_keys.RenderResolution, /*Default=*/1);
// ==== Video End ===========
@ -442,72 +442,80 @@ bool Settings::LoadConfig()
m_audio.codec_pcm = m_si.GetBoolValue(section_audio, sect_audio_keys.codec_pcm, /*Default=*/true, nullptr);
m_audio.codec_xadpcm = m_si.GetBoolValue(section_audio, sect_audio_keys.codec_xadpcm, /*Default=*/true, nullptr);
m_audio.codec_unknown = m_si.GetBoolValue(section_audio, sect_audio_keys.codec_unknown, /*Default=*/true, nullptr);
m_audio.codec_unknown = m_si.GetBoolValue(section_audio, sect_audio_keys.codec_unknown, /*Default=*/true, nullptr);
m_audio.mute_on_unfocus = m_si.GetBoolValue(section_audio, sect_audio_keys.mute_on_unfocus, /*Default=*/true, nullptr);
// ==== Audio End ===========
// ==== Network Begin =======
// ==== Audio End ===========
// ==== Network Begin =======
si_data = m_si.GetValue(section_network, sect_network_keys.adapter_name, /*Default=*/nullptr);
// Fallback to null string if value is empty or contains a bigger string.
if (si_data == nullptr || std::strlen(si_data) >= std::size(m_network.adapter_name)) {
m_network.adapter_name[0] = '\0';
} else {
std::strncpy(m_network.adapter_name, si_data, std::size(m_network.adapter_name));
}
}
// ==== Network End =========
// ==== Input Begin ====
for (int port_num = 0; port_num < 4; port_num++) {
std::string current_section = std::string(section_input) + std::to_string(port_num);
int ret = m_si.GetLongValue(current_section.c_str(), sect_input.type, -2);
if (ret == -2) {
m_input[port_num].Type = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
continue;
}
m_input[port_num].Type = ret;
m_input[port_num].DeviceName = m_si.GetValue(current_section.c_str(), sect_input.device);
m_input[port_num].ProfileName = TrimQuoteFromString(m_si.GetValue(current_section.c_str(), sect_input.config));
}
for (int port_num = 0; port_num < 4; port_num++) {
std::string current_section = std::string(section_input) + std::to_string(port_num);
int ret = m_si.GetLongValue(current_section.c_str(), sect_input.type, -2);
if (ret == -2) {
m_input[port_num].Type = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
continue;
}
m_input[port_num].Type = ret;
m_input[port_num].DeviceName = m_si.GetValue(current_section.c_str(), sect_input.device);
m_input[port_num].ProfileName = TrimQuoteFromString(m_si.GetValue(current_section.c_str(), sect_input.config));
}
// ==== Input End ==============
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
// ==== Input End ==============
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int i = 0; i < dev_num_buttons[0]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[0].push_back(control_name);
}
// TODO: add the control names of the other devices
index = 0;
while (true) {
std::string current_section = std::string(section_input_profiles) + std::to_string(index);
if (m_si.GetSectionSize(current_section.c_str()) == -1) {
break;
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
if (dev_num_buttons[device] == 0) {
continue;
}
s_input_profiles local_profile;
local_profile.Type = m_si.GetLongValue(current_section.c_str(), sect_input_profiles.type);
local_profile.ProfileName = TrimQuoteFromString(m_si.GetValue(current_section.c_str(), sect_input_profiles.config));
local_profile.DeviceName = m_si.GetValue(current_section.c_str(), sect_input_profiles.device);
for (int vec_control_index = 0; vec_control_index < dev_num_buttons[local_profile.Type]; vec_control_index++) {
local_profile.ControlList.push_back(m_si.GetValue(current_section.c_str(),
control_names[local_profile.Type][vec_control_index].c_str()));
for (int i = 0; i < dev_num_buttons[device]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[device].push_back(control_name);
}
m_input_profiles[local_profile.Type].push_back(std::move(local_profile));
index++;
}
// TODO: add the control names of the other devices
index = 0;
while (true) {
std::string current_section = std::string(section_input_profiles) + std::to_string(index);
if (m_si.GetSectionSize(current_section.c_str()) == -1) {
break;
}
s_input_profiles local_profile;
local_profile.Type = m_si.GetLongValue(current_section.c_str(), sect_input_profiles.type);
local_profile.ProfileName = TrimQuoteFromString(m_si.GetValue(current_section.c_str(), sect_input_profiles.config));
local_profile.DeviceName = m_si.GetValue(current_section.c_str(), sect_input_profiles.device);
for (int vec_control_index = 0; vec_control_index < dev_num_buttons[local_profile.Type]; vec_control_index++) {
local_profile.ControlList.push_back(m_si.GetValue(current_section.c_str(),
control_names[local_profile.Type][vec_control_index].c_str()));
}
m_input_profiles[local_profile.Type].push_back(std::move(local_profile));
index++;
}
// ==== Input Profile End ======
// Delete legacy configs from previous revisions
RemoveLegacyConfigs(m_core.Revision);
m_core.Revision = settings_version;
// Delete legacy configs from previous revisions
RemoveLegacyConfigs(m_core.Revision);
m_core.Revision = settings_version;
return true;
}
@ -520,7 +528,7 @@ bool Settings::Save(std::string file_path)
// Minimal need is 25, 0x37 for GUID.
char si_value[64];
std::string quote_str;
std::string quote_str;
// ==== GUI Begin ===========
@ -539,22 +547,22 @@ bool Settings::Save(std::string file_path)
// ==== GUI End =============
// ==== Core Begin ==========
m_si.SetLongValue(section_core, sect_core_keys.Revision, m_core.Revision, nullptr, false, true);
m_si.SetLongValue(section_core, sect_core_keys.FlagsLLE, m_core.FlagsLLE, nullptr, true, true);
m_si.SetLongValue(section_core, sect_core_keys.KrnlDebugMode, m_core.KrnlDebugMode, nullptr, true, true);
m_si.SetValue(section_core, sect_core_keys.KrnlDebugLogFile, m_core.szKrnlDebug, nullptr, true);
m_si.SetBoolValue(section_core, sect_core_keys.AllowAdminPrivilege, m_core.allowAdminPrivilege, nullptr, true);
m_si.SetLongValue(section_core, sect_core_keys.LogLevel, m_core.LogLevel, nullptr, false, true);
m_si.SetBoolValue(section_core, sect_core_keys.AllowAdminPrivilege, m_core.allowAdminPrivilege, nullptr, true);
m_si.SetLongValue(section_core, sect_core_keys.LogLevel, m_core.LogLevel, nullptr, false, true);
std::stringstream stream;
stream << "0x" << std::hex << m_core.LoggedModules[0];
std::stringstream stream;
stream << "0x" << std::hex << m_core.LoggedModules[0];
m_si.SetValue(section_core, sect_core_keys.LoggedModules, stream.str().c_str(), nullptr, true);
for (int i = 1; i < NUM_INTEGERS_LOG; i++) {
stream.str("");
for (int i = 1; i < NUM_INTEGERS_LOG; i++) {
stream.str("");
stream << "0x" << std::hex << m_core.LoggedModules[i];
m_si.SetValue(section_core, sect_core_keys.LoggedModules, stream.str().c_str(), nullptr, false);
}
}
// ==== Core End ============
@ -566,8 +574,8 @@ bool Settings::Save(std::string file_path)
m_si.SetLongValue(section_video, sect_video_keys.Direct3DDevice, m_video.direct3DDevice, nullptr, true, true);
m_si.SetBoolValue(section_video, sect_video_keys.VSync, m_video.bVSync, nullptr, true);
m_si.SetBoolValue(section_video, sect_video_keys.FullScreen, m_video.bFullScreen, nullptr, true);
m_si.SetBoolValue(section_video, sect_video_keys.HardwareYUV, m_video.bHardwareYUV, nullptr, true);
m_si.SetLongValue(section_video, sect_video_keys.RenderResolution, m_video.renderScaleFactor, nullptr, false, true);
m_si.SetBoolValue(section_video, sect_video_keys.HardwareYUV, m_video.bHardwareYUV, nullptr, true);
m_si.SetLongValue(section_video, sect_video_keys.RenderResolution, m_video.renderScaleFactor, nullptr, false, true);
// ==== Video End ===========
// ==== Audio Begin =========
@ -585,68 +593,75 @@ bool Settings::Save(std::string file_path)
m_si.SetBoolValue(section_audio, sect_audio_keys.codec_unknown, m_audio.codec_unknown, nullptr, true);
m_si.SetBoolValue(section_audio, sect_audio_keys.mute_on_unfocus, m_audio.mute_on_unfocus, nullptr, true);
// ==== Audio End ===========
// ==== Network Begin =======
// ==== Audio End ===========
// ==== Network Begin =======
m_si.SetValue(section_network, sect_network_keys.adapter_name, m_network.adapter_name, nullptr, true);
// ==== Network End =========
// ==== Input Begin ====
for (int port_num = 0; port_num < 4; port_num++) {
std::string current_section = std::string(section_input) + std::to_string(port_num);
std::string quoted_prf_str = m_input[port_num].ProfileName.insert(0, "\"");
quoted_prf_str += "\"";
m_si.SetLongValue(current_section.c_str(), sect_input.type, m_input[port_num].Type, nullptr, false, true);
m_si.SetValue(current_section.c_str(), sect_input.device, m_input[port_num].DeviceName.c_str(), nullptr, true);
m_si.SetValue(current_section.c_str(), sect_input.config, quoted_prf_str.c_str(), nullptr, true);
}
// ==== Input End ==============
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int i = 0; i < dev_num_buttons[0]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[0].push_back(control_name);
}
// TODO: add the control names of the other devices
int profile_num = 0;
for (int i = 0; i < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); i++) {
size_t vec_size = m_input_profiles[i].size();
if (vec_size == 0) {
continue;
for (int port_num = 0; port_num < 4; port_num++) {
std::string current_section = std::string(section_input) + std::to_string(port_num);
std::string quoted_prf_str = m_input[port_num].ProfileName.insert(0, "\"");
quoted_prf_str += "\"";
m_si.SetLongValue(current_section.c_str(), sect_input.type, m_input[port_num].Type, nullptr, false, true);
m_si.SetValue(current_section.c_str(), sect_input.device, m_input[port_num].DeviceName.c_str(), nullptr, true);
m_si.SetValue(current_section.c_str(), sect_input.config, quoted_prf_str.c_str(), nullptr, true);
}
// ==== Input End ==============
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
if (dev_num_buttons[device] == 0) {
continue;
}
for (unsigned int vec_index = 0; vec_index < vec_size; vec_index++, profile_num++) {
std::string current_section = std::string(section_input_profiles) + std::to_string(profile_num);
std::string quoted_prf_str = m_input_profiles[i][vec_index].ProfileName.insert(0, "\"");
quoted_prf_str += "\"";
m_si.SetLongValue(current_section.c_str(), sect_input_profiles.type, m_input_profiles[i][vec_index].Type, nullptr, false, true);
m_si.SetValue(current_section.c_str(), sect_input_profiles.config, quoted_prf_str.c_str(), nullptr, true);
m_si.SetValue(current_section.c_str(), sect_input_profiles.device, m_input_profiles[i][vec_index].DeviceName.c_str(), nullptr, true);
size_t vec_control_size = m_input_profiles[i][vec_index].ControlList.size();
if (vec_control_size == 0) {
continue;
}
m_si.SetValue(current_section.c_str(), control_names[i][0].c_str(), m_input_profiles[i][vec_index].ControlList[0].c_str(), nullptr, true);
for (unsigned int vec_control_index = 1; vec_control_index < vec_control_size; vec_control_index++) {
m_si.SetValue(current_section.c_str(), control_names[i][vec_control_index].c_str(),
m_input_profiles[i][vec_index].ControlList[vec_control_index].c_str(), nullptr, true);
}
for (int i = 0; i < dev_num_buttons[device]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[device].push_back(control_name);
}
}
while (true) {
std::string current_section = std::string(section_input_profiles) + std::to_string(profile_num);
if (m_si.GetSectionSize(current_section.c_str()) == -1) {
break;
}
m_si.Delete(current_section.c_str(), nullptr, true);
profile_num++;
}
// TODO: add the control names of the other devices
int profile_num = 0;
for (int i = 0; i < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); i++) {
size_t vec_size = m_input_profiles[i].size();
if (vec_size == 0) {
continue;
}
for (unsigned int vec_index = 0; vec_index < vec_size; vec_index++, profile_num++) {
std::string current_section = std::string(section_input_profiles) + std::to_string(profile_num);
std::string quoted_prf_str = m_input_profiles[i][vec_index].ProfileName.insert(0, "\"");
quoted_prf_str += "\"";
m_si.SetLongValue(current_section.c_str(), sect_input_profiles.type, m_input_profiles[i][vec_index].Type, nullptr, false, true);
m_si.SetValue(current_section.c_str(), sect_input_profiles.config, quoted_prf_str.c_str(), nullptr, true);
m_si.SetValue(current_section.c_str(), sect_input_profiles.device, m_input_profiles[i][vec_index].DeviceName.c_str(), nullptr, true);
size_t vec_control_size = m_input_profiles[i][vec_index].ControlList.size();
if (vec_control_size == 0) {
continue;
}
m_si.SetValue(current_section.c_str(), control_names[i][0].c_str(), m_input_profiles[i][vec_index].ControlList[0].c_str(), nullptr, true);
for (unsigned int vec_control_index = 1; vec_control_index < vec_control_size; vec_control_index++) {
m_si.SetValue(current_section.c_str(), control_names[i][vec_control_index].c_str(),
m_input_profiles[i][vec_index].ControlList[vec_control_index].c_str(), nullptr, true);
}
}
}
while (true) {
std::string current_section = std::string(section_input_profiles) + std::to_string(profile_num);
if (m_si.GetSectionSize(current_section.c_str()) == -1) {
break;
}
m_si.Delete(current_section.c_str(), nullptr, true);
profile_num++;
}
// ==== Input Profile End ======
@ -683,38 +698,38 @@ void Settings::Delete()
void Settings::SyncToEmulator()
{
// register Core settings
g_EmuShared->SetCoreSettings(&m_core);
g_EmuShared->SetCoreSettings(&m_core);
g_EmuShared->SetIsKrnlLogEnabled(m_core.KrnlDebugMode != DebugMode::DM_NONE);
// register Video settings
g_EmuShared->SetVideoSettings(&m_video);
// register Audio settings
g_EmuShared->SetAudioSettings(&m_audio);
g_EmuShared->SetAudioSettings(&m_audio);
// register Network settings
g_EmuShared->SetNetworkSettings(&m_network);
// register input settings
for (int i = 0; i < 4; i++) {
g_EmuShared->SetInputDevTypeSettings(&m_input[i].Type, i);
if (m_input[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
g_EmuShared->SetInputDevNameSettings(m_input[i].DeviceName.c_str(), i);
auto it = std::find_if(m_input_profiles[m_input[i].Type].begin(),
m_input_profiles[m_input[i].Type].end(), [this, i](const auto& profile) {
if (profile.ProfileName == m_input[i].ProfileName) {
return true;
}
return false;
});
if (it != m_input_profiles[m_input[i].Type].end()) {
char controls_name[XBOX_CTRL_NUM_BUTTONS][30];
for (int index = 0; index < dev_num_buttons[m_input[i].Type]; index++) {
strncpy(controls_name[index], it->ControlList[index].c_str(), 30);
}
g_EmuShared->SetInputBindingsSettings(controls_name, XBOX_CTRL_NUM_BUTTONS, i);
}
}
// register input settings
for (int i = 0; i < 4; i++) {
g_EmuShared->SetInputDevTypeSettings(&m_input[i].Type, i);
if (m_input[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
g_EmuShared->SetInputDevNameSettings(m_input[i].DeviceName.c_str(), i);
auto it = std::find_if(m_input_profiles[m_input[i].Type].begin(),
m_input_profiles[m_input[i].Type].end(), [this, i](const auto& profile) {
if (profile.ProfileName == m_input[i].ProfileName) {
return true;
}
return false;
});
if (it != m_input_profiles[m_input[i].Type].end()) {
char controls_name[XBOX_CTRL_NUM_BUTTONS][30];
for (int index = 0; index < dev_num_buttons[m_input[i].Type]; index++) {
strncpy(controls_name[index], it->ControlList[index].c_str(), 30);
}
g_EmuShared->SetInputBindingsSettings(controls_name, XBOX_CTRL_NUM_BUTTONS, i);
}
}
}
// register Hacks settings
@ -805,17 +820,17 @@ std::string Settings::GetDataLocation()
return m_current_data_location;
}
void Settings::RemoveLegacyConfigs(unsigned int CurrentRevision)
{
switch (CurrentRevision) {
case 2:
case 3:
case 4:
m_si.Delete(section_controller_dinput, nullptr, true);
m_si.Delete(section_controller_port, nullptr, true);
break;
case 5:
default:
break;
}
void Settings::RemoveLegacyConfigs(unsigned int CurrentRevision)
{
switch (CurrentRevision) {
case 2:
case 3:
case 4:
m_si.Delete(section_controller_dinput, nullptr, true);
m_si.Delete(section_controller_port, nullptr, true);
break;
case 5:
default:
break;
}
}

View File

@ -35,7 +35,8 @@ EmuDevice::EmuDevice(int type, HWND hwnd)
{
switch (type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
m_hwnd = hwnd;
for (int i = 0; i < ARRAY_SIZE(button_xbox_ctrl_id); i++) {
m_buttons.push_back(new Button(button_xbox_ctrl_id[i], i, hwnd));

View File

@ -62,8 +62,8 @@ int Gui2XboxPortArray[4] = {
};
int dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)] = {
XBOX_CTRL_NUM_BUTTONS,
0,
XBOX_CTRL_NUM_BUTTONS, // MS_CONTROLLER_DUKE
XBOX_CTRL_NUM_BUTTONS, // MS_CONTROLLER_S
0,
0,
0,
@ -349,12 +349,12 @@ bool InputDeviceManager::UpdateXboxPortInput(int usb_port, void* Buffer, int Dir
if (dev_ptr->GetPort(usb_port)) {
switch (xid_type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
has_changed = UpdateInputXpad(dev_ptr, Buffer, Direction);
}
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN):
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):

View File

@ -83,14 +83,14 @@ bool operator==(XTL::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
{
switch (XidType)
{
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE: {
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S: {
if (XppType == g_DeviceType_Gamepad) {
return true;
}
}
break;
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
case XBOX_INPUT_DEVICE::LIGHT_GUN:
case XBOX_INPUT_DEVICE::STEERING_WHEEL:
case XBOX_INPUT_DEVICE::MEMORY_UNIT:
@ -129,13 +129,25 @@ bool ConstructHleInputDevice(int Type, int Port)
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
}
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
g_XboxControllerHostBridge[Port].XboxPort = Port;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::MS_CONTROLLER_S;
g_XboxControllerHostBridge[Port].InState = new XpadInput();
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = XINPUT_DEVTYPE_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
}
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
// TODO
}
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN):
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):

View File

@ -97,7 +97,7 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
for (int i = 0, j = 0; i != 4; i++) {
hHandle = GetDlgItem(hWndDlg, IDC_DEVICE_PORT1 + i);
for (auto str : { "None", "MS Controller Duke" }) {
for (auto str : { "None", "MS Controller Duke", "MS Controller S" }) {
LRESULT index = SendMessage(hHandle, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(str));
SendMessage(hHandle, CB_SETITEMDATA, index,
to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID) + j);
@ -142,7 +142,8 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
int DeviceType = SendMessage(hHandle, CB_GETITEMDATA, SendMessage(hHandle, CB_GETCURSEL, 0, 0), 0);
switch (DeviceType)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_XID_DUKE_CFG), hWndDlg, DlgXidControllerConfigProc,
(DeviceType << 8) | port);
}