Add Steel battalion controller support to input gui
This commit is contained in:
parent
689e3ca93c
commit
6a54aa5573
|
@ -471,22 +471,35 @@ bool Settings::LoadConfig()
|
|||
// ==== Input Port End ==============
|
||||
|
||||
// ==== Input Profile Begin ====
|
||||
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
|
||||
|
||||
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) {
|
||||
int num_buttons = dev_num_buttons[device];
|
||||
if (num_buttons == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
auto &lambda = [&control_names, &device](int num_buttons, const char *const ctrl_names[]) {
|
||||
for (int i = 0; i < num_buttons; i++) {
|
||||
char control_name[BUF_NAME_LENGTH];
|
||||
std::sprintf(control_name, sect_input_profiles.control, ctrl_names[i]);
|
||||
control_names[device].push_back(control_name);
|
||||
}
|
||||
};
|
||||
|
||||
switch (num_buttons)
|
||||
{
|
||||
case XBOX_CTRL_NUM_BUTTONS:
|
||||
lambda(XBOX_CTRL_NUM_BUTTONS, button_xbox_ctrl_names);
|
||||
break;
|
||||
|
||||
case SBC_NUM_BUTTONS:
|
||||
lambda(SBC_NUM_BUTTONS, button_sbc_names);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
@ -621,19 +634,32 @@ bool Settings::Save(std::string file_path)
|
|||
|
||||
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) {
|
||||
int num_buttons = dev_num_buttons[device];
|
||||
if (num_buttons == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
auto &lambda = [&control_names, &device](int num_buttons, const char *const ctrl_names[]) {
|
||||
for (int i = 0; i < num_buttons; i++) {
|
||||
char control_name[BUF_NAME_LENGTH];
|
||||
std::sprintf(control_name, sect_input_profiles.control, ctrl_names[i]);
|
||||
control_names[device].push_back(control_name);
|
||||
}
|
||||
};
|
||||
|
||||
switch (num_buttons)
|
||||
{
|
||||
case XBOX_CTRL_NUM_BUTTONS:
|
||||
lambda(XBOX_CTRL_NUM_BUTTONS, button_xbox_ctrl_names);
|
||||
break;
|
||||
|
||||
case SBC_NUM_BUTTONS:
|
||||
lambda(SBC_NUM_BUTTONS, button_sbc_names);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
@ -713,7 +739,7 @@ void Settings::SyncToEmulator()
|
|||
// register Network settings
|
||||
g_EmuShared->SetNetworkSettings(&m_network);
|
||||
|
||||
// register input settings
|
||||
// register Input settings
|
||||
for (int i = 0; i < 4; i++) {
|
||||
g_EmuShared->SetInputDevTypeSettings(&m_input_port[i].Type, i);
|
||||
if (m_input_port[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
||||
|
@ -726,11 +752,11 @@ void Settings::SyncToEmulator()
|
|||
return false;
|
||||
});
|
||||
if (it != m_input_profiles[m_input_port[i].Type].end()) {
|
||||
char controls_name[XBOX_CTRL_NUM_BUTTONS][30];
|
||||
char controls_name[HIGHEST_NUM_BUTTONS][30];
|
||||
for (int index = 0; index < dev_num_buttons[m_input_port[i].Type]; index++) {
|
||||
strncpy(controls_name[index], it->ControlList[index].c_str(), 30);
|
||||
}
|
||||
g_EmuShared->SetInputBindingsSettings(controls_name, XBOX_CTRL_NUM_BUTTONS, i);
|
||||
g_EmuShared->SetInputBindingsSettings(controls_name, dev_num_buttons[m_input_port[i].Type], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,27 +51,22 @@ void Button::GetText(char* const text, size_t size) const
|
|||
SendMessage(m_button_hwnd, WM_GETTEXT, size, reinterpret_cast<LPARAM>(text));
|
||||
}
|
||||
|
||||
std::string Button::GetName(int api, int idx) const
|
||||
{
|
||||
assert(api == XINPUT_DEFAULT || api == DINPUT_DEFAULT);
|
||||
return button_xbox_ctrl_names[idx][api];
|
||||
}
|
||||
|
||||
LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
|
||||
LRESULT CALLBACK ButtonDukeSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
// Remove the window subclass when this window is destroyed
|
||||
case WM_NCDESTROY: {
|
||||
RemoveWindowSubclass(hWnd, ButtonSubclassProc, uIdSubclass);
|
||||
RemoveWindowSubclass(hWnd, ButtonDukeSubclassProc, uIdSubclass);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDOWN: {
|
||||
reinterpret_cast<Button*>(dwRefData)->ClearText();
|
||||
g_InputWindow->UpdateProfile(std::string(), BUTTON_CLEAR);
|
||||
if (reinterpret_cast<Button*>(dwRefData)->GetId() == IDC_SET_MOTOR) {
|
||||
g_InputWindow->UpdateProfile(std::string(), RUMBLE_CLEAR);
|
||||
Button *button = reinterpret_cast<Button *>(dwRefData);
|
||||
button->ClearText();
|
||||
static_cast<DukeInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), BUTTON_CLEAR);
|
||||
if (button->GetId() == IDC_SET_MOTOR) {
|
||||
static_cast<DukeInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), RUMBLE_CLEAR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -80,3 +75,25 @@ LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
|
|||
|
||||
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK ButtonSbcSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
// Remove the window subclass when this window is destroyed
|
||||
case WM_NCDESTROY: {
|
||||
RemoveWindowSubclass(hWnd, ButtonSbcSubclassProc, uIdSubclass);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDOWN: {
|
||||
Button *button = reinterpret_cast<Button *>(dwRefData);
|
||||
button->ClearText();
|
||||
static_cast<SbcInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), BUTTON_CLEAR);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <string>
|
||||
|
||||
#define XBOX_CTRL_NUM_BUTTONS 25
|
||||
#define SBC_NUM_BUTTONS 65
|
||||
#define SBC_NUM_BUTTONS 56
|
||||
#define HIGHEST_NUM_BUTTONS SBC_NUM_BUTTONS
|
||||
|
||||
|
||||
|
@ -40,20 +40,22 @@
|
|||
class Button
|
||||
{
|
||||
public:
|
||||
Button(int id, int index, HWND hwnd) : m_id(id), m_index(index), m_button_hwnd(GetDlgItem(hwnd, m_id)) {};
|
||||
Button(int id, int index, HWND hwnd, void *wnd) : m_id(id), m_index(index), m_button_hwnd(GetDlgItem(hwnd, m_id)), m_wnd(wnd) {};
|
||||
void EnableButton(bool enable) const;
|
||||
void UpdateText(const char* text) const;
|
||||
void ClearText() const;
|
||||
void GetText(char* const text, size_t size) const;
|
||||
std::string GetName(int api, int idx) const;
|
||||
int GetId() const { return m_id; }
|
||||
int GetIndex() const { return m_index; }
|
||||
void *GetWnd() const { return m_wnd; }
|
||||
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
int m_index;
|
||||
HWND m_button_hwnd;
|
||||
void *m_wnd;
|
||||
};
|
||||
|
||||
LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
||||
LRESULT CALLBACK ButtonDukeSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
||||
LRESULT CALLBACK ButtonSbcSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#include"Button.h"
|
||||
#include "Button.h"
|
||||
#include "InputManager.h"
|
||||
#include "layout_xbox_device.h"
|
||||
#include "gui/resource/ResCxbx.h"
|
||||
|
||||
|
||||
EmuDevice::EmuDevice(int type, HWND hwnd)
|
||||
EmuDevice::EmuDevice(int type, HWND hwnd, void *wnd)
|
||||
{
|
||||
m_hwnd = hwnd;
|
||||
|
||||
|
@ -40,21 +40,21 @@ EmuDevice::EmuDevice(int type, HWND hwnd)
|
|||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(button_xbox_ctrl_id); i++) {
|
||||
m_buttons.push_back(new Button(button_xbox_ctrl_id[i], i, hwnd));
|
||||
m_buttons.push_back(new Button(button_xbox_ctrl_id[i], i, hwnd, wnd));
|
||||
|
||||
// Install the subclass for the button control
|
||||
SetWindowSubclass(GetDlgItem(hwnd, button_xbox_ctrl_id[i]), ButtonSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
|
||||
SetWindowSubclass(GetDlgItem(hwnd, button_xbox_ctrl_id[i]), ButtonDukeSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(button_sbc_id); i++) {
|
||||
m_buttons.push_back(new Button(button_sbc_id[i], i, hwnd));
|
||||
printf("button id: %d, button idx: %d\n", button_sbc_id[i], i);
|
||||
m_buttons.push_back(new Button(button_sbc_id[i], i, hwnd, wnd));
|
||||
|
||||
// Not sure yet if this is necessary
|
||||
// Install the subclass for the button control
|
||||
//SetWindowSubclass(GetDlgItem(hwnd, button_sbc_id[i]), ButtonSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
|
||||
SetWindowSubclass(GetDlgItem(hwnd, button_sbc_id[i]), ButtonSbcSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -86,10 +86,11 @@ Button* EmuDevice::FindButtonByIndex(int index)
|
|||
return m_buttons[index];
|
||||
}
|
||||
|
||||
void EmuDevice::BindDefault(int api)
|
||||
template<size_t size>
|
||||
void EmuDevice::BindDefault(const std::array<const char *, size> &arr)
|
||||
{
|
||||
std::for_each(m_buttons.begin(), m_buttons.end(), [&api](const auto button) {
|
||||
button->UpdateText(button->GetName(api, button->GetIndex()).c_str());
|
||||
std::for_each(m_buttons.begin(), m_buttons.end(), [&arr](const auto button) {
|
||||
button->UpdateText(arr[button->GetIndex()]);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -29,17 +29,19 @@
|
|||
|
||||
#include "Button.h"
|
||||
#include "common\util\CxbxUtil.h"
|
||||
#include <array>
|
||||
|
||||
|
||||
/* Represents the guest device currently being configured in the gui */
|
||||
class EmuDevice
|
||||
{
|
||||
public:
|
||||
EmuDevice(int type, HWND hwnd);
|
||||
EmuDevice(int type, HWND hwnd, void *wnd);
|
||||
~EmuDevice();
|
||||
Button* FindButtonById(int id);
|
||||
Button* FindButtonByIndex(int index);
|
||||
void BindDefault(int api);
|
||||
template<size_t size>
|
||||
void BindDefault(const std::array<const char *, size> &arr);
|
||||
void ClearButtons();
|
||||
|
||||
|
||||
|
@ -47,3 +49,5 @@ private:
|
|||
std::vector<Button*> m_buttons;
|
||||
HWND m_hwnd;
|
||||
};
|
||||
|
||||
template void EmuDevice::BindDefault(const std::array<const char *, XBOX_CTRL_NUM_BUTTONS> &arr);
|
||||
|
|
|
@ -43,46 +43,41 @@ std::string GetInputDeviceName(int dev_type)
|
|||
|
||||
switch (dev_type)
|
||||
{
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
|
||||
str = "MS Gamepad Duke";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
|
||||
str = "MS Gamepad S";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN):
|
||||
str = "Light gun";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
|
||||
str = "Steering wheel";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):
|
||||
str = "Memory unit";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE):
|
||||
str = "IR dongle";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
|
||||
str = "Steel battalion controller";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID):
|
||||
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX): {
|
||||
str = "None";
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX):
|
||||
str = "Invalid";
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "Unknown";
|
||||
|
|
|
@ -157,7 +157,7 @@ private:
|
|||
// all the output controls detected and usable on this device
|
||||
std::vector<Output*> m_Outputs;
|
||||
// xbox port(s) this device is attached to
|
||||
bool m_XboxPort[4] = { false };
|
||||
bool m_XboxPort[4] = { false, false, false, false };
|
||||
// button bindings to the xbox device buttons
|
||||
std::map<int, IoControl*> m_Bindings;
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ int dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)] = {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
XBOX_CTRL_NUM_BUTTONS, // STEEL_BATTALION_CONTROLLER This probably isn't correct?? Let's see what happens
|
||||
SBC_NUM_BUTTONS, // STEEL_BATTALION_CONTROLLER
|
||||
};
|
||||
|
||||
extern CXBX_CONTROLLER_HOST_BRIDGE g_XboxControllerHostBridge[4]; // hle xinput
|
||||
|
@ -311,10 +311,10 @@ void InputDeviceManager::DisconnectDevice(int port, int usb_port, bool ack)
|
|||
void InputDeviceManager::BindHostDevice(int port, int usb_port, int type)
|
||||
{
|
||||
char dev_name[50];
|
||||
char dev_control_names[XBOX_CTRL_NUM_BUTTONS][30];
|
||||
char dev_control_names[HIGHEST_NUM_BUTTONS][30];
|
||||
|
||||
g_EmuShared->GetInputDevNameSettings(dev_name, port);
|
||||
g_EmuShared->GetInputBindingsSettings(dev_control_names, XBOX_CTRL_NUM_BUTTONS, port);
|
||||
g_EmuShared->GetInputBindingsSettings(dev_control_names, dev_num_buttons[type], port);
|
||||
|
||||
auto dev = FindDevice(std::string(dev_name));
|
||||
if (dev != nullptr) {
|
||||
|
@ -342,7 +342,7 @@ bool InputDeviceManager::UpdateXboxPortInput(int usb_port, void* Buffer, int Dir
|
|||
|
||||
// If somebody else is currently holding the lock, we won't wait and instead report no input changes
|
||||
if (m_Mtx.try_lock()) {
|
||||
for (auto dev_ptr : m_Devices) {
|
||||
for (auto &dev_ptr : m_Devices) {
|
||||
if (dev_ptr->GetPort(usb_port)) {
|
||||
switch (xid_type)
|
||||
{
|
||||
|
@ -353,7 +353,7 @@ bool InputDeviceManager::UpdateXboxPortInput(int usb_port, void* Buffer, int Dir
|
|||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
|
||||
has_changed = UpdateInputSBC(dev_ptr, Buffer, Direction);
|
||||
has_changed = UpdateInputSBC(dev_ptr, Buffer, Direction, usb_port);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -384,12 +384,12 @@ bool InputDeviceManager::UpdateInputXpad(std::shared_ptr<InputDevice>& Device, v
|
|||
assert(bindings.size() == static_cast<size_t>(dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE)]));
|
||||
|
||||
if (Direction == DIRECTION_IN) {
|
||||
//XpadInput* in_buf = reinterpret_cast<XpadInput*>(static_cast<uint8_t*>(Buffer) + 2); lle usb
|
||||
XpadInput* in_buf = reinterpret_cast<XpadInput*>(Buffer);
|
||||
if (!Device->UpdateInput()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//XpadInput* in_buf = reinterpret_cast<XpadInput*>(static_cast<uint8_t*>(Buffer) + 2); lle usb
|
||||
XpadInput *in_buf = static_cast<XpadInput *>(Buffer);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i])->GetState() : 0.0;
|
||||
if (state) {
|
||||
|
@ -399,40 +399,34 @@ bool InputDeviceManager::UpdateInputXpad(std::shared_ptr<InputDevice>& Device, v
|
|||
in_buf->wButtons &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 8, j = 0; i < 16; i++, j++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i])->GetState() : 0.0;
|
||||
in_buf->bAnalogButtons[j] = static_cast<uint8_t>(state * 0xFF);
|
||||
}
|
||||
|
||||
for (int i = 16, j = 0; i < 24; i += 2, j++) {
|
||||
for (int i = 16; i < 24; i += 2) {
|
||||
ControlState state_plus = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i])->GetState() : 0.0;
|
||||
ControlState state_minus = (bindings[i + 1] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i + 1])->GetState() : 0.0;
|
||||
ControlState state = state_plus ? state_plus * 0x7FFF : state_minus ? -state_minus * 0x8000 : 0.0;
|
||||
switch (j)
|
||||
switch (i)
|
||||
{
|
||||
case 0: {
|
||||
case 16:
|
||||
in_buf->sThumbLX = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
case 18:
|
||||
in_buf->sThumbLY = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
case 20:
|
||||
in_buf->sThumbRX = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 3: {
|
||||
case 22:
|
||||
in_buf->sThumbRY = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default: {
|
||||
// unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,75 +438,163 @@ bool InputDeviceManager::UpdateInputXpad(std::shared_ptr<InputDevice>& Device, v
|
|||
out_buf->right_actuator_strength / static_cast<ControlState>(0xFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputDeviceManager::UpdateInputSBC(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction)
|
||||
bool InputDeviceManager::UpdateInputSBC(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction, int Port)
|
||||
{
|
||||
std::map<int, InputDevice::IoControl*> bindings = Device->GetBindings();
|
||||
assert(bindings.size() == static_cast<size_t>(dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER)]));
|
||||
|
||||
// NOTE: the output state is not supported
|
||||
if (Direction == DIRECTION_IN) {
|
||||
//XpadInput* in_buf = reinterpret_cast<XpadInput*>(static_cast<uint8_t*>(Buffer) + 2); lle usb
|
||||
XpadInput* in_buf = reinterpret_cast<XpadInput*>(Buffer);
|
||||
if (!Device->UpdateInput()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i])->GetState() : 0.0;
|
||||
// We change the toggle buttons only when a press -> release input transaction is completed
|
||||
// 0 -> CockpitHatch
|
||||
// 1 -> Ignition
|
||||
// 2 -> ToggleFilterControl
|
||||
// 3 -> ToggleOxygenSupply
|
||||
// 4 -> ToggleFuelFlowRate
|
||||
// 5 -> ToggleBuffreMaterial
|
||||
// 6 -> ToggleVTLocation
|
||||
// 7 -> TunerDial Up
|
||||
// 8 -> TunerDial Down
|
||||
// 9 -> GearLever Up
|
||||
// 10 -> GearLever Down
|
||||
static uint16_t last_in_state[4] = { 0, 0, 0, 0 };
|
||||
SBCInput *in_buf = static_cast<SBCInput *>(Buffer);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() : 0.0;
|
||||
if (state) {
|
||||
in_buf->wButtons |= (1 << i);
|
||||
in_buf->wButtons[0] |= (1 << i);
|
||||
}
|
||||
else {
|
||||
in_buf->wButtons &= ~(1 << i);
|
||||
in_buf->wButtons[0] &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
for (int i = 8, j = 0; i < 16; i++, j++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i])->GetState() : 0.0;
|
||||
in_buf->bAnalogButtons[j] = static_cast<uint8_t>(state * 0xFF);
|
||||
|
||||
// CockpitHatch and Ignition are toggle buttons
|
||||
for (int i = 4, j = 0; i < 6; i++, j++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() : 0.0;
|
||||
uint16_t curr_in_state = static_cast<uint16_t>(!!state);
|
||||
if ((~curr_in_state) & ((last_in_state[Port] >> j) & 1)) {
|
||||
in_buf->wButtons[0] ^= (1 << i);
|
||||
}
|
||||
(last_in_state[Port] &= ~(1 << j)) |= (curr_in_state << j);
|
||||
}
|
||||
|
||||
for (int i = 16, j = 0; i < 24; i += 2, j++) {
|
||||
ControlState state_plus = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i])->GetState() : 0.0;
|
||||
ControlState state_minus = (bindings[i + 1] != nullptr) ? dynamic_cast<InputDevice::Input*>(bindings[i + 1])->GetState() : 0.0;
|
||||
ControlState state = state_plus ? state_plus * 0x7FFF : state_minus ? -state_minus * 0x8000 : 0.0;
|
||||
switch (j)
|
||||
for (int i = 6; i < 34; i++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() : 0.0;
|
||||
if (state) {
|
||||
in_buf->wButtons[i / 16] |= (1 << (i % 16));
|
||||
}
|
||||
else {
|
||||
in_buf->wButtons[i / 16] &= ~(1 << (i % 16));
|
||||
}
|
||||
}
|
||||
|
||||
// The last five digital buttons are toggle buttons
|
||||
for (int i = 34, j = 2; i < 39; i++, j++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() : 0.0;
|
||||
uint16_t curr_in_state = static_cast<uint16_t>(!!state);
|
||||
if ((~curr_in_state) & ((last_in_state[Port] >> j) & 1)) {
|
||||
in_buf->wButtons[2] ^= (1 << (i % 16));
|
||||
}
|
||||
(last_in_state[Port] &= ~(1 << j)) |= (curr_in_state << j);
|
||||
}
|
||||
|
||||
for (int i = 39; i < 49; i += 2) {
|
||||
ControlState state_plus = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() : 0.0;
|
||||
ControlState state_minus = (bindings[i + 1] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i + 1])->GetState() : 0.0;
|
||||
switch (i)
|
||||
{
|
||||
case 0: {
|
||||
in_buf->sThumbLX = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
case 39:
|
||||
// NOTE: the center of the stick is 0x7F, not zero
|
||||
in_buf->sAimingX = static_cast<uint8_t>(state_plus ? (0x80 * state_plus) + 0x7F : state_minus ? (1.0 - state_minus) * 0x7F : 0x7F);
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
in_buf->sThumbLY = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
// NOTE: the center of the stick is 0x7F, not zero
|
||||
in_buf->sAimingY = static_cast<uint8_t>(state_plus ? (1.0 - state_plus) * 0x7F : state_minus ? (0x80 * state_minus) + 0x7F : 0x7F);
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
in_buf->sThumbRX = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
case 43:
|
||||
// left: negative, right: positive
|
||||
in_buf->sRotationLever = static_cast<int8_t>(static_cast<int8_t>(state_plus ? -state_plus * 0x80 : state_minus ? state_minus * 0x7F : 0.0));
|
||||
break;
|
||||
|
||||
case 3: {
|
||||
in_buf->sThumbRY = static_cast<int16_t>(state);
|
||||
}
|
||||
break;
|
||||
case 45:
|
||||
// left: positive, right: negative
|
||||
in_buf->sSightChangeX = static_cast<int8_t>(state_plus ? state_plus * 0x7F : state_minus ? -state_minus * 0x80 : 0.0);
|
||||
break;
|
||||
|
||||
case 47:
|
||||
// up: negative, down: positive
|
||||
in_buf->sSightChangeY = static_cast<int8_t>(state_plus ? -state_plus * 0x80 : state_minus ? state_minus * 0x7F : 0.0);
|
||||
break;
|
||||
|
||||
default: {
|
||||
// unreachable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (bindings[24] != nullptr) {
|
||||
//XpadOutput* out_buf = reinterpret_cast<XpadOutput*>(static_cast<uint8_t*>(Buffer) + 2); lle usb
|
||||
XpadOutput* out_buf = reinterpret_cast<XpadOutput*>(Buffer);
|
||||
dynamic_cast<InputDevice::Output*>(bindings[24])->SetState(out_buf->left_actuator_strength / static_cast<ControlState>(0xFFFF),
|
||||
out_buf->right_actuator_strength / static_cast<ControlState>(0xFFFF));
|
||||
|
||||
for (int i = 49; i < 52; i++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? (dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() * 0xFF) : 0.0;
|
||||
switch (i)
|
||||
{
|
||||
case 49:
|
||||
in_buf->wLeftPedal = static_cast<uint8_t>(state);
|
||||
break;
|
||||
|
||||
case 50:
|
||||
in_buf->wMiddlePedal = static_cast<uint8_t>(state);
|
||||
break;
|
||||
|
||||
case 51:
|
||||
in_buf->wRightPedal = static_cast<uint8_t>(state);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TunerDial and GearLever work like toggles
|
||||
for (int i = 52, j = 7; i < 56; i++, j++) {
|
||||
ControlState state = (bindings[i] != nullptr) ? dynamic_cast<InputDevice::Input *>(bindings[i])->GetState() : 0.0;
|
||||
uint16_t curr_in_state = static_cast<uint16_t>(!!state);
|
||||
if ((~curr_in_state) & ((last_in_state[Port] >> j) & 1)) {
|
||||
switch (i)
|
||||
{
|
||||
case 52:
|
||||
if (in_buf->ucTunerDial != 12) {
|
||||
in_buf->ucTunerDial += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 53:
|
||||
if (in_buf->ucTunerDial != 0) {
|
||||
in_buf->ucTunerDial -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 54:
|
||||
if (in_buf->ucGearLever != 13) {
|
||||
in_buf->ucGearLever += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 55:
|
||||
if (in_buf->ucGearLever != 7) {
|
||||
in_buf->ucGearLever -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
(last_in_state[Port] &= ~(1 << j)) |= (curr_in_state << j);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,18 +39,6 @@
|
|||
|
||||
extern int dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)];
|
||||
|
||||
typedef struct _input_controller {
|
||||
XBOX_INPUT_DEVICE type;
|
||||
const char* name;
|
||||
} input_controller;
|
||||
|
||||
static input_controller input_support_list[] = {
|
||||
{ XBOX_INPUT_DEVICE::DEVICE_INVALID, "None" },
|
||||
{ XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE, "MS Controller Duke" },
|
||||
{ XBOX_INPUT_DEVICE::MS_CONTROLLER_S, "MS Controller S" },
|
||||
{ XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER, "Steel Battalion Controller" },
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// xpad in/out buffers stripped of the first two bytes
|
||||
|
@ -68,62 +56,30 @@ struct XpadOutput {
|
|||
uint16_t right_actuator_strength;
|
||||
};
|
||||
|
||||
struct SBCInput { //Was told not to copy this, did it anyways for the sake of having the proper input size and potentially modifying it's bindings from there.
|
||||
uint16_t wButtons[3];
|
||||
int16_t sAimingX;
|
||||
int16_t sAimingY;
|
||||
int16_t sRotationLever;//maybe only high byte was used.
|
||||
int16_t sSightChangeX;
|
||||
int16_t sSightChangeY;
|
||||
uint16_t wLeftPedal;//maybe only high byte was used.
|
||||
uint16_t wMiddlePedal;//maybe only high byte was used.
|
||||
uint16_t wRightPedal;//maybe only high byte was used.
|
||||
uint8_t ucTunerDial;//low nibble, The 9 o'clock postion is 0, and the 6 o'clock position is 12. The blank area between the 6 and 9 o'clock positions is 13, 14, and 15 clockwise.
|
||||
uint8_t ucGearLever;//GearLever 1~5 for gear 1~5, 7~13 for gear R,N,1~5, 15 for gear R. we use the continues range from 7~13
|
||||
struct SBCInput {
|
||||
uint16_t wButtons[3];
|
||||
uint8_t bPad1;
|
||||
uint8_t sAimingX;
|
||||
uint8_t bPad2;
|
||||
uint8_t sAimingY;
|
||||
uint8_t bPad3;
|
||||
int8_t sRotationLever;
|
||||
uint8_t bPad4;
|
||||
int8_t sSightChangeX;
|
||||
uint8_t bPad5;
|
||||
int8_t sSightChangeY;
|
||||
uint8_t bPad6;
|
||||
uint8_t wLeftPedal;
|
||||
uint8_t bPad7;
|
||||
uint8_t wMiddlePedal;
|
||||
uint8_t bPad8;
|
||||
uint8_t wRightPedal;
|
||||
uint8_t ucTunerDial;
|
||||
uint8_t ucGearLever;
|
||||
};
|
||||
|
||||
struct SBCOutput { //Likewise, with 0x14
|
||||
uint16_t StartLED; //Commented out because it stops compilation
|
||||
uint16_t bLen;
|
||||
uint16_t EmergencyEject;
|
||||
uint16_t CockpitHatch;
|
||||
uint16_t Ignition;
|
||||
uint16_t Start;
|
||||
uint16_t OpenClose;
|
||||
uint16_t MapZoomInOut;
|
||||
uint16_t ModeSelect;
|
||||
uint16_t SubMonitorModeSelect;
|
||||
uint16_t MainMonitorZoomIn;
|
||||
uint16_t MainMonitorZoomOut;
|
||||
uint16_t ForecastShootingSystem;
|
||||
uint16_t Manipulator;
|
||||
uint16_t LineColorChange;
|
||||
uint16_t Washing;
|
||||
uint16_t Extinguisher;
|
||||
uint16_t Chaff;
|
||||
uint16_t TankDetach;
|
||||
uint16_t Override;
|
||||
uint16_t NightScope;
|
||||
uint16_t F1;
|
||||
uint16_t F2;
|
||||
uint16_t F3;
|
||||
uint16_t MainWeaponControl;
|
||||
uint16_t SubWeaponControl;
|
||||
uint16_t MagazineChange;
|
||||
uint16_t Comm1;
|
||||
uint16_t Comm2;
|
||||
uint16_t Comm3;
|
||||
uint16_t Comm4;
|
||||
uint16_t Comm5;
|
||||
uint16_t Blank; //This might not be correct, as XboxDevWiki shows an empty box for this entry
|
||||
uint16_t GearR;
|
||||
uint16_t GearN;
|
||||
uint16_t Gear1;
|
||||
uint16_t Gear2;
|
||||
uint16_t Gear3;
|
||||
uint16_t Gear4;
|
||||
uint16_t Gear5;
|
||||
uint16_t Unused; //Also might not be correct, but unsure
|
||||
struct SBCOutput {
|
||||
uint8_t LedState[20];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
@ -160,7 +116,7 @@ private:
|
|||
// update input for an xbox controller
|
||||
bool UpdateInputXpad(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction);
|
||||
// update input for a Steel Battalion controller
|
||||
bool UpdateInputSBC(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction);
|
||||
bool UpdateInputSBC(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction, int Port);
|
||||
// bind a host device to an emulated device
|
||||
void BindHostDevice(int port, int usb_port, int type);
|
||||
// connect a device to the emulated machine
|
||||
|
|
|
@ -34,73 +34,8 @@
|
|||
#include "Logging.h"
|
||||
#include <future>
|
||||
|
||||
#define INPUT_TIMEOUT 5000
|
||||
#define OUTPUT_TIMEOUT 3000
|
||||
|
||||
|
||||
constexpr ControlState INPUT_DETECT_THRESHOLD = 0.35; // NOTE: this should probably be made user configurable
|
||||
InputWindow* g_InputWindow = nullptr;
|
||||
|
||||
|
||||
void InputWindow::Initialize(HWND hwnd, int port_num, int dev_type)
|
||||
{
|
||||
// Save window/device specific variables
|
||||
m_hwnd_window = hwnd;
|
||||
m_hwnd_device_list = GetDlgItem(m_hwnd_window, IDC_DEVICE_LIST);
|
||||
m_hwnd_profile_list = GetDlgItem(m_hwnd_window, IDC_XID_PROFILE_NAME);
|
||||
m_hwnd_default = GetDlgItem(m_hwnd_window, IDC_XID_DEFAULT);
|
||||
m_dev_type = dev_type;
|
||||
m_max_num_buttons = dev_num_buttons[dev_type];
|
||||
m_port_num = port_num;
|
||||
m_bHasChanges = false;
|
||||
m_bIsBinding = false;
|
||||
|
||||
// Set window icon
|
||||
SetClassLong(m_hwnd_window, GCL_HICON, (LONG)LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_CXBX)));
|
||||
|
||||
// Set window title
|
||||
std::string title;
|
||||
switch (m_dev_type)
|
||||
{
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
|
||||
title += "Xbox Controller Duke at port ";
|
||||
}
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
|
||||
title += "Xbox Controller S at port ";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SendMessage(m_hwnd_window, WM_SETTEXT, 0,
|
||||
reinterpret_cast<LPARAM>((title + std::to_string(PORT_INC(m_port_num))).c_str()));
|
||||
|
||||
// Set the maximum profile name lenght the user can enter in the profile combobox
|
||||
SendMessage(m_hwnd_profile_list, CB_LIMITTEXT, 49, 0);
|
||||
|
||||
// construct emu device
|
||||
m_DeviceConfig = new EmuDevice(m_dev_type, m_hwnd_window);
|
||||
|
||||
// Enumerate devices
|
||||
UpdateDeviceList();
|
||||
|
||||
// Load currently saved profile for this port/device type
|
||||
LoadDefaultProfile();
|
||||
|
||||
// Load currently selected host device
|
||||
UpdateCurrentDevice();
|
||||
|
||||
// Load rumble binding
|
||||
char rumble[30];
|
||||
m_DeviceConfig->FindButtonByIndex(m_max_num_buttons - 1)->GetText(rumble, sizeof(rumble));
|
||||
m_rumble = rumble;
|
||||
|
||||
// Install the subclass for the profile combobox
|
||||
SetWindowSubclass(GetWindow(m_hwnd_profile_list, GW_CHILD), ProfileNameSubclassProc, 0, 0);
|
||||
}
|
||||
|
||||
InputWindow::~InputWindow()
|
||||
{
|
||||
|
@ -242,38 +177,6 @@ void InputWindow::BindButton(int ControlID)
|
|||
}
|
||||
}
|
||||
|
||||
void InputWindow::BindDefault()
|
||||
{
|
||||
int api = EnableDefaultButton();
|
||||
if (api != -1) {
|
||||
m_DeviceConfig->BindDefault(api);
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InputWindow::ClearBindings()
|
||||
{
|
||||
m_DeviceConfig->ClearButtons();
|
||||
m_rumble = std::string();
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
|
||||
int InputWindow::EnableDefaultButton()
|
||||
{
|
||||
if (std::strncmp(m_host_dev.c_str(), "XInput", std::strlen("XInput")) == 0) {
|
||||
EnableWindow(m_hwnd_default, TRUE);
|
||||
return XINPUT_DEFAULT;
|
||||
}
|
||||
else if (std::strncmp(m_host_dev.c_str(), "DInput", std::strlen("DInput")) == 0) {
|
||||
EnableWindow(m_hwnd_default, TRUE);
|
||||
return DINPUT_DEFAULT;
|
||||
}
|
||||
else {
|
||||
EnableWindow(m_hwnd_default, FALSE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
InputWindow::ProfileIt InputWindow::FindProfile(const std::string& name)
|
||||
{
|
||||
auto it = std::find_if(g_Settings->m_input_profiles[m_dev_type].begin(),
|
||||
|
@ -283,40 +186,6 @@ InputWindow::ProfileIt InputWindow::FindProfile(const std::string& name)
|
|||
return it;
|
||||
}
|
||||
|
||||
void InputWindow::UpdateProfile(const std::string& name, int command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case PROFILE_LOAD: {
|
||||
LoadProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROFILE_SAVE: {
|
||||
SaveProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROFILE_DELETE: {
|
||||
DeleteProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case RUMBLE_CLEAR: {
|
||||
m_rumble = std::string();
|
||||
}
|
||||
break;
|
||||
|
||||
case BUTTON_CLEAR: {
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InputWindow::LoadProfile(const std::string& name)
|
||||
{
|
||||
ProfileIt profile = FindProfile(name);
|
||||
|
@ -421,74 +290,3 @@ void InputWindow::UpdateCurrentDevice()
|
|||
m_host_dev = device_name;
|
||||
EnableDefaultButton();
|
||||
}
|
||||
|
||||
void InputWindow::InitRumble(HWND hwnd)
|
||||
{
|
||||
m_hwnd_rumble = hwnd;
|
||||
m_hwnd_rumble_list = GetDlgItem(m_hwnd_rumble, IDC_RUMBLE_LIST);
|
||||
SendMessage(m_hwnd_rumble_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(""));
|
||||
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
|
||||
if (dev != nullptr) {
|
||||
auto outputs = dev->GetOutputs();
|
||||
for (const auto out : outputs) {
|
||||
SendMessage(m_hwnd_rumble_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(out->GetName().c_str()));
|
||||
}
|
||||
}
|
||||
SendMessage(m_hwnd_rumble_list, CB_SETCURSEL, SendMessage(m_hwnd_rumble_list, CB_FINDSTRINGEXACT, 1,
|
||||
reinterpret_cast<LPARAM>(m_rumble.c_str())), 0);
|
||||
}
|
||||
|
||||
void InputWindow::UpdateRumble(int command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case RUMBLE_SET: {
|
||||
char rumble[30];
|
||||
SendMessage(m_hwnd_rumble_list, WM_GETTEXT, sizeof(rumble), reinterpret_cast<LPARAM>(rumble));
|
||||
m_rumble = rumble;
|
||||
}
|
||||
break;
|
||||
|
||||
case RUMBLE_UPDATE: {
|
||||
m_DeviceConfig->FindButtonByIndex(m_max_num_buttons - 1)->UpdateText(m_rumble.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case RUMBLE_TEST: {
|
||||
DetectOutput(OUTPUT_TIMEOUT);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InputWindow::DetectOutput(int ms)
|
||||
{
|
||||
if (m_rumble == std::string()) {
|
||||
return;
|
||||
}
|
||||
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
|
||||
if (dev != nullptr) {
|
||||
// Don't block the message processing loop
|
||||
std::thread([this, dev, ms]() {
|
||||
EnableWindow(m_hwnd_rumble, FALSE);
|
||||
SendMessage(m_hwnd_rumble_list, WM_SETTEXT, 0, reinterpret_cast<LPARAM>("..."));
|
||||
auto outputs = dev->GetOutputs();
|
||||
for (const auto out : outputs) {
|
||||
if (out->GetName() == m_rumble) {
|
||||
out->SetState(1.0, 1.0);
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||
for (const auto out : outputs) {
|
||||
if (out->GetName() == m_rumble) {
|
||||
out->SetState(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
SendMessage(m_hwnd_rumble_list, WM_SETTEXT, 0, reinterpret_cast<LPARAM>("Test"));
|
||||
EnableWindow(m_hwnd_rumble, TRUE);
|
||||
}).detach();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,11 @@
|
|||
#define RUMBLE_CLEAR 7
|
||||
#define BUTTON_CLEAR 8
|
||||
|
||||
#define XINPUT_DEFAULT 1
|
||||
#define DINPUT_DEFAULT 2
|
||||
#define XINPUT_DEFAULT 0
|
||||
#define DINPUT_DEFAULT 1
|
||||
|
||||
#define INPUT_TIMEOUT 5000
|
||||
#define OUTPUT_TIMEOUT 3000
|
||||
|
||||
LRESULT CALLBACK ProfileNameSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
||||
|
||||
|
@ -49,30 +52,26 @@ LRESULT CALLBACK ProfileNameSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
|
|||
class InputWindow
|
||||
{
|
||||
public:
|
||||
void Initialize(HWND hwnd, int port_num, int dev_type);
|
||||
void InitRumble(HWND hwnd);
|
||||
virtual void Initialize(HWND hwnd, int port_num, int dev_type) = 0;
|
||||
~InputWindow();
|
||||
void UpdateDeviceList();
|
||||
void BindButton(int ControlID);
|
||||
void BindDefault();
|
||||
void ClearBindings();
|
||||
void UpdateProfile(const std::string& name, int command);
|
||||
void UpdateRumble(int command);
|
||||
virtual void ClearBindings() = 0;
|
||||
virtual void UpdateProfile(const std::string& name, int command) = 0;
|
||||
void UpdateCurrentDevice();
|
||||
bool IsProfileSaved();
|
||||
|
||||
|
||||
private:
|
||||
protected:
|
||||
typedef std::vector<Settings::s_input_profiles>::iterator ProfileIt;
|
||||
InputDevice::Input* DetectInput(InputDevice* const Device, int ms);
|
||||
void DetectOutput(int ms);
|
||||
ProfileIt FindProfile(const std::string& name);
|
||||
void LoadProfile(const std::string& name);
|
||||
bool SaveProfile(const std::string& name);
|
||||
void DeleteProfile(const std::string& name);
|
||||
void OverwriteProfile(const std::string& name);
|
||||
void LoadDefaultProfile();
|
||||
int EnableDefaultButton();
|
||||
virtual int EnableDefaultButton() = 0;
|
||||
|
||||
// xbox device under configuration
|
||||
EmuDevice* m_DeviceConfig;
|
||||
|
@ -82,12 +81,6 @@ private:
|
|||
HWND m_hwnd_device_list;
|
||||
// handle of the profile list combobox
|
||||
HWND m_hwnd_profile_list;
|
||||
// handle of the rumble window
|
||||
HWND m_hwnd_rumble;
|
||||
// handle of the rumble combobox
|
||||
HWND m_hwnd_rumble_list;
|
||||
// handle of the default bindings button
|
||||
HWND m_hwnd_default;
|
||||
// type of the device
|
||||
int m_dev_type;
|
||||
// num of buttons of device under configuration
|
||||
|
@ -96,12 +89,45 @@ private:
|
|||
int m_port_num;
|
||||
// host device under configuration
|
||||
std::string m_host_dev;
|
||||
// currently selected rumble control
|
||||
std::string m_rumble;
|
||||
// indicates if the current profile has unsaved changes
|
||||
bool m_bHasChanges;
|
||||
// prevent current input attempt to set the previous input at same time
|
||||
std::atomic<bool> m_bIsBinding;
|
||||
};
|
||||
|
||||
extern InputWindow* g_InputWindow;
|
||||
class DukeInputWindow : public InputWindow
|
||||
{
|
||||
public:
|
||||
void Initialize(HWND hwnd, int port_num, int dev_type) override;
|
||||
void InitRumble(HWND hwnd);
|
||||
void UpdateRumble(int command);
|
||||
void BindDefault();
|
||||
void ClearBindings() override;
|
||||
void UpdateProfile(const std::string &name, int command) override;
|
||||
|
||||
|
||||
private:
|
||||
int EnableDefaultButton() override;
|
||||
void DetectOutput(int ms);
|
||||
|
||||
// handle of the default bindings button
|
||||
HWND m_hwnd_default;
|
||||
// handle of the rumble window
|
||||
HWND m_hwnd_rumble;
|
||||
// handle of the rumble combobox
|
||||
HWND m_hwnd_rumble_list;
|
||||
// currently selected rumble control
|
||||
std::string m_rumble;
|
||||
};
|
||||
|
||||
class SbcInputWindow : public InputWindow
|
||||
{
|
||||
public:
|
||||
void Initialize(HWND hwnd, int port_num, int dev_type) override;
|
||||
void ClearBindings() override;
|
||||
void UpdateProfile(const std::string &name, int command) override;
|
||||
|
||||
|
||||
private:
|
||||
int EnableDefaultButton() override;
|
||||
};
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define BUF_NAME_LENGTH 30
|
||||
|
||||
#ifndef CXBXR_EMU_EXPORTS
|
||||
#include "gui/resource/ResCxbx.h"
|
||||
|
||||
|
@ -104,7 +106,8 @@ inline int button_sbc_id[SBC_NUM_BUTTONS] = {
|
|||
IDC_AIMING_NEGX,
|
||||
IDC_AIMING_POSY,
|
||||
IDC_AIMING_NEGY,
|
||||
IDC_ROTATION_LEVER,
|
||||
IDC_LEVER_LEFT,
|
||||
IDC_LEVER_RIGHT,
|
||||
IDC_SIGHT_CHANGE_POSX,
|
||||
IDC_SIGHT_CHANGE_NEGX,
|
||||
IDC_SIGHT_CHANGE_POSY,
|
||||
|
@ -112,47 +115,129 @@ inline int button_sbc_id[SBC_NUM_BUTTONS] = {
|
|||
IDC_BTN_LEFT_PEDAL,
|
||||
IDC_BTN_MIDDLE_PEDAL,
|
||||
IDC_BTN_RIGHT_PEDAL,
|
||||
IDC_RADIO_TD0,
|
||||
IDC_RADIO_TD1,
|
||||
IDC_RADIO_TD2,
|
||||
IDC_RADIO_TD3,
|
||||
IDC_RADIO_TD4,
|
||||
IDC_RADIO_TD5,
|
||||
IDC_RADIO_TD6,
|
||||
IDC_RADIO_TD7,
|
||||
IDC_RADIO_TD8,
|
||||
IDC_RADIO_TD9,
|
||||
IDC_RADIO_TD10,
|
||||
IDC_RADIO_TD11,
|
||||
IDC_RADIO_TD12,
|
||||
IDC_GEAR_LEVER,
|
||||
IDC_RADIO_TD_UP,
|
||||
IDC_RADIO_TD_DOWN,
|
||||
IDC_GEAR_UP,
|
||||
IDC_GEAR_DOWN,
|
||||
};
|
||||
#endif
|
||||
|
||||
inline const char* button_xbox_ctrl_names[XBOX_CTRL_NUM_BUTTONS][3] = {
|
||||
"D Pad Up", "Pad N", "UP",
|
||||
"D Pad Down", "Pad S", "DOWN",
|
||||
"D Pad Left", "Pad W", "LEFT",
|
||||
"D Pad Right", "Pad E", "RIGHT",
|
||||
"Start", "Start", "RETURN",
|
||||
"Back", "Back", "SPACE",
|
||||
"L Thumb", "Thumb L", "B",
|
||||
"R Thumb", "Thumb R", "M",
|
||||
"A", "Button A", "S",
|
||||
"B", "Button B", "D",
|
||||
"X", "Button X", "W",
|
||||
"Y", "Button Y", "E",
|
||||
"Black", "Shoulder R", "C",
|
||||
"White", "Shoulder L", "X",
|
||||
"L Trigger", "Trigger L", "Q",
|
||||
"R Trigger", "Trigger R", "R",
|
||||
"Left Axis X+", "Left X+", "H",
|
||||
"Left Axis X-", "Left X-", "F",
|
||||
"Left Axis Y+", "Left Y+", "T",
|
||||
"Left Axis Y-", "Left Y-", "G",
|
||||
"Right Axis X+", "Right X+", "L",
|
||||
"Right Axis X-", "Right X-", "J",
|
||||
"Right Axis Y+", "Right Y+", "I",
|
||||
"Right Axis Y-", "Right Y-", "K",
|
||||
"Motor", "LeftRight", "",
|
||||
inline constexpr const char* button_xbox_ctrl_names[XBOX_CTRL_NUM_BUTTONS] = {
|
||||
"D Pad Up",
|
||||
"D Pad Down",
|
||||
"D Pad Left",
|
||||
"D Pad Right",
|
||||
"Start",
|
||||
"Back",
|
||||
"L Thumb",
|
||||
"R Thumb",
|
||||
"A",
|
||||
"B",
|
||||
"X",
|
||||
"Y",
|
||||
"Black",
|
||||
"White",
|
||||
"L Trigger",
|
||||
"R Trigger",
|
||||
"Left Axis X+",
|
||||
"Left Axis X-",
|
||||
"Left Axis Y+",
|
||||
"Left Axis Y-",
|
||||
"Right Axis X+",
|
||||
"Right Axis X-",
|
||||
"Right Axis Y+",
|
||||
"Right Axis Y-",
|
||||
"Motor",
|
||||
};
|
||||
|
||||
inline constexpr const char *button_sbc_names[SBC_NUM_BUTTONS] = {
|
||||
"RightJoyMainWeapon",
|
||||
"RightJoyFire",
|
||||
"RightJoyLockOn",
|
||||
"Eject",
|
||||
"CockpitHatch",
|
||||
"Ignition",
|
||||
"Start",
|
||||
"MultiMonOpenClose",
|
||||
"MultiMonMapZoomInOut",
|
||||
"MultiMonModeSelect",
|
||||
"MultiMonSubMonitor",
|
||||
"MainMonZoomIn",
|
||||
"MainMonZoomOut",
|
||||
"FunctionFSS",
|
||||
"FunctionManipulator",
|
||||
"FunctionLineColorChange",
|
||||
"Washing",
|
||||
"Extinguisher",
|
||||
"Chaff",
|
||||
"FunctionTankDetach",
|
||||
"FunctionOverride",
|
||||
"FunctionNightScope",
|
||||
"FunctionF1",
|
||||
"FunctionF2",
|
||||
"FunctionF3",
|
||||
"WeaponConMain",
|
||||
"WeaponConSub",
|
||||
"WeaponConMagazine",
|
||||
"Comm1",
|
||||
"Comm2",
|
||||
"Comm3",
|
||||
"Comm4",
|
||||
"Comm5",
|
||||
"LeftJoySightChange",
|
||||
"ToggleFilterControl",
|
||||
"ToggleOxygenSupply",
|
||||
"ToggleFuelFlowRate",
|
||||
"ToggleBufferMaterial",
|
||||
"ToggleVTLocation",
|
||||
"Aiming X+",
|
||||
"Aiming X-",
|
||||
"Aiming Y+",
|
||||
"Aiming Y-",
|
||||
"LeverLeft",
|
||||
"LeverRight",
|
||||
"SightChange X+",
|
||||
"SightChange X-",
|
||||
"SightChange Y+",
|
||||
"SightChange Y-",
|
||||
"LeftPedal",
|
||||
"MiddlePedal",
|
||||
"RightPedal",
|
||||
"TunerDial Up",
|
||||
"TunerDial Down",
|
||||
"GearLever Up",
|
||||
"GearLever Down",
|
||||
};
|
||||
|
||||
constexpr bool check_button_name_size(unsigned max_num_buttons)
|
||||
{
|
||||
switch (max_num_buttons)
|
||||
{
|
||||
case XBOX_CTRL_NUM_BUTTONS: {
|
||||
for (unsigned i = 0; i < max_num_buttons; i++) {
|
||||
if (std::char_traits<char>::length(button_xbox_ctrl_names[i]) > (BUF_NAME_LENGTH - 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SBC_NUM_BUTTONS: {
|
||||
for (unsigned i = 0; i < max_num_buttons; i++) {
|
||||
if (std::char_traits<char>::length(button_sbc_names[i]) > (BUF_NAME_LENGTH - 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sanity checks: the button buffers used in the input system are 30 bytes large, so ensure that we do not exceed them
|
||||
static_assert(check_button_name_size(XBOX_CTRL_NUM_BUTTONS));
|
||||
static_assert(check_button_name_size(SBC_NUM_BUTTONS));
|
||||
|
|
|
@ -132,7 +132,7 @@ class EmuShared : public Mutex
|
|||
void SetInputDevNameSettings(const char* name, int port) { Lock(); strncpy(m_DeviceName[port], name, 50); Unlock(); }
|
||||
void GetInputBindingsSettings(char button_str[][30], int max_num_buttons, int port)
|
||||
{
|
||||
assert(max_num_buttons <= XBOX_CTRL_NUM_BUTTONS);
|
||||
assert(max_num_buttons <= HIGHEST_NUM_BUTTONS);
|
||||
Lock();
|
||||
for (int i = 0; i < max_num_buttons; i++) {
|
||||
strncpy(button_str[i], m_DeviceControlNames[port][i], 30);
|
||||
|
@ -141,7 +141,7 @@ class EmuShared : public Mutex
|
|||
}
|
||||
void SetInputBindingsSettings(const char button_str[][30], int max_num_buttons, int port)
|
||||
{
|
||||
assert(max_num_buttons <= XBOX_CTRL_NUM_BUTTONS);
|
||||
assert(max_num_buttons <= HIGHEST_NUM_BUTTONS);
|
||||
Lock();
|
||||
for (int i = 0; i < max_num_buttons; i++) {
|
||||
strncpy(m_DeviceControlNames[port][i], button_str[i], 30);
|
||||
|
@ -303,7 +303,7 @@ class EmuShared : public Mutex
|
|||
bool m_bReserved4;
|
||||
unsigned int m_dwKrnlProcID; // Only used for kernel mode level.
|
||||
int m_DeviceType[4];
|
||||
char m_DeviceControlNames[4][XBOX_CTRL_NUM_BUTTONS][30]; // macro should be num of buttons of dev with highest num buttons
|
||||
char m_DeviceControlNames[4][HIGHEST_NUM_BUTTONS][30];
|
||||
char m_DeviceName[4][50];
|
||||
long m_MoAxisRange;
|
||||
long m_MoWheelRange;
|
||||
|
|
|
@ -46,33 +46,21 @@
|
|||
#include "core\hle\XAPI\Xapi.h"
|
||||
#include "core\hle\XAPI\XapiCxbxr.h"
|
||||
|
||||
bool g_bCxbxVSBCLoaded = false;
|
||||
HINSTANCE g_module;
|
||||
typedef int (FAR WINAPI *PFARPROC1)(int);
|
||||
typedef int (FAR WINAPI *PFARPROC2)(UCHAR*);
|
||||
typedef int (NEAR WINAPI *PNEARPROC1)(int);
|
||||
typedef int (NEAR WINAPI *PNEARPROC2)(UCHAR*);
|
||||
typedef int (WINAPI *PPROC)();
|
||||
|
||||
PFARPROC2 fnCxbxVSBCSetState;
|
||||
PFARPROC2 fnCxbxVSBCGetState;
|
||||
PFARPROC1 fnCxbxVSBCOpen;
|
||||
//typedef DWORD(*fnCxbxVSBCOpen)(HWND);
|
||||
//typedef DWORD(*fnCxbxVSBCSetState)(UCHAR *);
|
||||
//typedef DWORD(*fnCxbxVSBCGetState)(UCHAR *);
|
||||
xbox::PXPP_DEVICE_TYPE g_DeviceType_Gamepad = nullptr;
|
||||
xbox::PXPP_DEVICE_TYPE g_DeviceType_SBC = nullptr; //deviceTable[i]->XppType?
|
||||
xbox::PXPP_DEVICE_TYPE g_DeviceType_SBC = nullptr;
|
||||
|
||||
// Flag is unset after initialize devices is done by simulate LLE USB thread.
|
||||
std::atomic<bool> g_bIsDevicesInitializing = true;
|
||||
std::atomic<bool> g_bIsDevicesEmulating = false;
|
||||
static CXBX_XINPUT_IN_STATE InState[4];
|
||||
|
||||
//global bridge for xbox controller to host, 4 elements for 4 ports.
|
||||
CXBX_CONTROLLER_HOST_BRIDGE g_XboxControllerHostBridge[4] = {
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, &InState[0], false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, &InState[1], false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, &InState[2], false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, &InState[3], false, false, false, { 0, 0, 0, 0, 0 } },
|
||||
};
|
||||
|
||||
|
||||
|
@ -114,14 +102,13 @@ bool operator!=(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
|
|||
bool ConstructHleInputDevice(int Type, int Port)
|
||||
{
|
||||
g_bIsDevicesEmulating = true;
|
||||
bool ret = true;
|
||||
bool ret;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
|
||||
g_XboxControllerHostBridge[Port].XboxPort = Port;
|
||||
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE;
|
||||
g_XboxControllerHostBridge[Port].InState = new XpadInput();
|
||||
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
|
||||
g_XboxControllerHostBridge[Port].bSignaled = false;
|
||||
g_XboxControllerHostBridge[Port].bIoInProgress = false;
|
||||
|
@ -130,12 +117,13 @@ bool ConstructHleInputDevice(int Type, int Port)
|
|||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
|
||||
ret = true;
|
||||
}
|
||||
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;
|
||||
|
@ -144,36 +132,39 @@ bool ConstructHleInputDevice(int Type, int Port)
|
|||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
|
||||
g_XboxControllerHostBridge[Port].XboxPort = Port;
|
||||
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER;
|
||||
g_XboxControllerHostBridge[Port].InState = new SBCInput();
|
||||
g_XboxControllerHostBridge[Port].InState->SBC.ucGearLever = 8;
|
||||
g_XboxControllerHostBridge[Port].InState->SBC.sAimingX = static_cast<uint8_t>(0x7F);
|
||||
g_XboxControllerHostBridge[Port].InState->SBC.sAimingY = static_cast<uint8_t>(0x7F);
|
||||
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
|
||||
g_XboxControllerHostBridge[Port].bSignaled = false;
|
||||
g_XboxControllerHostBridge[Port].bIoInProgress = false;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = XINPUT_DEVTYPE_STEELBATTALION;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = 0x18;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = 0x14;
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(SBCInput);
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(SBCOutput);
|
||||
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN):
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):
|
||||
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE): {
|
||||
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE):
|
||||
EmuLog(LOG_LEVEL::INFO, "%s: device %s is not yet supported", __func__, GetInputDeviceName(Type).c_str());
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
EmuLog(LOG_LEVEL::WARNING, "Attempted to attach an unknown device type (type was %d)", Type);
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
g_bIsDevicesEmulating = false;
|
||||
|
@ -187,7 +178,7 @@ void DestructHleInputDevice(int Port)
|
|||
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::DEVICE_INVALID;
|
||||
g_XboxControllerHostBridge[Port].XboxPort = PORT_INVALID;
|
||||
while (g_XboxControllerHostBridge[Port].bIoInProgress) {}
|
||||
delete g_XboxControllerHostBridge[Port].InState;
|
||||
std::memset(&InState[Port], 0, g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize);
|
||||
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
|
||||
g_XboxControllerHostBridge[Port].bSignaled = false;
|
||||
g_XboxControllerHostBridge[Port].bIoInProgress = false;
|
||||
|
@ -207,7 +198,7 @@ void SetupXboxDeviceTypes()
|
|||
// First, attempt to find GetTypeInformation
|
||||
auto typeInformation = g_SymbolAddresses.find("GetTypeInformation");
|
||||
if (typeInformation != g_SymbolAddresses.end() && typeInformation->second != xbox::zero) {
|
||||
printf("Deriving XDEVICE_TYPE_GAMEPAD from DeviceTable (via GetTypeInformation)\n");
|
||||
EmuLog(LOG_LEVEL::INFO, "Deriving XDEVICE_TYPE_GAMEPAD from DeviceTable (via GetTypeInformation)");
|
||||
// Read the offset values of the device table structure from GetTypeInformation
|
||||
xbox::addr_xt deviceTableStartOffset = *(uint32_t*)((uint32_t)typeInformation->second + 0x01);
|
||||
xbox::addr_xt deviceTableEndOffset = *(uint32_t*)((uint32_t)typeInformation->second + 0x09);
|
||||
|
@ -215,9 +206,9 @@ void SetupXboxDeviceTypes()
|
|||
// Calculate the number of device entires in the table
|
||||
size_t deviceTableEntryCount = (deviceTableEndOffset - deviceTableStartOffset) / sizeof(uint32_t);
|
||||
|
||||
printf("DeviceTableStart: 0x%08X\n", deviceTableStartOffset);
|
||||
printf("DeviceTableEnd: 0x%08X\n", deviceTableEndOffset);
|
||||
printf("DeviceTable Entires: %u\n", deviceTableEntryCount);
|
||||
EmuLog(LOG_LEVEL::INFO, "DeviceTableStart: 0x%08X", deviceTableStartOffset);
|
||||
EmuLog(LOG_LEVEL::INFO, "DeviceTableEnd: 0x%08X", deviceTableEndOffset);
|
||||
EmuLog(LOG_LEVEL::INFO, "DeviceTable Entires: %u", deviceTableEntryCount);
|
||||
|
||||
// Sanity check: Where all these device offsets within Xbox memory
|
||||
if ((deviceTableStartOffset >= g_SystemMaxMemory) || (deviceTableEndOffset >= g_SystemMaxMemory)) {
|
||||
|
@ -232,21 +223,22 @@ void SetupXboxDeviceTypes()
|
|||
continue;
|
||||
}
|
||||
|
||||
printf("----------------------------------------\n");
|
||||
printf("DeviceTable[%u]->ucType = %d\n", i, deviceTable[i]->ucType);
|
||||
printf("DeviceTable[%u]->XppType = 0x%08X (", i, (uintptr_t)deviceTable[i]->XppType);
|
||||
EmuLog(LOG_LEVEL::INFO, "----------------------------------------");
|
||||
EmuLog(LOG_LEVEL::INFO, "DeviceTable[%u]->ucType = %d", i, deviceTable[i]->ucType);
|
||||
|
||||
switch (deviceTable[i]->ucType) {
|
||||
case XINPUT_DEVTYPE_GAMEPAD:
|
||||
g_DeviceType_Gamepad = deviceTable[i]->XppType;
|
||||
printf("XDEVICE_TYPE_GAMEPAD)\n");
|
||||
EmuLog(LOG_LEVEL::INFO, "DeviceTable[%u]->XppType = 0x%08X (XDEVICE_TYPE_GAMEPAD)", i, (uintptr_t)g_DeviceType_Gamepad);
|
||||
break;
|
||||
|
||||
case XINPUT_DEVTYPE_STEELBATTALION:
|
||||
g_DeviceType_SBC = deviceTable[i]->XppType;
|
||||
printf("XDEVICE_TYPE_STEELBATTALION)\n");
|
||||
EmuLog(LOG_LEVEL::INFO, "DeviceTable[%u]->XppType = 0x%08X (XDEVICE_TYPE_STEELBATTALION)", i, (uintptr_t)g_DeviceType_SBC);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown device type)\n");
|
||||
EmuLog(LOG_LEVEL::WARNING, "DeviceTable[%u]->XppType = 0x%08X (Unknown device type)", i, (uintptr_t)deviceTable[i]->XppType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +248,7 @@ void SetupXboxDeviceTypes()
|
|||
// so this works well for us.
|
||||
void* XInputOpenAddr = (void*)g_SymbolAddresses["XInputOpen"];
|
||||
if (XInputOpenAddr != nullptr) {
|
||||
printf("XAPI: Deriving XDEVICE_TYPE_GAMEPAD from XInputOpen (0x%08X)\n", (uintptr_t)XInputOpenAddr);
|
||||
EmuLog(LOG_LEVEL::INFO, "Deriving XDEVICE_TYPE_GAMEPAD from XInputOpen (0x%08X)", (uintptr_t)XInputOpenAddr);
|
||||
g_DeviceType_Gamepad = *(xbox::PXPP_DEVICE_TYPE*)((uint32_t)XInputOpenAddr + 0x0B);
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +258,7 @@ void SetupXboxDeviceTypes()
|
|||
return;
|
||||
}
|
||||
|
||||
printf("XAPI: XDEVICE_TYPE_GAMEPAD Found at 0x%08X\n", (uintptr_t)g_DeviceType_Gamepad);
|
||||
EmuLog(LOG_LEVEL::INFO, "XDEVICE_TYPE_GAMEPAD Found at 0x%08X", (uintptr_t)g_DeviceType_Gamepad);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,32 +426,6 @@ xbox::HANDLE WINAPI xbox::EMUPATCH(XInputOpen)
|
|||
|
||||
if (dwPort >= PORT_1 && dwPort <= PORT_4) {
|
||||
if (DeviceType == g_XboxControllerHostBridge[dwPort].XboxType) {
|
||||
#if 0 // TODO
|
||||
if(g_XboxControllerHostBridge[dwPort].dwHostType==X_XONTROLLER_HOST_BRIDGE_HOSTTYPE_VIRTUAL_SBC){
|
||||
//if DLL not loaded yet, load it.
|
||||
if (g_bCxbxVSBCLoaded != true) {
|
||||
|
||||
g_module = LoadLibrary(TEXT("CxbxVSBC.dll"));
|
||||
if (g_module != 0) {
|
||||
g_bCxbxVSBCLoaded = true;
|
||||
}
|
||||
}
|
||||
if(g_module!=0&& fnCxbxVSBCOpen==0){
|
||||
fnCxbxVSBCSetState = (PFARPROC2)GetProcAddress(g_module, "VSBCSetState");
|
||||
fnCxbxVSBCGetState = (PFARPROC2)GetProcAddress(g_module, "VSBCGetState");
|
||||
fnCxbxVSBCOpen = (PFARPROC1)GetProcAddress(g_module, "VSBCOpen");
|
||||
}
|
||||
|
||||
if (fnCxbxVSBCOpen == 0) {
|
||||
printf("EmuXapi: EmuXInputOpen: GetPRocAddress VSBCOpen failed!\n");
|
||||
}
|
||||
else {
|
||||
(*fnCxbxVSBCOpen)(X_XONTROLLER_HOST_BRIDGE_HOSTTYPE_VIRTUAL_SBC);
|
||||
}
|
||||
//DWORD dwVXBCOpenResult = CxbxVSBC::MyCxbxVSBC::VSBCOpen(X_XONTROLLER_HOST_BRIDGE_HOSTTYPE_VIRTUAL_SBC);
|
||||
|
||||
}
|
||||
#endif
|
||||
g_XboxControllerHostBridge[dwPort].hXboxDevice = &g_XboxControllerHostBridge[dwPort];
|
||||
RETURN(g_XboxControllerHostBridge[dwPort].hXboxDevice);
|
||||
}
|
||||
|
@ -528,234 +494,6 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XInputGetCapabilities)
|
|||
RETURN(ret);
|
||||
}
|
||||
|
||||
//variable names correlated to SBC_FEEDBACK, mapped to each nibble accordingly.
|
||||
char * XboxSBCFeedbackNames[] = {
|
||||
"EmergencyEject",
|
||||
"CockpitHatch",
|
||||
"Ignition",
|
||||
"Start",
|
||||
"OpenClose",
|
||||
"RightJoyMainWeapon",
|
||||
"RightJoyLockOn",
|
||||
"RightJoyFire",
|
||||
"MapZoomInOut",
|
||||
"ModeSelect",
|
||||
"SubMonitorModeSelect",
|
||||
"MainMonitorZoomIn",
|
||||
"MainMonitorZoomOut",
|
||||
"ForecastShootingSystem",
|
||||
"Manipulator",
|
||||
"LineColorChange",
|
||||
"Washing",
|
||||
"Extinguisher",
|
||||
"Chaff",
|
||||
"TankDetach",
|
||||
"Override",
|
||||
"NightScope",
|
||||
"F1",
|
||||
"F2",
|
||||
"F3",
|
||||
"MainWeaponControl",
|
||||
"SubWeaponControl",
|
||||
"MagazineChange",
|
||||
"Comm1",
|
||||
"Comm2",
|
||||
"Comm3",
|
||||
"Comm4",
|
||||
"Comm5",
|
||||
"Unknown",
|
||||
"GearR",
|
||||
"GearN",
|
||||
"Gear1",
|
||||
"Gear2",
|
||||
"Gear3",
|
||||
"Gear4",
|
||||
"Gear5"
|
||||
};
|
||||
|
||||
//keep last SBC_GAMEPAD status, for DIP switch and GearLever
|
||||
xbox::SBC_GAMEPAD XboxSBCGamepad = {};
|
||||
|
||||
//virtual SteelBattalion controller GetState, using port 0 from XInput and DirectInput to emulate virtual controller.
|
||||
void EmuSBCGetState(xbox::PSBC_GAMEPAD pSBCGamepad, xbox::PXINPUT_GAMEPAD pXIGamepad, xbox::PXINPUT_GAMEPAD pDIGamepad)
|
||||
{
|
||||
// Now convert those values to SteelBattalion Gamepad
|
||||
|
||||
//restore certain variables such as GerLever and Toggle Switches.
|
||||
|
||||
//restore the kept ucGearLever
|
||||
pSBCGamepad->ucGearLever = XboxSBCGamepad.ucGearLever;
|
||||
//we use continues range 7~13, 8 for gear N.
|
||||
if (pSBCGamepad->ucGearLever < 7 || pSBCGamepad->ucGearLever>13) {
|
||||
pSBCGamepad->ucGearLever = 8;
|
||||
}
|
||||
|
||||
//restore Toggle Switches.
|
||||
pSBCGamepad->wButtons[0] |= (XboxSBCGamepad.wButtons[0] & (CXBX_SBC_GAMEPAD_W0_COCKPITHATCH | CXBX_SBC_GAMEPAD_W0_IGNITION));
|
||||
|
||||
pSBCGamepad->wButtons[2] |= (XboxSBCGamepad.wButtons[2]&( CXBX_SBC_GAMEPAD_W2_TOGGLEFILTERCONTROL
|
||||
| CXBX_SBC_GAMEPAD_W2_TOGGLEOXYGENSUPPLY
|
||||
| CXBX_SBC_GAMEPAD_W2_TOGGLEFUELFLOWRATE
|
||||
| CXBX_SBC_GAMEPAD_W2_TOGGLEBUFFREMATERIAL
|
||||
| CXBX_SBC_GAMEPAD_W2_TOGGLEVTLOCATION));
|
||||
|
||||
|
||||
// Analog Sticks
|
||||
pSBCGamepad->sAimingX = pXIGamepad->sThumbRX;
|
||||
pSBCGamepad->sAimingY = pXIGamepad->sThumbRY;
|
||||
pSBCGamepad->sRotationLever = 0;//(pXIGamepad->wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 255 : 0;
|
||||
pSBCGamepad->sSightChangeX = pXIGamepad->sThumbLX;
|
||||
pSBCGamepad->sSightChangeY = pXIGamepad->sThumbLY;
|
||||
pSBCGamepad->wLeftPedal = ((SHORT)(pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_LEFT_TRIGGER]))<<8;
|
||||
pSBCGamepad->wMiddlePedal=0;// = (pXIGamepad->wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 255 : 0;
|
||||
pSBCGamepad->wRightPedal = (SHORT)(pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_RIGHT_TRIGGER])<<8;
|
||||
pSBCGamepad->ucTunerDial=0;//low nibble
|
||||
|
||||
|
||||
// Digital Buttons
|
||||
if (pXIGamepad->bAnalogButtons [CXBX_XINPUT_GAMEPAD_A]>0) {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_RIGHTJOYMAINWEAPON;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_RIGHTJOYMAINWEAPON;
|
||||
}
|
||||
if (pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_B]>0) {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_RIGHTJOYFIRE;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_RIGHTJOYFIRE;
|
||||
}
|
||||
if (pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_X]>0) {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_RIGHTJOYLOCKON;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_RIGHTJOYLOCKON;
|
||||
}
|
||||
if (pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_Y]>0) {
|
||||
pSBCGamepad->wButtons[1] |= CXBX_SBC_GAMEPAD_W1_WEAPONCONMAGAZINE;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[1] &= ~CXBX_SBC_GAMEPAD_W1_WEAPONCONMAGAZINE;
|
||||
}
|
||||
|
||||
//GearLever 1~5 for gear 1~5, 7~13 for gear R,N,1~5, 15 for gear R. we use the continues range from 7~13
|
||||
if (pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_WHITE]>0) {//Left Shouder, Gear Down
|
||||
if (pSBCGamepad->ucGearLever >7) {
|
||||
pSBCGamepad->ucGearLever-- ;
|
||||
}
|
||||
}
|
||||
|
||||
if (pXIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_BLACK]>0) {//Right Shouder, Gear Up
|
||||
if (pSBCGamepad->ucGearLever < 13) {
|
||||
pSBCGamepad->ucGearLever ++;
|
||||
}
|
||||
}
|
||||
//OLD_XINPUT
|
||||
/* //not used, don't duplicate the handling for same setting of pXIGamepad's members, later one will over write privous one.
|
||||
if (pXIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_START) {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_START;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_START;
|
||||
}
|
||||
*/
|
||||
if (pXIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_LEFT_THUMB) {//Center Sight Change
|
||||
pSBCGamepad->wButtons[2] |= CXBX_SBC_GAMEPAD_W2_LEFTJOYSIGHTCHANGE;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[2] &= ~CXBX_SBC_GAMEPAD_W2_LEFTJOYSIGHTCHANGE;
|
||||
}
|
||||
//OLD_XINPUT
|
||||
/* //not used
|
||||
if (pXIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_RIGHT_THUMB) {
|
||||
pSBCGamepad->wButtons |= CXBX_XINPUT_GAMEPAD_RIGHT_THUMB;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons &= ~CXBX_XINPUT_GAMEPAD_RIGHT_THUMB;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//additional input from 2nd input, default using directinput
|
||||
if (pDIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_A]>0) {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_START;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_START;
|
||||
}
|
||||
// Iginition is Toggle Switch
|
||||
if (pDIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_B]>0) {
|
||||
if (pSBCGamepad->wButtons[0] & CXBX_SBC_GAMEPAD_W0_IGNITION) {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_IGNITION;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_IGNITION;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_X]>0) {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_EJECT;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_EJECT;
|
||||
}
|
||||
// CockpitHatch is Toggle Switch
|
||||
if (pDIGamepad->bAnalogButtons[CXBX_XINPUT_GAMEPAD_Y]>0) {
|
||||
if (pSBCGamepad->wButtons[0] & CXBX_SBC_GAMEPAD_W0_COCKPITHATCH) {
|
||||
pSBCGamepad->wButtons[0] &= ~CXBX_SBC_GAMEPAD_W0_COCKPITHATCH;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[0] |= CXBX_SBC_GAMEPAD_W0_COCKPITHATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_BACK) {//Toggle Switch ToggleFilterControl
|
||||
if (pSBCGamepad->wButtons[2] & CXBX_SBC_GAMEPAD_W2_TOGGLEFILTERCONTROL) {
|
||||
pSBCGamepad->wButtons[2] &= ~CXBX_SBC_GAMEPAD_W2_TOGGLEFILTERCONTROL;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[2] |= CXBX_SBC_GAMEPAD_W2_TOGGLEFILTERCONTROL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_DPAD_UP) {//Toggle Switch ToggleOxygenSupply
|
||||
if (pSBCGamepad->wButtons[2] & CXBX_SBC_GAMEPAD_W2_TOGGLEOXYGENSUPPLY) {
|
||||
pSBCGamepad->wButtons[2] &= ~CXBX_SBC_GAMEPAD_W2_TOGGLEOXYGENSUPPLY;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[2] |= CXBX_SBC_GAMEPAD_W2_TOGGLEOXYGENSUPPLY;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_DPAD_DOWN) {//Toggle Switch ToggleBuffreMaterial
|
||||
if (pSBCGamepad->wButtons[2] & CXBX_SBC_GAMEPAD_W2_TOGGLEBUFFREMATERIAL) {
|
||||
pSBCGamepad->wButtons[2] &= ~CXBX_SBC_GAMEPAD_W2_TOGGLEBUFFREMATERIAL;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[2] |= CXBX_SBC_GAMEPAD_W2_TOGGLEBUFFREMATERIAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_DPAD_LEFT) {//Toggle Switch ToggleVTLocation
|
||||
if (pSBCGamepad->wButtons[2] & CXBX_SBC_GAMEPAD_W2_TOGGLEVTLOCATION) {
|
||||
pSBCGamepad->wButtons[2] &= ~CXBX_SBC_GAMEPAD_W2_TOGGLEVTLOCATION;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[2] |= CXBX_SBC_GAMEPAD_W2_TOGGLEVTLOCATION;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDIGamepad->wButtons & CXBX_XINPUT_GAMEPAD_DPAD_RIGHT) {//Toggle Switch ToggleFuelFlowRate
|
||||
if (pSBCGamepad->wButtons[2] & CXBX_SBC_GAMEPAD_W2_TOGGLEFUELFLOWRATE) {
|
||||
pSBCGamepad->wButtons[2] &= ~CXBX_SBC_GAMEPAD_W2_TOGGLEFUELFLOWRATE;
|
||||
}
|
||||
else {
|
||||
pSBCGamepad->wButtons[2] |= CXBX_SBC_GAMEPAD_W2_TOGGLEFUELFLOWRATE;
|
||||
}
|
||||
}
|
||||
//reserve the SBCGamepad to keep the status of GearLever and Toggole Switches.
|
||||
XboxSBCGamepad = *pSBCGamepad;
|
||||
}
|
||||
// ******************************************************************
|
||||
// * patch: XInputGetState
|
||||
// ******************************************************************
|
||||
|
@ -781,7 +519,7 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XInputGetState)
|
|||
if (g_InputDeviceManager.UpdateXboxPortInput(Port, g_XboxControllerHostBridge[Port].InState, DIRECTION_IN, to_underlying(g_XboxControllerHostBridge[Port].XboxType))) {
|
||||
pState->dwPacketNumber = g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber++;
|
||||
}
|
||||
memcpy((void*)&pState->Gamepad, g_XboxControllerHostBridge[Port].InState, sizeof(pState->Gamepad));
|
||||
memcpy((void*)&pState->Gamepad, g_XboxControllerHostBridge[Port].InState, g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize);
|
||||
g_XboxControllerHostBridge[Port].bIoInProgress = false;
|
||||
ret = ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -111,13 +111,13 @@ typedef struct _XID_TYPE_INFORMATION
|
|||
{
|
||||
xbox::uchar_xt ucType;
|
||||
xbox::byte_xt bRemainingHandles;
|
||||
xbox::uchar_xt ucUnknown[2];//probably for xbox::dword_xt align
|
||||
PXPP_DEVICE_TYPE XppType;//pointer to DeviceType structure.
|
||||
PXPP_DEVICE_INPUTSTATE_DESC pInputStateDesc;//pointer to InputStateDesc structure
|
||||
PXPP_DEVICE_FEEDBACK_DESC pFeedbackDesc;//pointer to FeedbackDesc structure
|
||||
xbox::dword_xt * pConstant;//always 0x0801
|
||||
void * pFunction;//unknown function for device related process
|
||||
xbox::dword_xt dwEndZero;//last DWROD, always 0
|
||||
xbox::uchar_xt ucUnknown[2]; // probably for xbox::dword_xt align
|
||||
PXPP_DEVICE_TYPE XppType; // pointer to DeviceType structure.
|
||||
PXPP_DEVICE_INPUTSTATE_DESC pInputStateDesc; // pointer to InputStateDesc structure
|
||||
PXPP_DEVICE_FEEDBACK_DESC pFeedbackDesc; // pointer to FeedbackDesc structure
|
||||
xbox::dword_xt * pConstant; // always 0x0801
|
||||
void * pFunction; // unknown function for device related process
|
||||
xbox::dword_xt dwEndZero; // last DWROD, always 0
|
||||
} XID_TYPE_INFORMATION, *PXID_TYPE_INFORMATION;
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -130,6 +130,7 @@ typedef struct _XDEVICE_PREALLOC_TYPE
|
|||
}
|
||||
XDEVICE_PREALLOC_TYPE, *PXDEVICE_PREALLOC_TYPE;
|
||||
|
||||
#pragma pack(1)
|
||||
// ******************************************************************
|
||||
// * XINPUT_GAMEPAD for xbox, xbox's GAMEPAD struct differs from PC's
|
||||
// ******************************************************************
|
||||
|
@ -145,43 +146,24 @@ typedef struct _XINPUT_GAMEPAD
|
|||
XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||
|
||||
// ******************************************************************
|
||||
// * X_SBC_GAMEPAD for xbox SteelBattalion GAMEPAD struc
|
||||
// * X_SBC_GAMEPAD for xbox SteelBattalion GAMEPAD struct
|
||||
// ******************************************************************
|
||||
typedef struct _SBC_GAMEPAD {
|
||||
xbox::word_xt wButtons[3];
|
||||
xbox::short_xt sAimingX;
|
||||
xbox::short_xt sAimingY;
|
||||
xbox::short_xt sRotationLever;//maybe only high byte was used.
|
||||
xbox::ushort_xt sAimingX;
|
||||
xbox::ushort_xt sAimingY;
|
||||
xbox::short_xt sRotationLever; //maybe only high byte was used.
|
||||
xbox::short_xt sSightChangeX;
|
||||
xbox::short_xt sSightChangeY;
|
||||
xbox::word_xt wLeftPedal;//maybe only high byte was used.
|
||||
xbox::word_xt wMiddlePedal;//maybe only high byte was used.
|
||||
xbox::word_xt wRightPedal;//maybe only high byte was used.
|
||||
xbox::uchar_xt ucTunerDial;//low nibble, The 9 o'clock postion is 0, and the 6 o'clock position is 12. The blank area between the 6 and 9 o'clock positions is 13, 14, and 15 clockwise.
|
||||
xbox::uchar_xt ucGearLever;//GearLever 1~5 for gear 1~5, 7~13 for gear R,N,1~5, 15 for gear R. we use the continues range from 7~13
|
||||
xbox::word_xt wLeftPedal; //maybe only high byte was used.
|
||||
xbox::word_xt wMiddlePedal; //maybe only high byte was used.
|
||||
xbox::word_xt wRightPedal; //maybe only high byte was used.
|
||||
xbox::uchar_xt ucTunerDial; //low nibble, The 9 o'clock postion is 0, and the 6 o'clock position is 12. The blank area between the 6 and 9 o'clock positions is 13, 14, and 15 clockwise.
|
||||
xbox::uchar_xt ucGearLever; //GearLever 1~5 for gear 1~5, 7~13 for gear R,N,1~5, 15 for gear R. we use the continues range from 7~13
|
||||
}
|
||||
SBC_GAMEPAD, *PSBC_GAMEPAD;
|
||||
|
||||
// ergo720: from the description of the above gear levers, the gear to use is probably interpreted by looking at the first 3 bits of ucGearLever.
|
||||
// Remove this when this theory is confirmed to be true or false
|
||||
/*
|
||||
0000 0000 -> should be N ??
|
||||
0000 0001 1
|
||||
0000 0010 2
|
||||
0000 0011 3
|
||||
0000 0100 4
|
||||
0000 0101 5
|
||||
0000 0110
|
||||
0000 0111 R
|
||||
0000 1000 N
|
||||
0000 1001 1
|
||||
0000 1010 2
|
||||
0000 1011 3
|
||||
0000 1100 4
|
||||
0000 1101 5
|
||||
0000 1110
|
||||
0000 1111 R
|
||||
*/
|
||||
#pragma pack()
|
||||
|
||||
// ******************************************************************
|
||||
// * XINPUT_RUMBLE
|
||||
|
@ -223,7 +205,7 @@ XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
|
|||
// all game controller use 0x01 GAMEPAD device type. then specify the subtype in returned Capabilities when XInputGetCapabilities called.
|
||||
#define XINPUT_DEVTYPE_GAMEPAD 0x01
|
||||
// SteelBattalion controller is the only one with special device type other than 1.
|
||||
#define XINPUT_DEVTYPE_STEELBATTALION 0x80
|
||||
#define XINPUT_DEVTYPE_STEELBATTALION 0x80
|
||||
|
||||
// ******************************************************************
|
||||
// * Device XBOX Input Device SubTypes, for use in XINPUT_CAPABILITIES
|
||||
|
|
|
@ -31,18 +31,25 @@
|
|||
// ******************************************************************
|
||||
// * XINPUT_DEVICE_INFO
|
||||
// ******************************************************************
|
||||
|
||||
typedef struct _CXBX_XINPUT_DEVICE_INFO
|
||||
{
|
||||
|
||||
UCHAR ucType; //xbox controller type
|
||||
UCHAR ucSubType; //xbox controller subtype
|
||||
UCHAR ucInputStateSize; //xbox controller input state size in bytes, not include dwPacketNumber
|
||||
UCHAR ucFeedbackSize; //xbox controller feedback size in bytes, not include FeedbackHeader
|
||||
DWORD dwPacketNumber;
|
||||
uint8_t ucType; //xbox controller type
|
||||
uint8_t ucSubType; //xbox controller subtype
|
||||
uint8_t ucInputStateSize; //xbox controller input state size in bytes, not include dwPacketNumber
|
||||
uint8_t ucFeedbackSize; //xbox controller feedback size in bytes, not include FeedbackHeader
|
||||
uint16_t dwPacketNumber;
|
||||
}
|
||||
CXBX_XINPUT_DEVICE_INFO, *PCXBX_XINPUT_DEVICE_INFO;
|
||||
|
||||
// ******************************************************************
|
||||
// * XINPUT_IN_STATE
|
||||
// ******************************************************************
|
||||
union CXBX_XINPUT_IN_STATE {
|
||||
XpadInput Gamepad;
|
||||
SBCInput SBC;
|
||||
};
|
||||
|
||||
//this structure is for use of tracking the xbox controllers assigned to 4 ports.
|
||||
// ******************************************************************
|
||||
// * CXBX_CONTROLLER_HOST_BRIDGE
|
||||
|
@ -52,7 +59,7 @@ typedef struct _CXBX_CONTROLLER_HOST_BRIDGE
|
|||
HANDLE hXboxDevice; //xbox device handle to this device, we use the address of this bridge as the handle, only set after opened. cleared after closed.
|
||||
int XboxPort; //xbox port# for this xbox controller
|
||||
XBOX_INPUT_DEVICE XboxType; //xbox device type
|
||||
void* InState;
|
||||
CXBX_XINPUT_IN_STATE * InState;
|
||||
bool bPendingRemoval;
|
||||
bool bSignaled;
|
||||
bool bIoInProgress;
|
||||
|
|
|
@ -64,11 +64,11 @@ void SyncInputSettings(int port_num, int dev_type, bool is_opt)
|
|||
return false;
|
||||
});
|
||||
if (it != g_Settings->m_input_profiles[dev_type].end()) {
|
||||
char controls_name[XBOX_CTRL_NUM_BUTTONS][30];
|
||||
char controls_name[HIGHEST_NUM_BUTTONS][30];
|
||||
for (int index = 0; index < dev_num_buttons[dev_type]; index++) {
|
||||
strncpy(controls_name[index], it->ControlList[index].c_str(), 30);
|
||||
}
|
||||
g_EmuShared->SetInputBindingsSettings(controls_name, XBOX_CTRL_NUM_BUTTONS, port_num);
|
||||
g_EmuShared->SetInputBindingsSettings(controls_name, dev_num_buttons[dev_type], port_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,11 +115,15 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
|
||||
for (int i = 0, j = 0; i != 4; i++) {
|
||||
HWND hHandle = GetDlgItem(hWndDlg, IDC_DEVICE_PORT1 + i);
|
||||
for (auto input : input_support_list) {
|
||||
LRESULT index = SendMessage(hHandle, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(input.name));
|
||||
SendMessage(hHandle, CB_SETITEMDATA, index,
|
||||
to_underlying(input.type));
|
||||
if (g_Settings->m_input_port[i].Type == to_underlying(input.type)) {
|
||||
for (auto dev_type : {
|
||||
XBOX_INPUT_DEVICE::DEVICE_INVALID,
|
||||
XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE,
|
||||
XBOX_INPUT_DEVICE::MS_CONTROLLER_S,
|
||||
XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER
|
||||
}) {
|
||||
LRESULT index = SendMessage(hHandle, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(dev_type)).c_str()));
|
||||
SendMessage(hHandle, CB_SETITEMDATA, index, to_underlying(dev_type));
|
||||
if (g_Settings->m_input_port[i].Type == to_underlying(dev_type)) {
|
||||
SendMessage(hHandle, CB_SETCURSEL, index, 0);
|
||||
if (g_Settings->m_input_port[i].Type == to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
||||
EnableWindow(GetDlgItem(hWndDlg, IDC_CONFIGURE_PORT1 + i), FALSE);
|
||||
|
@ -175,6 +179,9 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
assert(port != -1);
|
||||
HWND hHandle = GetDlgItem(hWndDlg, IDC_DEVICE_PORT1 + port);
|
||||
int DeviceType = SendMessage(hHandle, CB_GETITEMDATA, SendMessage(hHandle, CB_GETCURSEL, 0, 0), 0);
|
||||
assert(DeviceType > to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID) &&
|
||||
DeviceType < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX));
|
||||
|
||||
if (g_bHasOptChanges) {
|
||||
UpdateInputOpt(hWndDlg);
|
||||
g_InputDeviceManager.UpdateOpt(true);
|
||||
|
@ -190,7 +197,7 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
|
||||
DialogBoxParam(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDD_VIRTUAL_SBC_FEEDBACK), hWndDlg, DlgSBControllerConfigProc,
|
||||
DialogBoxParam(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDD_SBC_CFG), hWndDlg, DlgSBControllerConfigProc,
|
||||
(DeviceType << 8) | port);
|
||||
}
|
||||
break;
|
||||
|
@ -198,8 +205,6 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
|||
default:
|
||||
break;
|
||||
}
|
||||
assert(DeviceType > to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID) &&
|
||||
DeviceType < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX));
|
||||
|
||||
// Also inform the kernel process if it exists
|
||||
SyncInputSettings(port, DeviceType, false);
|
||||
|
|
|
@ -34,6 +34,205 @@
|
|||
#include "common/Logging.h"
|
||||
|
||||
|
||||
static constexpr std::array<std::array<const char *, XBOX_CTRL_NUM_BUTTONS>, 2> button_xbox_ctrl_default = { {
|
||||
{ "Pad N", "Pad S", "Pad W", "Pad E", "Start", "Back", "Thumb L", "Thumb R", "Button A", "Button B", "Button X", "Button Y", "Shoulder R", "Shoulder L", "Trigger L",
|
||||
"Trigger R", "Left X+", "Left X-", "Left Y+", "Left Y-", "Right X+", "Right X-", "Right Y+", "Right Y-", "LeftRight" },
|
||||
{ "UP", "DOWN", "LEFT", "RIGHT", "RETURN", "SPACE", "B", "M", "S", "D", "W", "E", "C", "X", "Q", "R", "H", "F", "T", "G", "L", "J", "I", "K", "" }
|
||||
} };
|
||||
|
||||
static DukeInputWindow *g_InputWindow = nullptr;
|
||||
|
||||
void DukeInputWindow::Initialize(HWND hwnd, int port_num, int dev_type)
|
||||
{
|
||||
// Save window/device specific variables
|
||||
m_hwnd_window = hwnd;
|
||||
m_hwnd_device_list = GetDlgItem(m_hwnd_window, IDC_DEVICE_LIST);
|
||||
m_hwnd_profile_list = GetDlgItem(m_hwnd_window, IDC_PROFILE_NAME);
|
||||
m_hwnd_default = GetDlgItem(m_hwnd_window, IDC_DEFAULT);
|
||||
m_dev_type = dev_type;
|
||||
m_max_num_buttons = dev_num_buttons[dev_type];
|
||||
m_port_num = port_num;
|
||||
m_bHasChanges = false;
|
||||
m_bIsBinding = false;
|
||||
|
||||
// Set window icon
|
||||
SetClassLong(m_hwnd_window, GCL_HICON, (LONG)LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_CXBX)));
|
||||
|
||||
// Set window title
|
||||
std::string title;
|
||||
switch (m_dev_type)
|
||||
{
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
|
||||
title += "Xbox Controller Duke at port ";
|
||||
}
|
||||
break;
|
||||
|
||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
|
||||
title += "Xbox Controller S at port ";
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
SendMessage(m_hwnd_window, WM_SETTEXT, 0,
|
||||
reinterpret_cast<LPARAM>((title + std::to_string(PORT_INC(m_port_num))).c_str()));
|
||||
|
||||
// Set the maximum profile name lenght the user can enter in the profile combobox
|
||||
SendMessage(m_hwnd_profile_list, CB_LIMITTEXT, 49, 0);
|
||||
|
||||
// construct emu device
|
||||
m_DeviceConfig = new EmuDevice(m_dev_type, m_hwnd_window, this);
|
||||
|
||||
// Enumerate devices
|
||||
UpdateDeviceList();
|
||||
|
||||
// Load currently saved profile for this port/device type
|
||||
LoadDefaultProfile();
|
||||
|
||||
// Load currently selected host device
|
||||
UpdateCurrentDevice();
|
||||
|
||||
// Load rumble binding
|
||||
char rumble[30];
|
||||
m_DeviceConfig->FindButtonByIndex(m_max_num_buttons - 1)->GetText(rumble, sizeof(rumble));
|
||||
m_rumble = rumble;
|
||||
|
||||
// Install the subclass for the profile combobox
|
||||
SetWindowSubclass(GetWindow(m_hwnd_profile_list, GW_CHILD), ProfileNameSubclassProc, 0, 0);
|
||||
}
|
||||
|
||||
void DukeInputWindow::InitRumble(HWND hwnd)
|
||||
{
|
||||
m_hwnd_rumble = hwnd;
|
||||
m_hwnd_rumble_list = GetDlgItem(m_hwnd_rumble, IDC_RUMBLE_LIST);
|
||||
SendMessage(m_hwnd_rumble_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(""));
|
||||
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
|
||||
if (dev != nullptr) {
|
||||
auto outputs = dev->GetOutputs();
|
||||
for (const auto out : outputs) {
|
||||
SendMessage(m_hwnd_rumble_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(out->GetName().c_str()));
|
||||
}
|
||||
}
|
||||
SendMessage(m_hwnd_rumble_list, CB_SETCURSEL, SendMessage(m_hwnd_rumble_list, CB_FINDSTRINGEXACT, 1,
|
||||
reinterpret_cast<LPARAM>(m_rumble.c_str())), 0);
|
||||
}
|
||||
|
||||
void DukeInputWindow::UpdateRumble(int command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case RUMBLE_SET: {
|
||||
char rumble[30];
|
||||
SendMessage(m_hwnd_rumble_list, WM_GETTEXT, sizeof(rumble), reinterpret_cast<LPARAM>(rumble));
|
||||
m_rumble = rumble;
|
||||
}
|
||||
break;
|
||||
|
||||
case RUMBLE_UPDATE: {
|
||||
m_DeviceConfig->FindButtonByIndex(m_max_num_buttons - 1)->UpdateText(m_rumble.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case RUMBLE_TEST: {
|
||||
DetectOutput(OUTPUT_TIMEOUT);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DukeInputWindow::BindDefault()
|
||||
{
|
||||
int api = EnableDefaultButton();
|
||||
if (api != -1) {
|
||||
m_DeviceConfig->BindDefault<XBOX_CTRL_NUM_BUTTONS>(button_xbox_ctrl_default[api]);
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
int DukeInputWindow::EnableDefaultButton()
|
||||
{
|
||||
if (std::strncmp(m_host_dev.c_str(), "XInput", std::strlen("XInput")) == 0) {
|
||||
EnableWindow(m_hwnd_default, TRUE);
|
||||
return XINPUT_DEFAULT;
|
||||
}
|
||||
else if (std::strncmp(m_host_dev.c_str(), "DInput", std::strlen("DInput")) == 0) {
|
||||
EnableWindow(m_hwnd_default, TRUE);
|
||||
return DINPUT_DEFAULT;
|
||||
}
|
||||
else {
|
||||
EnableWindow(m_hwnd_default, FALSE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void DukeInputWindow::ClearBindings()
|
||||
{
|
||||
m_DeviceConfig->ClearButtons();
|
||||
m_rumble = std::string();
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
|
||||
void DukeInputWindow::UpdateProfile(const std::string &name, int command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case PROFILE_LOAD: {
|
||||
LoadProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROFILE_SAVE: {
|
||||
SaveProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROFILE_DELETE: {
|
||||
DeleteProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case RUMBLE_CLEAR: {
|
||||
m_rumble = std::string();
|
||||
}
|
||||
break;
|
||||
|
||||
case BUTTON_CLEAR: {
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DukeInputWindow::DetectOutput(int ms)
|
||||
{
|
||||
if (m_rumble == std::string()) {
|
||||
return;
|
||||
}
|
||||
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
|
||||
if (dev != nullptr) {
|
||||
// Don't block the message processing loop
|
||||
std::thread([this, dev, ms]() {
|
||||
EnableWindow(m_hwnd_rumble, FALSE);
|
||||
SendMessage(m_hwnd_rumble_list, WM_SETTEXT, 0, reinterpret_cast<LPARAM>("..."));
|
||||
auto outputs = dev->GetOutputs();
|
||||
for (const auto out : outputs) {
|
||||
if (out->GetName() == m_rumble) {
|
||||
out->SetState(1.0, 1.0);
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||
for (const auto out : outputs) {
|
||||
if (out->GetName() == m_rumble) {
|
||||
out->SetState(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
SendMessage(m_hwnd_rumble_list, WM_SETTEXT, 0, reinterpret_cast<LPARAM>("Test"));
|
||||
EnableWindow(m_hwnd_rumble, TRUE);
|
||||
}).detach();
|
||||
}
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK DlgRumbleConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
INT_PTR CALLBACK DlgXidControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -52,7 +251,7 @@ INT_PTR CALLBACK DlgXidControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPar
|
|||
assert(dev_type == to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE) ||
|
||||
dev_type == to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S));
|
||||
|
||||
g_InputWindow = new InputWindow;
|
||||
g_InputWindow = new DukeInputWindow;
|
||||
g_InputWindow->Initialize(hWndDlg, port_num, dev_type);
|
||||
}
|
||||
break;
|
||||
|
@ -78,10 +277,10 @@ INT_PTR CALLBACK DlgXidControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPar
|
|||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_PROFILE_NAME: {
|
||||
case IDC_PROFILE_NAME: {
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
char name[50];
|
||||
HWND hwnd = GetDlgItem(hWndDlg, IDC_XID_PROFILE_NAME);
|
||||
HWND hwnd = GetDlgItem(hWndDlg, IDC_PROFILE_NAME);
|
||||
LRESULT str_idx = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
|
||||
if (str_idx != CB_ERR) {
|
||||
SendMessage(hwnd, CB_GETLBTEXT, str_idx, reinterpret_cast<LPARAM>(name));
|
||||
|
@ -91,25 +290,25 @@ INT_PTR CALLBACK DlgXidControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPar
|
|||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_PROFILE_SAVE:
|
||||
case IDC_XID_PROFILE_DELETE: {
|
||||
case IDC_PROFILE_SAVE:
|
||||
case IDC_PROFILE_DELETE: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
char name[50];
|
||||
SendMessage(GetDlgItem(hWndDlg, IDC_XID_PROFILE_NAME), WM_GETTEXT,
|
||||
SendMessage(GetDlgItem(hWndDlg, IDC_PROFILE_NAME), WM_GETTEXT,
|
||||
sizeof(name), reinterpret_cast<LPARAM>(name));
|
||||
g_InputWindow->UpdateProfile(std::string(name), (LOWORD(wParam) == IDC_XID_PROFILE_SAVE) ? PROFILE_SAVE : PROFILE_DELETE);
|
||||
g_InputWindow->UpdateProfile(std::string(name), (LOWORD(wParam) == IDC_PROFILE_SAVE) ? PROFILE_SAVE : PROFILE_DELETE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_DEFAULT: {
|
||||
case IDC_DEFAULT: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
g_InputWindow->BindDefault();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_CLEAR: {
|
||||
case IDC_CLEAR: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
if (PopupQuestionEx(hWndDlg, LOG_LEVEL::WARNING, PopupButtons::YesNo, PopupReturn::No, "Are you sure you want to remove all button bindings?") == PopupReturn::Yes) {
|
||||
g_InputWindow->ClearBindings();
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
// * If not, write to the Free Software Foundation, Inc.,
|
||||
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
||||
// *
|
||||
// * (c) 2019 ergo720
|
||||
// * (c) 2021 ergo720
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
|
@ -33,6 +33,87 @@
|
|||
#include "gui\DlgInputConfig.h"
|
||||
#include "common/Logging.h"
|
||||
|
||||
|
||||
static SbcInputWindow *g_InputWindow = nullptr;
|
||||
|
||||
void SbcInputWindow::Initialize(HWND hwnd, int port_num, int dev_type)
|
||||
{
|
||||
// Save window/device specific variables
|
||||
m_hwnd_window = hwnd;
|
||||
m_hwnd_device_list = GetDlgItem(m_hwnd_window, IDC_DEVICE_LIST);
|
||||
m_hwnd_profile_list = GetDlgItem(m_hwnd_window, IDC_PROFILE_NAME);
|
||||
m_dev_type = dev_type;
|
||||
m_max_num_buttons = dev_num_buttons[dev_type];
|
||||
m_port_num = port_num;
|
||||
m_bHasChanges = false;
|
||||
m_bIsBinding = false;
|
||||
|
||||
// Set window icon
|
||||
SetClassLong(m_hwnd_window, GCL_HICON, (LONG)LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_CXBX)));
|
||||
|
||||
// Set window title
|
||||
std::string title("Steel Battalion Controller at port ");
|
||||
SendMessage(m_hwnd_window, WM_SETTEXT, 0,
|
||||
reinterpret_cast<LPARAM>((title + std::to_string(PORT_INC(m_port_num))).c_str()));
|
||||
|
||||
// Set the maximum profile name lenght the user can enter in the profile combobox
|
||||
SendMessage(m_hwnd_profile_list, CB_LIMITTEXT, 49, 0);
|
||||
|
||||
// construct emu device
|
||||
m_DeviceConfig = new EmuDevice(m_dev_type, m_hwnd_window, this);
|
||||
|
||||
// Enumerate devices
|
||||
UpdateDeviceList();
|
||||
|
||||
// Load currently saved profile for this port/device type
|
||||
LoadDefaultProfile();
|
||||
|
||||
// Load currently selected host device
|
||||
UpdateCurrentDevice();
|
||||
|
||||
// Install the subclass for the profile combobox
|
||||
SetWindowSubclass(GetWindow(m_hwnd_profile_list, GW_CHILD), ProfileNameSubclassProc, 0, 0);
|
||||
}
|
||||
|
||||
void SbcInputWindow::ClearBindings()
|
||||
{
|
||||
m_DeviceConfig->ClearButtons();
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
|
||||
void SbcInputWindow::UpdateProfile(const std::string &name, int command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case PROFILE_LOAD: {
|
||||
LoadProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROFILE_SAVE: {
|
||||
SaveProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROFILE_DELETE: {
|
||||
DeleteProfile(name);
|
||||
}
|
||||
break;
|
||||
|
||||
case BUTTON_CLEAR: {
|
||||
m_bHasChanges = true;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int SbcInputWindow::EnableDefaultButton()
|
||||
{
|
||||
// The SBC window does not have a default button, so we return a dummy value here
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DlgSBControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
|
@ -46,9 +127,9 @@ INT_PTR CALLBACK DlgSBControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPara
|
|||
assert(port_num >= PORT_1 && port_num <= PORT_4);
|
||||
|
||||
// Ensure that the controller type is valid
|
||||
dev_type == to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER);
|
||||
assert(dev_type == to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER));
|
||||
|
||||
g_InputWindow = new InputWindow;
|
||||
g_InputWindow = new SbcInputWindow;
|
||||
g_InputWindow->Initialize(hWndDlg, port_num, dev_type);
|
||||
}
|
||||
break;
|
||||
|
@ -74,10 +155,10 @@ INT_PTR CALLBACK DlgSBControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPara
|
|||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_PROFILE_NAME: {
|
||||
case IDC_PROFILE_NAME: {
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
char name[50];
|
||||
HWND hwnd = GetDlgItem(hWndDlg, IDC_XID_PROFILE_NAME);
|
||||
HWND hwnd = GetDlgItem(hWndDlg, IDC_PROFILE_NAME);
|
||||
LRESULT str_idx = SendMessage(hwnd, CB_GETCURSEL, 0, 0);
|
||||
if (str_idx != CB_ERR) {
|
||||
SendMessage(hwnd, CB_GETLBTEXT, str_idx, reinterpret_cast<LPARAM>(name));
|
||||
|
@ -87,25 +168,18 @@ INT_PTR CALLBACK DlgSBControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPara
|
|||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_PROFILE_SAVE:
|
||||
case IDC_XID_PROFILE_DELETE: {
|
||||
case IDC_PROFILE_SAVE:
|
||||
case IDC_PROFILE_DELETE: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
char name[50];
|
||||
SendMessage(GetDlgItem(hWndDlg, IDC_XID_PROFILE_NAME), WM_GETTEXT,
|
||||
SendMessage(GetDlgItem(hWndDlg, IDC_PROFILE_NAME), WM_GETTEXT,
|
||||
sizeof(name), reinterpret_cast<LPARAM>(name));
|
||||
g_InputWindow->UpdateProfile(std::string(name), (LOWORD(wParam) == IDC_XID_PROFILE_SAVE) ? PROFILE_SAVE : PROFILE_DELETE);
|
||||
g_InputWindow->UpdateProfile(std::string(name), (LOWORD(wParam) == IDC_PROFILE_SAVE) ? PROFILE_SAVE : PROFILE_DELETE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_DEFAULT: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
g_InputWindow->BindDefault();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_XID_CLEAR: {
|
||||
case IDC_CLEAR: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
if (PopupQuestionEx(hWndDlg, LOG_LEVEL::WARNING, PopupButtons::YesNo, PopupReturn::No, "Are you sure you want to remove all button bindings?") == PopupReturn::Yes) {
|
||||
g_InputWindow->ClearBindings();
|
||||
|
@ -121,81 +195,9 @@ INT_PTR CALLBACK DlgSBControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPara
|
|||
}
|
||||
break;
|
||||
|
||||
case IDC_SET_X:
|
||||
case IDC_SET_Y:
|
||||
case IDC_SET_A:
|
||||
case IDC_SET_B:
|
||||
case IDC_SET_WHITE:
|
||||
case IDC_SET_BLACK:
|
||||
case IDC_SET_LTRIGGER:
|
||||
case IDC_SET_RTRIGGER:
|
||||
case IDC_SET_LTHUMB:
|
||||
case IDC_SET_RTHUMB:
|
||||
case IDC_SET_START:
|
||||
case IDC_SET_BACK:
|
||||
case IDC_SET_DPAD_LEFT:
|
||||
case IDC_SET_DPAD_RIGHT:
|
||||
case IDC_SET_DPAD_UP:
|
||||
case IDC_SET_DPAD_DOWN:
|
||||
case IDC_SET_LEFT_POSY:
|
||||
case IDC_SET_LEFT_NEGX:
|
||||
case IDC_SET_LEFT_NEGY:
|
||||
case IDC_SET_LEFT_POSX:
|
||||
case IDC_SET_RIGHT_POSY:
|
||||
case IDC_SET_RIGHT_NEGY:
|
||||
case IDC_SET_RIGHT_NEGX:
|
||||
case IDC_SET_RIGHT_POSX:
|
||||
case IDC_GEAR_0:
|
||||
case IDC_GEAR_1:
|
||||
case IDC_GEAR_2:
|
||||
case IDC_GEAR_3:
|
||||
case IDC_GEAR_4:
|
||||
case IDC_GEAR_5:
|
||||
case IDC_GEAR_R:
|
||||
case IDC_SIGHT_CHANGE_NEGY:
|
||||
case IDC_OXYGEN_SUPPLY_SYSTEM:
|
||||
case IDC_FILT_CONTROL_SYSTEM:
|
||||
case IDC_FUEL_FLOW_RATE:
|
||||
case IDC_BUFFER_MATERIAL:
|
||||
case IDC_VT_LOCATION_MEASUREMENT:
|
||||
case IDC_ROTATION_LEVER:
|
||||
case IDC_BTN_SIGHT_CHANGE:
|
||||
case IDC_BTN_COM1:
|
||||
case IDC_BTN_COM2:
|
||||
case IDC_BTN_COM3:
|
||||
case IDC_BTN_COM4:
|
||||
case IDC_BTN_COM5:
|
||||
case IDC_BTN_MAIN_WEAPON_CONTROL:
|
||||
case IDC_BTN_SUB_WEAPON_CONTROL:
|
||||
case IDC_BTN_MAGAZINE_CHANGE:
|
||||
case IDC_BTN_WASHING:
|
||||
case IDC_BTN_EXTINGUISHER:
|
||||
case IDC_BTN_CHAFF:
|
||||
case IDC_BTN_FUNC3:
|
||||
case IDC_BTN_FUNC2:
|
||||
case IDC_BTN_FUNC1:
|
||||
case IDC_BTN_NIGHT_SCOPE:
|
||||
case IDC_BTN_LINE_COLOR_CHANGE:
|
||||
case IDC_BTN_OVERRIDE:
|
||||
case IDC_BTN_MANIPULATOR:
|
||||
case IDC_BTN_TANK_DETACH:
|
||||
case IDC_BTN_FSS:
|
||||
case IDC_RADIO_TD0:
|
||||
case IDC_RADIO_TD1:
|
||||
case IDC_RADIO_TD2:
|
||||
case IDC_RADIO_TD3:
|
||||
case IDC_RADIO_TD4:
|
||||
case IDC_RADIO_TD5:
|
||||
case IDC_RADIO_TD6:
|
||||
case IDC_RADIO_TD7:
|
||||
case IDC_RADIO_TD8:
|
||||
case IDC_RADIO_TD9:
|
||||
case IDC_RADIO_TD10:
|
||||
case IDC_RADIO_TD11:
|
||||
case IDC_RADIO_TD12:
|
||||
case IDC_BTN_LOCK_ON:
|
||||
case IDC_BTN_SUB_WEAPON:
|
||||
case IDC_BTN_MAIN_WEAPON:
|
||||
case IDC_BTN_SUB_WEAPON:
|
||||
case IDC_BTN_LOCK_ON:
|
||||
case IDC_BTN_EJECT:
|
||||
case IDC_BTN_COCKPIT_HATCH:
|
||||
case IDC_BTN_IGNITION:
|
||||
|
@ -206,9 +208,49 @@ INT_PTR CALLBACK DlgSBControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPara
|
|||
case IDC_BTN_SUB_MONITOR_MODE_SELECT:
|
||||
case IDC_BTN_ZOOM_IN:
|
||||
case IDC_BTN_ZOOM_OUT:
|
||||
case IDC_BTN_FSS:
|
||||
case IDC_BTN_MANIPULATOR:
|
||||
case IDC_BTN_LINE_COLOR_CHANGE:
|
||||
case IDC_BTN_WASHING:
|
||||
case IDC_BTN_EXTINGUISHER:
|
||||
case IDC_BTN_CHAFF:
|
||||
case IDC_BTN_TANK_DETACH:
|
||||
case IDC_BTN_OVERRIDE:
|
||||
case IDC_BTN_NIGHT_SCOPE:
|
||||
case IDC_BTN_FUNC1:
|
||||
case IDC_BTN_FUNC2:
|
||||
case IDC_BTN_FUNC3:
|
||||
case IDC_BTN_MAIN_WEAPON_CONTROL:
|
||||
case IDC_BTN_SUB_WEAPON_CONTROL:
|
||||
case IDC_BTN_MAGAZINE_CHANGE:
|
||||
case IDC_BTN_COM1:
|
||||
case IDC_BTN_COM2:
|
||||
case IDC_BTN_COM3:
|
||||
case IDC_BTN_COM4:
|
||||
case IDC_BTN_COM5:
|
||||
case IDC_BTN_SIGHT_CHANGE:
|
||||
case IDC_FILT_CONTROL_SYSTEM:
|
||||
case IDC_OXYGEN_SUPPLY_SYSTEM:
|
||||
case IDC_FUEL_FLOW_RATE:
|
||||
case IDC_BUFFER_MATERIAL:
|
||||
case IDC_VT_LOCATION_MEASUREMENT:
|
||||
case IDC_AIMING_POSX:
|
||||
case IDC_AIMING_NEGX:
|
||||
case IDC_AIMING_POSY:
|
||||
case IDC_AIMING_NEGY:
|
||||
case IDC_LEVER_LEFT:
|
||||
case IDC_LEVER_RIGHT:
|
||||
case IDC_SIGHT_CHANGE_POSX:
|
||||
case IDC_SIGHT_CHANGE_NEGX:
|
||||
case IDC_SIGHT_CHANGE_POSY:
|
||||
case IDC_SIGHT_CHANGE_NEGY:
|
||||
case IDC_BTN_LEFT_PEDAL:
|
||||
case IDC_BTN_MIDDLE_PEDAL:
|
||||
case IDC_BTN_RIGHT_PEDAL: {
|
||||
case IDC_BTN_RIGHT_PEDAL:
|
||||
case IDC_RADIO_TD_UP:
|
||||
case IDC_RADIO_TD_DOWN:
|
||||
case IDC_GEAR_UP:
|
||||
case IDC_GEAR_DOWN: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
g_InputWindow->BindButton(LOWORD(wParam));
|
||||
}
|
||||
|
|
|
@ -31,12 +31,9 @@ BEGIN
|
|||
BEGIN
|
||||
END
|
||||
|
||||
IDD_VIRTUAL_SBC_FEEDBACK, DIALOG
|
||||
IDD_SBC_CFG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 1032
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 207
|
||||
BOTTOMMARGIN, 269
|
||||
END
|
||||
|
||||
IDD_VIDEO_CFG, DIALOG
|
||||
|
@ -92,7 +89,7 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMEN
|
|||
CAPTION "Cxbx-Reloaded : Input Configuration"
|
||||
FONT 8, "Verdana", 0, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Xbox device configuration",IDC_XID_CONFIG,13,10,217,103,WS_GROUP,WS_EX_CLIENTEDGE
|
||||
GROUPBOX "Xbox device configuration",IDC_DEVICE,13,10,217,103,WS_GROUP,WS_EX_CLIENTEDGE
|
||||
COMBOBOX IDC_DEVICE_PORT1,50,25,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_DEVICE_PORT2,50,46,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_DEVICE_PORT3,50,67,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
@ -116,14 +113,14 @@ IDD_XID_DUKE_CFG DIALOGEX 0, 0, 528, 280
|
|||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "Verdana", 0, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Device",IDC_XID_CONFIG,12,10,175,35,WS_GROUP
|
||||
GROUPBOX "Device",IDC_DEVICE,12,10,175,35,WS_GROUP
|
||||
COMBOBOX IDC_DEVICE_LIST,21,23,101,15,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Refresh",IDC_REFRESH_DEVICES,128,23,50,14,BS_FLAT
|
||||
GROUPBOX "Profile",IDC_XID_PROFILE,197,10,320,35,WS_GROUP
|
||||
COMBOBOX IDC_XID_PROFILE_NAME,207,24,194,10,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Save",IDC_XID_PROFILE_SAVE,405,23,50,14,BS_FLAT
|
||||
PUSHBUTTON "Delete",IDC_XID_PROFILE_DELETE,459,23,50,14,BS_FLAT
|
||||
GROUPBOX "Buttons",IDC_XID_BUTTONS,12,65,121,181,WS_GROUP
|
||||
GROUPBOX "Profile",IDC_PROFILE,197,10,320,35,WS_GROUP
|
||||
COMBOBOX IDC_PROFILE_NAME,207,24,194,10,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Save",IDC_PROFILE_SAVE,405,23,50,14,BS_FLAT
|
||||
PUSHBUTTON "Delete",IDC_PROFILE_DELETE,459,23,50,14,BS_FLAT
|
||||
GROUPBOX "Buttons",IDC_BUTTONS,12,65,121,181,WS_GROUP
|
||||
PUSHBUTTON "",IDC_SET_A,59,75,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_B,59,93,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_X,59,111,57,14,BS_FLAT
|
||||
|
@ -140,7 +137,7 @@ BEGIN
|
|||
LTEXT "White",IDC_STATIC,28,165,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Back",IDC_STATIC,28,183,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Start",IDC_STATIC,28,201,20,14,SS_CENTERIMAGE
|
||||
GROUPBOX "L Stick",IDC_XID_LSTICK,140,65,121,181,WS_GROUP
|
||||
GROUPBOX "L Stick",IDC_LSTICK,140,65,121,181,WS_GROUP
|
||||
PUSHBUTTON "",IDC_SET_LEFT_POSY,187,75,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_LEFT_NEGY,187,93,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_LEFT_NEGX,187,111,57,14,BS_FLAT
|
||||
|
@ -150,8 +147,8 @@ BEGIN
|
|||
LTEXT "Down",IDC_STATIC,156,93,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Left",IDC_STATIC,156,111,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Right",IDC_STATIC,156,129,20,14,SS_CENTERIMAGE
|
||||
LTEXT "L Click",IDC_STATIC,156,147,27,14,SS_CENTERIMAGE
|
||||
GROUPBOX "R Stick",IDC_XID_RSTICK,268,65,121,181,WS_GROUP
|
||||
LTEXT "Click",IDC_STATIC,156,147,27,14,SS_CENTERIMAGE
|
||||
GROUPBOX "R Stick",IDC_RSTICK,268,65,121,181,WS_GROUP
|
||||
PUSHBUTTON "",IDC_SET_RIGHT_POSY,315,75,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_RIGHT_NEGY,315,93,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_RIGHT_NEGX,315,111,57,14,BS_FLAT
|
||||
|
@ -161,8 +158,8 @@ BEGIN
|
|||
LTEXT "Down",IDC_STATIC,284,93,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Left",IDC_STATIC,284,111,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Right",IDC_STATIC,284,129,20,14,SS_CENTERIMAGE
|
||||
LTEXT "R Click",IDC_STATIC,284,147,27,14,SS_CENTERIMAGE
|
||||
GROUPBOX "D Pad",IDC_XID_DPAD,396,65,121,88,WS_GROUP
|
||||
LTEXT "Click",IDC_STATIC,284,147,27,14,SS_CENTERIMAGE
|
||||
GROUPBOX "D Pad",IDC_DPAD,396,65,121,88,WS_GROUP
|
||||
PUSHBUTTON "",IDC_SET_DPAD_UP,443,75,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_DPAD_DOWN,443,93,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_DPAD_LEFT,443,111,57,14,BS_FLAT
|
||||
|
@ -171,16 +168,16 @@ BEGIN
|
|||
LTEXT "Down",IDC_STATIC,412,93,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Left",IDC_STATIC,412,111,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Right",IDC_STATIC,412,129,20,14,SS_CENTERIMAGE
|
||||
GROUPBOX "Triggers",IDC_XID_TRIGGERS,396,157,121,52,WS_GROUP
|
||||
GROUPBOX "Triggers",IDC_TRIGGERS,396,157,121,52,WS_GROUP
|
||||
PUSHBUTTON "",IDC_SET_LTRIGGER,443,168,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_SET_RTRIGGER,443,187,57,14,BS_FLAT
|
||||
LTEXT "Left",IDC_STATIC,412,168,20,14,SS_CENTERIMAGE
|
||||
LTEXT "Right",IDC_STATIC,412,187,20,14,SS_CENTERIMAGE
|
||||
GROUPBOX "Rumble",IDC_XID_RUMBLE,396,212,121,34,WS_GROUP
|
||||
GROUPBOX "Rumble",IDC_RUMBLE,396,212,121,34,WS_GROUP
|
||||
PUSHBUTTON "",IDC_SET_MOTOR,443,224,57,14,BS_FLAT
|
||||
LTEXT "Motor",IDC_STATIC,412,224,26,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "Default Bindings",IDC_XID_DEFAULT,362,256,69,14,BS_FLAT
|
||||
PUSHBUTTON "Clear",IDC_XID_CLEAR,443,256,50,14,BS_FLAT
|
||||
PUSHBUTTON "Default Bindings",IDC_DEFAULT,362,256,69,14,BS_FLAT
|
||||
PUSHBUTTON "Clear",IDC_CLEAR,443,256,50,14,BS_FLAT
|
||||
END
|
||||
|
||||
IDD_RUMBLE_CFG DIALOGEX 0, 0, 155, 35
|
||||
|
@ -192,111 +189,134 @@ BEGIN
|
|||
PUSHBUTTON "Test",IDC_RUMBLE_TEST,95,11,45,14,BS_FLAT
|
||||
END
|
||||
|
||||
IDD_VIRTUAL_SBC_FEEDBACK DIALOGEX 0, 0, 1039, 280
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Virtual SteelBattalion Controller"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
IDD_SBC_CFG DIALOGEX 0, 0, 854, 280
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "Verdana", 0, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Device", IDC_XID_CONFIG, 12, 10, 175, 35, WS_GROUP
|
||||
COMBOBOX IDC_DEVICE_LIST, 21, 23, 101, 15, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Refresh", IDC_REFRESH_DEVICES, 128, 23, 50, 14, BS_FLAT
|
||||
GROUPBOX "Profile", IDC_XID_PROFILE, 703, 10, 320, 35, WS_GROUP
|
||||
COMBOBOX IDC_XID_PROFILE_NAME, 713, 24, 194, 10, CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP //Move forward 506
|
||||
PUSHBUTTON "Save", IDC_XID_PROFILE_SAVE, 911, 23, 50, 14, BS_FLAT
|
||||
PUSHBUTTON "Delete", IDC_XID_PROFILE_DELETE, 965, 23, 50, 14, BS_FLAT
|
||||
PUSHBUTTON "Clear", IDC_XID_CLEAR, 192, 23, 50, 14, BS_FLAT
|
||||
GROUPBOX "Left Block",IDC_LEFTBLOCK,12,50,292,203,0,WS_EX_RIGHT //Subtract 8x from all Left Block items
|
||||
//GROUPBOX "Left Block",IDC_LEFTBLOCK2,7,50,329,200,0,WS_EX_RIGHT
|
||||
GROUPBOX "Communication Buttons",IDC_LEFTBLOCK2,314,55,315,28,0,WS_EX_RIGHT
|
||||
GROUPBOX "", IDC_LEFTBLOCK2, 309, 50, 329, 203, 0, WS_EX_RIGHT
|
||||
GROUPBOX "Center Block", IDC_LEFTBLOCK2, 439, 178, 200, 75, 0, WS_EX_RIGHT //309
|
||||
GROUPBOX "Right Block",IDC_RIGHTBLOCK,689,50,329,203,0,WS_EX_LEFT
|
||||
GROUPBOX "Gear Lever",IDC_GEAR_LEVER,16,65,87,145,WS_GROUP,WS_EX_LEFT
|
||||
GROUPBOX "Toggle Switches",IDC_STATIC,113,148,185,100,0,WS_EX_LEFT
|
||||
PUSHBUTTON "", IDC_GEAR_5, 35, 79, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "5", IDC_STATIC, 25, 79, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_GEAR_4, 35, 97, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "4", IDC_STATIC, 25, 97, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_GEAR_3, 35, 115, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "3", IDC_STATIC, 25, 115, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_GEAR_2, 35, 133, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "2", IDC_STATIC, 25, 133, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_GEAR_1, 35, 152, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "1", IDC_STATIC, 25, 152, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_GEAR_0, 35, 169, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "N", IDC_STATIC, 25, 169, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_GEAR_R, 35, 187, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "R", IDC_STATIC, 25, 187, 5, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_VT_LOCATION_MEASUREMENT, 142, 161, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "VT-Location Measurement", IDC_STATIC, 204, 161, 90, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BUFFER_MATERIAL, 142, 178, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Buffer Material", IDC_STATIC, 204, 178, 80, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_FUEL_FLOW_RATE, 142, 195, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Fuel Flow Rate", IDC_STATIC, 204, 195, 80, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_OXYGEN_SUPPLY_SYSTEM, 120, 212, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Oxygen Supply System", IDC_STATIC, 182, 212, 80, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_FILT_CONTROL_SYSTEM, 120, 229, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Filt Control System", IDC_STATIC, 182, 229, 80, 14, SS_CENTERIMAGE
|
||||
LTEXT "Sight Change", IDC_STATIC, 139, 55, 80, 11, SS_CENTERIMAGE
|
||||
LTEXT "Rotation Lever", IDC_STATIC, 242, 88, 50, 11, SS_CENTERIMAGE
|
||||
LTEXT "Left", IDC_STATIC, 217, 99, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_ROTATION_LEVER, 237, 99, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Right", IDC_STATIC, 215, 115, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_ROTATION_LEVER, 238, 115, 57, 14, BS_FLAT //I don't think IDC_ROTATION_LEVER should be duplicated? Is it only one axis?
|
||||
LTEXT "Up", IDC_STATIC, 113, 67, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_SET_LEFT_POSY, 132, 67, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "Down", IDC_STATIC, 109, 83, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_SET_LEFT_NEGY, 132, 83, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "Left", IDC_STATIC, 111, 99, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_SET_LEFT_NEGX, 132, 99, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "Right", IDC_STATIC, 109, 115, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_SET_LEFT_POSX, 132, 115, 57, 14, BS_FLAT //Debug exception?
|
||||
LTEXT "Center", IDC_STATIC, 108, 131, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_SIGHT_CHANGE, 132, 131, 57, 14, BS_FLAT //Doesn't save
|
||||
PUSHBUTTON "", IDC_BTN_COM1, 319, 63, 57, 14, BS_FLAT //Doesn't save
|
||||
PUSHBUTTON "", IDC_BTN_COM2, 380, 63, 57, 14, BS_FLAT //Doesn't save
|
||||
PUSHBUTTON "", IDC_BTN_COM3, 441, 63, 57, 14, BS_FLAT //Doesn't save
|
||||
PUSHBUTTON "", IDC_BTN_COM4, 502, 63, 57, 14, BS_FLAT //Doesn't save
|
||||
PUSHBUTTON "", IDC_BTN_COM5, 563, 63, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Main Weapon", IDC_STATIC, 459, 223, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_MAIN_WEAPON_CONTROL, 451, 235, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Sub Weapon", IDC_STATIC, 519, 223, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_SUB_WEAPON_CONTROL, 512, 235, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Magazine Change", IDC_STATIC, 573, 223, 60, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_MAGAZINE_CHANGE, 573, 235, 57, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Washing", IDC_STATIC, 465, 188, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_WASHING, 451, 200, 57, 14, BS_FLAT
|
||||
LTEXT "Extinguisher", IDC_STATIC, 520, 188, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_EXTINGUISHER, 512, 200, 57, 14, BS_FLAT
|
||||
LTEXT "Chaff", IDC_STATIC, 593, 188, 40, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_CHAFF, 573, 200, 57, 14, BS_FLAT
|
||||
LTEXT "F3", IDC_STATIC, 475, 143, 65, 14, SS_CENTERIMAGE //-5y
|
||||
PUSHBUTTON "", IDC_BTN_FUNC3, 451, 155, 57, 14, BS_FLAT //Crashes
|
||||
LTEXT "Night Scope", IDC_STATIC, 520, 143, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_NIGHT_SCOPE, 512, 155, 57, 14, BS_FLAT
|
||||
LTEXT "Line Color Change", IDC_STATIC, 573, 143, 60, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_LINE_COLOR_CHANGE, 573, 155, 57, 14, BS_FLAT
|
||||
LTEXT "F2", IDC_STATIC, 475, 113, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_FUNC2, 451, 125, 57, 14, BS_FLAT
|
||||
LTEXT "Override", IDC_STATIC, 525, 112, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_OVERRIDE, 512, 125, 57, 14, BS_FLAT
|
||||
LTEXT "Manipulator", IDC_STATIC, 583, 113, 40, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_MANIPULATOR, 573, 125, 57, 14, BS_FLAT
|
||||
LTEXT "F1", IDC_STATIC, 475, 83, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_FUNC1, 451, 95, 57, 14, BS_FLAT
|
||||
LTEXT "Tank Detach", IDC_STATIC, 524, 83, 65, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_TANK_DETACH, 512, 95, 57, 14, BS_FLAT
|
||||
LTEXT "F.S.S", IDC_STATIC, 583, 83, 40, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_FSS, 573, 95, 57, 14, BS_FLAT
|
||||
LTEXT "Slide-step Pedal", IDC_STATIC, 320, 11, 60, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_LEFT_PEDAL, 320, 23, 50, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Brake Pedal", IDC_STATIC, 425, 11, 40, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_MIDDLE_PEDAL, 420, 23, 50, 14, BS_FLAT //Doesn't save
|
||||
LTEXT "Gas Pedal", IDC_STATIC, 529, 11, 40, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_RIGHT_PEDAL, 520, 23, 50, 14, BS_FLAT //Doesn't save
|
||||
|
||||
LTEXT "Main Weapon", IDC_STATIC, 840, 80, 60, 14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "", IDC_BTN_MAIN_WEAPON, 840, 60, 57, 14, BS_FLAT
|
||||
GROUPBOX "Device",IDC_DEVICE,12,10,175,35,WS_GROUP
|
||||
COMBOBOX IDC_DEVICE_LIST,21,23,101,15,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Refresh",IDC_REFRESH_DEVICES,128,23,50,14,BS_FLAT
|
||||
GROUPBOX "Profile",IDC_PROFILE,196,10,320,35,WS_GROUP
|
||||
COMBOBOX IDC_PROFILE_NAME,206,23,194,10,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Save",IDC_PROFILE_SAVE,404,23,50,14,BS_FLAT
|
||||
PUSHBUTTON "Delete",IDC_PROFILE_DELETE,458,23,50,14,BS_FLAT
|
||||
PUSHBUTTON "Clear",IDC_CLEAR,774,23,50,14,BS_FLAT
|
||||
GROUPBOX "Left Block",IDC_LEFTBLOCK,12,50,281,167
|
||||
GROUPBOX "Center Block",IDC_CENTERBLOCK,299,50,281,218
|
||||
GROUPBOX "Right Block",IDC_RIGHTBLOCK,586,50,255,218
|
||||
PUSHBUTTON "",IDC_GEAR_UP,67,64,57,14,BS_FLAT
|
||||
LTEXT "Gear Up",IDC_STATIC,25,64,38,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_GEAR_DOWN,67,82,57,14,BS_FLAT
|
||||
LTEXT "Gear Down",IDC_STATIC,25,82,38,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_VT_LOCATION_MEASUREMENT,223,64,57,14,BS_FLAT
|
||||
LTEXT "VT-Location Measurement",IDC_STATIC,133,64,90,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BUFFER_MATERIAL,223,82,57,14,BS_FLAT
|
||||
LTEXT "Buffer Material",IDC_STATIC,133,82,80,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_FUEL_FLOW_RATE,223,100,57,14,BS_FLAT
|
||||
LTEXT "Fuel Flow Rate",IDC_STATIC,133,100,80,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_OXYGEN_SUPPLY_SYSTEM,223,118,57,14,BS_FLAT
|
||||
LTEXT "Oxygen Supply System",IDC_STATIC,133,118,80,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_FILT_CONTROL_SYSTEM,223,136,57,14,BS_FLAT
|
||||
LTEXT "Filt Control System",IDC_STATIC,133,136,80,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_SIGHT_CHANGE,223,154,57,14, BS_FLAT
|
||||
LTEXT "Sight Change",IDC_STATIC,133,154,80,14, SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_LEVER_LEFT,67,172,57,14,BS_FLAT
|
||||
LTEXT "Lever Left",IDC_STATIC,25,172,42,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_LEVER_RIGHT,67,191,57,14,BS_FLAT
|
||||
LTEXT "Lever Right",IDC_STATIC,25,191,42,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_SIGHT_CHANGE_POSY,67,100,57,14,BS_FLAT
|
||||
LTEXT "Sight Up",IDC_STATIC,25,100,37,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_SIGHT_CHANGE_NEGY,67,118,57,14,BS_FLAT
|
||||
LTEXT "Sight Down",IDC_STATIC,25,118,40,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_SIGHT_CHANGE_NEGX,67,136,57,14,BS_FLAT
|
||||
LTEXT "Sight Left",IDC_STATIC,25,136,38,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_SIGHT_CHANGE_POSX,67,154,57,14,BS_FLAT
|
||||
LTEXT "Sight Right",IDC_STATIC,25,154,39,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_COM1,375,64,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_COM2,375,82,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_COM3,375,100,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_COM4,375,118,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_COM5,375,136,57,14,BS_FLAT
|
||||
LTEXT "Extinguisher",IDC_STATIC,444,136,65,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_MAIN_WEAPON_CONTROL,511,172,57,14,BS_FLAT
|
||||
LTEXT "Main Weapon",IDC_STATIC,444,172,65,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_SUB_WEAPON_CONTROL,511,190,57,14,BS_FLAT
|
||||
LTEXT "Magazine Change",IDC_STATIC,444,208,60,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_MAGAZINE_CHANGE,511,208,57,14,BS_FLAT
|
||||
LTEXT "Washing",IDC_STATIC,444,118,65,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_WASHING,511,118,57,14,BS_FLAT
|
||||
LTEXT "Chaff",IDC_STATIC,444,154,65,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_EXTINGUISHER,511,136,57,14,BS_FLAT
|
||||
LTEXT "Sub Weapon",IDC_STATIC,444,190,40,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_CHAFF,511,154,57,14,BS_FLAT
|
||||
LTEXT "Function 3",IDC_STATIC,311,191,44,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_FUNC3,375,190,57,14,BS_FLAT
|
||||
LTEXT "Night Scope",IDC_STATIC,311,244,51,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_NIGHT_SCOPE,375,244,57,14,BS_FLAT
|
||||
LTEXT "Line Color Change",IDC_STATIC,444,100,60,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_LINE_COLOR_CHANGE,511,100,57,14,BS_FLAT
|
||||
LTEXT "Function 2",IDC_STATIC,311,172,46,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_FUNC2,375,172,57,14,BS_FLAT
|
||||
LTEXT "Override",IDC_STATIC,311,226,47,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_OVERRIDE,375,226,57,14,BS_FLAT
|
||||
LTEXT "Manipulator",IDC_STATIC,444,82,40,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_MANIPULATOR,511,82,57,14,BS_FLAT
|
||||
LTEXT "Function 1",IDC_STATIC,311,154,37,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_FUNC1,375,154,57,14,BS_FLAT
|
||||
LTEXT "Tank Detach",IDC_STATIC,311,208,52,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_TANK_DETACH,375,208,57,14,BS_FLAT
|
||||
LTEXT "F.S.S",IDC_STATIC,444,64,40,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_BTN_FSS,511,64,57,14,BS_FLAT
|
||||
LTEXT "Slide-step",IDC_STATIC,17,239,40,14,SS_CENTERIMAGE
|
||||
LTEXT "Brake",IDC_STATIC,120,239,26,14,SS_CENTERIMAGE
|
||||
LTEXT "Accel",IDC_STATIC,209,239,23,14,SS_CENTERIMAGE
|
||||
LTEXT "Communication 1",IDC_STATIC,311,64,64,14,SS_CENTERIMAGE
|
||||
LTEXT "Communication 2",IDC_STATIC,311,82,64,14,SS_CENTERIMAGE
|
||||
LTEXT "Communication 3",IDC_STATIC,311,100,64,14,SS_CENTERIMAGE
|
||||
LTEXT "Communication 4",IDC_STATIC,311,118,64,14,SS_CENTERIMAGE
|
||||
LTEXT "Communication 5",IDC_STATIC,311,136,64,14,SS_CENTERIMAGE
|
||||
GROUPBOX "Pedals",IDC_BLOCK_PEDALS,12,220,281,48
|
||||
PUSHBUTTON "",IDC_BTN_LEFT_PEDAL,55,239,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_MIDDLE_PEDAL,144,239,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_RIGHT_PEDAL,230,239,57,14,BS_FLAT
|
||||
LTEXT "Tuner Up",IDC_STATIC,444,226,60,14,SS_CENTERIMAGE
|
||||
LTEXT "Tuner Down",IDC_STATIC,444,244,60,14,SS_CENTERIMAGE
|
||||
PUSHBUTTON "",IDC_RADIO_TD_UP,511,226,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_RADIO_TD_DOWN,511,244,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_AIMING_POSY,650,64,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_AIMING_NEGY,650,82,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_AIMING_NEGX,650,100,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_AIMING_POSX,650,118,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_MAIN_WEAPON,650,136,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_SUB_WEAPON,650,154,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_LOCK_ON,650,172,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_OPEN_CLOSE,650,190,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_MODE_SELECT,650,208,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_ZOOM_IN,650,226,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_MAP_ZOOM_IN_OUT,650,244,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_START,771,154,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_IGNITION,771,136,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_COCKPIT_HATCH,771,118,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_EJECT,771,100,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_ZOOM_OUT,771,82,57,14,BS_FLAT
|
||||
PUSHBUTTON "",IDC_BTN_SUB_MONITOR_MODE_SELECT,771,64,57,14,BS_FLAT
|
||||
LTEXT "Aim Up",IDC_STATIC,599,64,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Aim Down",IDC_STATIC,599,82,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Aim Left",IDC_STATIC,599,100,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Aim Right",IDC_STATIC,599,118,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Main Weapon",IDC_STATIC,599,136,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Sub Weapon",IDC_STATIC,599,154,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Lock On",IDC_STATIC,599,172,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Open Close",IDC_STATIC,599,190,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Mode Select",IDC_STATIC,599,208,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Zoom In",IDC_STATIC,599,226,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Map Zoom",IDC_STATIC,599,244,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Start",IDC_STATIC,720,154,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Ignition",IDC_STATIC,720,136,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Cockpit Hatch",IDC_STATIC,720,118,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Eject",IDC_STATIC,720,100,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Zoom Out",IDC_STATIC,720,82,51,14,SS_CENTERIMAGE
|
||||
LTEXT "Sub Monitor",IDC_STATIC,720,64,51,14,SS_CENTERIMAGE
|
||||
END
|
||||
|
||||
IDD_VIDEO_CFG DIALOGEX 0, 0, 259, 150
|
||||
|
@ -535,6 +555,11 @@ BEGIN
|
|||
0
|
||||
END
|
||||
|
||||
IDD_SBC_CFG AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#define IDD_ABOUT 119
|
||||
#define IDR_CONTRIBUTORS 121
|
||||
#define IDR_COPYING 122
|
||||
#define IDD_VIRTUAL_SBC_FEEDBACK 133
|
||||
#define IDD_SBC_CFG 133
|
||||
#define IDD_XID_DUKE_CFG 134
|
||||
#define IDD_RUMBLE_CFG 135
|
||||
#define IDD_NETWORK_CFG 136
|
||||
|
@ -199,41 +199,25 @@
|
|||
#define IDC_XBOX_PORT_1 1166
|
||||
#define IDC_XBOX_PORT_2 1174
|
||||
#define IDC_XBOX_PORT_3 1182
|
||||
#define IDC_LEFTBLOCK 1200
|
||||
#define IDC_LEFTBLOCK2 1201
|
||||
#define IDC_CENTERBLOCK 1200
|
||||
#define IDC_LEFTBLOCK 1201
|
||||
#define IDC_RIGHTBLOCK 1202
|
||||
#define IDC_GEAR_LEVER 1203
|
||||
#define IDC_GEAR_0 1204
|
||||
#define IDC_GEAR_1 1205
|
||||
#define IDC_GEAR_2 1206
|
||||
#define IDC_GEAR_3 1207
|
||||
#define IDC_GEAR_4 1208
|
||||
#define IDC_GEAR_5 1209
|
||||
#define IDC_GEAR_R 1210
|
||||
#define IDC_ROTATION_LEVER 1211
|
||||
#define IDC_TXT_ROTATION_LEVER 1212
|
||||
#define IDC_GEAR_UP 1203
|
||||
#define IDC_GEAR_DOWN 1204
|
||||
#define IDC_BLOCK_PEDALS 1205
|
||||
#define IDC_LEVER_LEFT 1211
|
||||
#define IDC_LEVER_RIGHT 1212
|
||||
#define IDC_VT_LOCATION_MEASUREMENT 1213
|
||||
#define IDC_BUFFER_MATERIAL 1214
|
||||
#define IDC_FUEL_FLOW_RATE 1215
|
||||
#define IDC_OXYGEN_SUPPLY_SYSTEM 1216
|
||||
#define IDC_FILT_CONTROL_SYSTEM 1217
|
||||
#define IDC_RADIO_TD0 1255
|
||||
#define IDC_RADIO_TD1 1256
|
||||
#define IDC_RADIO_TD2 1257
|
||||
#define IDC_RADIO_TD3 1258
|
||||
#define IDC_RADIO_TD4 1259
|
||||
#define IDC_RADIO_TD5 1260
|
||||
#define IDC_RADIO_TD6 1261
|
||||
#define IDC_RADIO_TD7 1262
|
||||
#define IDC_RADIO_TD8 1263
|
||||
#define IDC_RADIO_TD9 1264
|
||||
#define IDC_RADIO_TD10 1265
|
||||
#define IDC_RADIO_TD11 1266
|
||||
#define IDC_RADIO_TD12 1267
|
||||
#define IDC_RADIO_TD_UP 1255
|
||||
#define IDC_RADIO_TD_DOWN 1256
|
||||
#define IDC_EVENT_LV 1273
|
||||
#define IDC_CXBXR_EVENTS 1274
|
||||
#define IDC_KERNEL_EVENTS 1275
|
||||
#define IDC_XID_CONFIG 1276
|
||||
#define IDC_DEVICE 1276
|
||||
#define IDC_DEVICE_PORT1 1277
|
||||
#define IDC_DEVICE_PORT2 1278
|
||||
#define IDC_DEVICE_PORT3 1279
|
||||
|
@ -244,19 +228,19 @@
|
|||
#define IDC_CONFIGURE_PORT4 1284
|
||||
#define IDC_DEVICE_LIST 1285
|
||||
#define IDC_REFRESH_DEVICES 1286
|
||||
#define IDC_XID_DEFAULT 1287
|
||||
#define IDC_XID_PROFILE 1288
|
||||
#define IDC_XID_PROFILE_NAME 1289
|
||||
#define IDC_XID_PROFILE_SAVE 1291
|
||||
#define IDC_XID_PROFILE_DELETE 1292
|
||||
#define IDC_XID_BUTTONS 1293
|
||||
#define IDC_XID_LSTICK 1294
|
||||
#define IDC_XID_RSTICK 1295
|
||||
#define IDC_XID_DPAD 1296
|
||||
#define IDC_XID_TRIGGERS 1297
|
||||
#define IDC_XID_RUMBLE 1298
|
||||
#define IDC_XID_OPTIONS 1299
|
||||
#define IDC_XID_CLEAR 1300
|
||||
#define IDC_DEFAULT 1287
|
||||
#define IDC_PROFILE 1288
|
||||
#define IDC_PROFILE_NAME 1289
|
||||
#define IDC_PROFILE_SAVE 1291
|
||||
#define IDC_PROFILE_DELETE 1292
|
||||
#define IDC_BUTTONS 1293
|
||||
#define IDC_LSTICK 1294
|
||||
#define IDC_RSTICK 1295
|
||||
#define IDC_DPAD 1296
|
||||
#define IDC_TRIGGERS 1297
|
||||
#define IDC_RUMBLE 1298
|
||||
#define IDC_OPTIONS 1299
|
||||
#define IDC_CLEAR 1300
|
||||
#define IDC_RUMBLE_LIST 1301
|
||||
#define IDC_RUMBLE_TEST 1302
|
||||
#define IDC_NETWORK_ADAPTER 1303
|
||||
|
@ -275,10 +259,10 @@
|
|||
#define IDC_AIMING_NEGX 1316
|
||||
#define IDC_AIMING_NEGY 1317
|
||||
#define IDC_AIMING_POSX 1318
|
||||
#define IDC_SIGHT_CHANGE_POSY 1319
|
||||
#define IDC_SIGHT_CHANGE_NEGX 1320
|
||||
#define IDC_SIGHT_CHANGE_NEGY 1321
|
||||
#define IDC_SIGHT_CHANGE_POSX 1322
|
||||
#define IDC_SIGHT_CHANGE_POSY 1319
|
||||
#define IDC_SIGHT_CHANGE_NEGX 1320
|
||||
#define IDC_SIGHT_CHANGE_NEGY 1321
|
||||
#define IDC_SIGHT_CHANGE_POSX 1322
|
||||
#define ID_FILE_EXIT 40005
|
||||
#define ID_HELP_ABOUT 40008
|
||||
#define ID_EMULATION_START 40009
|
||||
|
@ -347,7 +331,7 @@
|
|||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 136
|
||||
#define _APS_NEXT_RESOURCE_VALUE 137
|
||||
#define _APS_NEXT_COMMAND_VALUE 40117
|
||||
#define _APS_NEXT_CONTROL_VALUE 1308
|
||||
#define _APS_NEXT_SYMED_VALUE 109
|
||||
|
|
Loading…
Reference in New Issue