Fixed some bugs in the mu handling of the gui + added XUnmountMU patch

This commit is contained in:
ergo720 2021-06-14 07:34:46 +02:00
parent 1d9dc0df2d
commit 9307f816ba
11 changed files with 108 additions and 46 deletions

View File

@ -783,8 +783,8 @@ void Settings::SyncToEmulator()
// register xbox device input settings
for (int i = 0; i < 4; i++) {
g_EmuShared->SetInputDevTypeSettings(&m_input_port[i].Type, i);
g_EmuShared->SetInputSlotTypeSettings(&m_input_port[i].TopSlotType, i, MU_SLOT_TOP);
g_EmuShared->SetInputSlotTypeSettings(&m_input_port[i].BottomSlotType, i, MU_SLOT_BOTTOM);
g_EmuShared->SetInputSlotTypeSettings(&m_input_port[i].TopSlotType, i, SLOT_TOP);
g_EmuShared->SetInputSlotTypeSettings(&m_input_port[i].BottomSlotType, i, SLOT_BOTTOM);
if (m_input_port[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
g_EmuShared->SetInputDevNameSettings(m_input_port[i].DeviceName.c_str(), i);
auto it = std::find_if(m_input_profiles[m_input_port[i].Type].begin(),

View File

@ -35,7 +35,7 @@
#define SBC_NUM_BUTTONS 56
#define HIGHEST_NUM_BUTTONS SBC_NUM_BUTTONS
#define MU_NUM_SLOTS 2
#define XBOX_CTRL_NUM_SLOTS 2
#define XBOX_BUTTON_NAME_LENGTH 30
#define HOST_BUTTON_NAME_LENGTH 30

View File

@ -37,8 +37,8 @@
#undef SetPort
#endif
#define MU_SLOT_TOP 0
#define MU_SLOT_BOTTOM 1
#define SLOT_TOP 0
#define SLOT_BOTTOM 1
extern int dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)];
@ -50,6 +50,11 @@ inline XBOX_INPUT_DEVICE input_support_list[] = {
XBOX_INPUT_DEVICE::ARCADE_STICK,
};
inline XBOX_INPUT_DEVICE slot_support_list[] = {
XBOX_INPUT_DEVICE::DEVICE_INVALID,
XBOX_INPUT_DEVICE::MEMORY_UNIT,
};
#pragma pack(1)
// xpad in/out buffers stripped of the first two bytes

View File

@ -43,7 +43,7 @@ InputWindow::~InputWindow()
m_DeviceConfig = nullptr;
}
bool InputWindow::IsProfileSaved()
int InputWindow::IsProfileSaved()
{
if (m_bHasChanges) {
PopupReturn ret = PopupQuestion(m_hwnd_window, "Current configuration is not saved. Save before closing?");
@ -53,23 +53,24 @@ bool InputWindow::IsProfileSaved()
char name[50];
SendMessage(m_hwnd_profile_list, WM_GETTEXT, sizeof(name), reinterpret_cast<LPARAM>(name));
if (SaveProfile(std::string(name))) {
return true;
return EXIT_SAVE;
}
return false;
return EXIT_ABORT;
}
case PopupReturn::No: {
return true;
return EXIT_IGNORE;
}
case PopupReturn::Cancel:
default: {
return false;
return EXIT_ABORT;
}
}
}
return true;
return EXIT_IGNORE;
}
void InputWindow::UpdateDeviceList()
@ -259,6 +260,10 @@ bool InputWindow::SaveProfile(const std::string& name)
g_Settings->m_input_port[m_port_num].DeviceName = profile.DeviceName;
g_Settings->m_input_port[m_port_num].ProfileName = profile.ProfileName;
g_Settings->m_input_profiles[m_dev_type].push_back(std::move(profile));
if (auto duke_wnd = dynamic_cast<DukeInputWindow *>(this)) {
duke_wnd->SaveSlotConfig();
}
m_bHasChanges = false;
return true;
}

View File

@ -42,6 +42,10 @@
#define BUTTON_SWAP 9
#define SLOTS_CHANGED 10
#define EXIT_ABORT 0
#define EXIT_SAVE 1
#define EXIT_IGNORE 2
#define XINPUT_DEFAULT 0
#define DINPUT_DEFAULT 1
@ -61,7 +65,7 @@ public:
virtual void ClearBindings() = 0;
virtual void UpdateProfile(const std::string& name, int command);
void UpdateCurrentDevice();
virtual bool IsProfileSaved();
virtual int IsProfileSaved();
void SwapMoCursorAxis(Button *button);
@ -107,7 +111,8 @@ public:
void BindDefault();
void ClearBindings() override;
void UpdateProfile(const std::string &name, int command) override;
bool IsProfileSaved() override;
int IsProfileSaved() override;
void SaveSlotConfig();
private:
@ -120,10 +125,8 @@ private:
HWND m_hwnd_rumble;
// handle of the rumble combobox
HWND m_hwnd_rumble_list;
// handle of the top slot combobox
HWND m_hwnd_top_slot_list;
// handle of the bottom slot combobox
HWND m_hwnd_bottom_slot_list;
// handles of the slot combobox
HWND m_hwnd_slot_list[2];
// currently selected rumble control
std::string m_rumble;
};

View File

@ -368,7 +368,7 @@ class EmuShared : public Mutex
bool m_bClipCursor;
unsigned int m_dwKrnlProcID; // Only used for kernel mode level.
int m_DeviceType[4];
int m_SlotDeviceType[4][MU_NUM_SLOTS];
int m_SlotDeviceType[4][XBOX_CTRL_NUM_SLOTS];
char m_DeviceControlNames[4][HIGHEST_NUM_BUTTONS][HOST_BUTTON_NAME_LENGTH];
char m_DeviceName[4][50];
char m_TitleMountPath[xbox::max_path];

View File

@ -365,6 +365,7 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
PATCH_ENTRY("XSetProcessQuantumLength", xbox::EMUPATCH(XSetProcessQuantumLength), PATCH_ALWAYS),
PATCH_ENTRY("timeKillEvent", xbox::EMUPATCH(timeKillEvent), PATCH_ALWAYS),
PATCH_ENTRY("timeSetEvent", xbox::EMUPATCH(timeSetEvent), PATCH_ALWAYS),
PATCH_ENTRY("XUnmountMU", xbox::EMUPATCH(XUnmountMU), PATCH_ALWAYS),
};
std::unordered_map<std::string, subhook::Hook> g_FunctionHooks;

View File

@ -1238,6 +1238,27 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XMountMURootA)
RETURN(ERROR_SUCCESS);
}
// ******************************************************************
// * patch: XUnmountMU
// ******************************************************************
xbox::dword_xt WINAPI xbox::EMUPATCH(XUnmountMU)
(
dword_xt dwPort,
dword_xt dwSlot
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(dwPort)
LOG_FUNC_ARG(dwSlot)
LOG_FUNC_END;
LOG_UNIMPLEMENTED();
RETURN(ERROR_SUCCESS);
}
// ******************************************************************
// * patch: OutputDebugStringA
// ******************************************************************

View File

@ -684,6 +684,15 @@ xbox::dword_xt WINAPI EMUPATCH(XMountMURootA)
PCHAR pchDrive
);
// ******************************************************************
// * patch: XUnmountMU
// ******************************************************************
xbox::dword_xt WINAPI EMUPATCH(XUnmountMU)
(
dword_xt dwPort,
dword_xt dwSlot
);
// ******************************************************************
// * patch: XMountAlternateTitleA
// ******************************************************************

View File

@ -51,8 +51,8 @@ void SyncInputSettings(int port_num, int dev_type, bool is_opt)
if (!is_opt) {
// Sync updated input to kernel process to use run-time settings.
g_EmuShared->SetInputDevTypeSettings(&g_Settings->m_input_port[port_num].Type, port_num);
g_EmuShared->SetInputSlotTypeSettings(&g_Settings->m_input_port[port_num].TopSlotType, port_num, MU_SLOT_TOP);
g_EmuShared->SetInputSlotTypeSettings(&g_Settings->m_input_port[port_num].BottomSlotType, port_num, MU_SLOT_BOTTOM);
g_EmuShared->SetInputSlotTypeSettings(&g_Settings->m_input_port[port_num].TopSlotType, port_num, SLOT_TOP);
g_EmuShared->SetInputSlotTypeSettings(&g_Settings->m_input_port[port_num].BottomSlotType, port_num, SLOT_BOTTOM);
if (dev_type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
std::string dev_name = g_Settings->m_input_port[port_num].DeviceName;

View File

@ -49,8 +49,8 @@ void DukeInputWindow::Initialize(HWND hwnd, int port_num, int dev_type)
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_hwnd_top_slot_list = GetDlgItem(hwnd, IDC_DEVICE_LIST_TOP_SLOT);
m_hwnd_bottom_slot_list = GetDlgItem(hwnd, IDC_DEVICE_LIST_BOTTOM_SLOT);
m_hwnd_slot_list[SLOT_TOP] = GetDlgItem(hwnd, IDC_DEVICE_LIST_TOP_SLOT);
m_hwnd_slot_list[SLOT_BOTTOM] = GetDlgItem(hwnd, IDC_DEVICE_LIST_BOTTOM_SLOT);
m_dev_type = dev_type;
m_max_num_buttons = dev_num_buttons[dev_type];
m_port_num = port_num;
@ -86,22 +86,27 @@ void DukeInputWindow::Initialize(HWND hwnd, int port_num, int dev_type)
// Set the maximum profile name lenght the user can enter in the profile combobox
SendMessage(m_hwnd_profile_list, CB_LIMITTEXT, 49, 0);
// Set up the device types we support in the slot ports
SendMessage(m_hwnd_top_slot_list, CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)).c_str()));
SendMessage(m_hwnd_bottom_slot_list, CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)).c_str()));
if (m_dev_type != to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK)) {
SendMessage(m_hwnd_top_slot_list, CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT)).c_str()));
SendMessage(m_hwnd_bottom_slot_list, CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT)).c_str()));
if (m_dev_type == to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK)) {
// The arcade joystick does not have slot ports so we always disable the corresponding options
EnableWindow(m_hwnd_slot_list[SLOT_TOP], FALSE);
EnableWindow(m_hwnd_slot_list[SLOT_BOTTOM], FALSE);
}
else {
// The arcade joystick does not have slot ports so always disable the corresponding options
EnableWindow(m_hwnd_top_slot_list, FALSE);
EnableWindow(m_hwnd_bottom_slot_list, FALSE);
// Set up the device types we support in the slot ports
for (auto slot_type : slot_support_list) {
LRESULT index_top = SendMessage(m_hwnd_slot_list[SLOT_TOP], CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(slot_type)).c_str()));
LRESULT index_bottom = SendMessage(m_hwnd_slot_list[SLOT_BOTTOM], CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(GetInputDeviceName(to_underlying(slot_type)).c_str()));
SendMessage(m_hwnd_slot_list[SLOT_TOP], CB_SETITEMDATA, index_top, to_underlying(slot_type));
SendMessage(m_hwnd_slot_list[SLOT_BOTTOM], CB_SETITEMDATA, index_bottom, to_underlying(slot_type));
if (g_Settings->m_input_port[m_port_num].TopSlotType == to_underlying(slot_type)) {
SendMessage(m_hwnd_slot_list[SLOT_TOP], CB_SETCURSEL, index_top, 0);
}
if (g_Settings->m_input_port[m_port_num].BottomSlotType == to_underlying(slot_type)) {
SendMessage(m_hwnd_slot_list[SLOT_BOTTOM], CB_SETCURSEL, index_bottom, 0);
}
}
}
// construct emu device
@ -210,7 +215,7 @@ void DukeInputWindow::UpdateProfile(const std::string &name, int command)
break;
default:
dynamic_cast<InputWindow *>(this)->UpdateProfile(name, command);
InputWindow::UpdateProfile(name, command);
}
}
@ -243,18 +248,30 @@ void DukeInputWindow::DetectOutput(int ms)
}
}
bool DukeInputWindow::IsProfileSaved()
int DukeInputWindow::IsProfileSaved()
{
if (dynamic_cast<InputWindow *>(this)->IsProfileSaved()) {
int DeviceType = SendMessage(m_hwnd_top_slot_list, CB_GETITEMDATA, SendMessage(m_hwnd_top_slot_list, CB_GETCURSEL, 0, 0), 0);
g_Settings->m_input_port[m_port_num].TopSlotType = DeviceType;
DeviceType = SendMessage(m_hwnd_bottom_slot_list, CB_GETITEMDATA, SendMessage(m_hwnd_bottom_slot_list, CB_GETCURSEL, 0, 0), 0);
g_Settings->m_input_port[m_port_num].BottomSlotType = DeviceType;
if (int ret = InputWindow::IsProfileSaved()) {
if (ret == EXIT_IGNORE) {
return EXIT_IGNORE;
}
else {
if (m_dev_type != to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK)) {
SaveSlotConfig();
}
return true;
return EXIT_SAVE;
}
}
return false;
return EXIT_ABORT;
}
void DukeInputWindow::SaveSlotConfig()
{
int DeviceType = SendMessage(m_hwnd_slot_list[SLOT_TOP], CB_GETITEMDATA, SendMessage(m_hwnd_slot_list[SLOT_TOP], CB_GETCURSEL, 0, 0), 0);
g_Settings->m_input_port[m_port_num].TopSlotType = DeviceType;
DeviceType = SendMessage(m_hwnd_slot_list[SLOT_BOTTOM], CB_GETITEMDATA, SendMessage(m_hwnd_slot_list[SLOT_BOTTOM], CB_GETCURSEL, 0, 0), 0);
g_Settings->m_input_port[m_port_num].BottomSlotType = DeviceType;
}
static INT_PTR CALLBACK DlgRumbleConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -302,7 +319,8 @@ INT_PTR CALLBACK DlgXidControllerConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wPar
}
break;
case IDC_DEVICE_LIST_TOP_SLOT: {
case IDC_DEVICE_LIST_TOP_SLOT:
case IDC_DEVICE_LIST_BOTTOM_SLOT: {
if (HIWORD(wParam) == CBN_SELCHANGE) {
g_InputWindow->UpdateProfile(std::string(), SLOTS_CHANGED);
}