mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 14:31:24 +12:00
implement CELL_PAD_INFO_INTERCEPTED
This commit is contained in:
parent
8ad14c4ada
commit
6f7b25de90
13 changed files with 250 additions and 153 deletions
|
@ -87,7 +87,12 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
|||
|
||||
if (auto manager = fxm::get<rsx::overlays::display_manager>())
|
||||
{
|
||||
manager->create<rsx::overlays::message_dialog>()->show(msgString.get_ptr(), _type, [callback, userData](s32 status)
|
||||
if (manager->get<rsx::overlays::message_dialog>())
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
const auto res = manager->create<rsx::overlays::message_dialog>()->show(msgString.get_ptr(), _type, [callback, userData](s32 status)
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
|
@ -99,7 +104,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
|||
}
|
||||
});
|
||||
|
||||
return CELL_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
const auto dlg = fxm::import<MsgDialogBase>(Emu.GetCallbacks().get_msg_dialog);
|
||||
|
@ -128,8 +133,12 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
|||
|
||||
fxm::remove<MsgDialogBase>();
|
||||
}
|
||||
|
||||
pad::SetIntercepted(false);
|
||||
};
|
||||
|
||||
pad::SetIntercepted(true);
|
||||
|
||||
atomic_t<bool> result(false);
|
||||
|
||||
// Run asynchronously in GUI thread
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "pad_thread.h"
|
||||
|
||||
#include "cellSysutil.h"
|
||||
#include "cellOskDialog.h"
|
||||
|
@ -22,14 +24,28 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogPara
|
|||
for (u32 i = 0; (i < maxLength) && (inputFieldInfo->init_text[i] != 0); i++)
|
||||
s_osk_text[i] = inputFieldInfo->init_text[i];
|
||||
|
||||
const auto osk = Emu.GetCallbacks().get_msg_dialog();
|
||||
const auto osk = fxm::import<MsgDialogBase>(Emu.GetCallbacks().get_msg_dialog);
|
||||
|
||||
if (!osk)
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
osk->on_close = [&](s32 status)
|
||||
osk->on_close = [wptr = std::weak_ptr<MsgDialogBase>(osk)](s32 status)
|
||||
{
|
||||
const auto osk = wptr.lock();
|
||||
|
||||
if (osk && osk->state.compare_and_swap_test(MsgDialogState::Open, MsgDialogState::Close))
|
||||
{
|
||||
fxm::remove<MsgDialogBase>();
|
||||
}
|
||||
|
||||
if (status != CELL_MSGDIALOG_BUTTON_OK) sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
|
||||
result = true;
|
||||
|
||||
pad::SetIntercepted(false);
|
||||
};
|
||||
|
||||
osk->on_osk_input_entered = [&]()
|
||||
|
@ -37,9 +53,12 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogPara
|
|||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED, 0);
|
||||
};
|
||||
|
||||
pad::SetIntercepted(true);
|
||||
|
||||
Emu.CallAfter([&]()
|
||||
{
|
||||
osk->CreateOsk("On Screen Keyboard", s_osk_text, maxLength);
|
||||
result = true;
|
||||
});
|
||||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
|
||||
|
@ -78,6 +97,21 @@ s32 cellOskDialogGetSize(vm::ptr<u16> width, vm::ptr<u16> height, vm::ptr<CellOs
|
|||
s32 cellOskDialogAbort()
|
||||
{
|
||||
cellOskDialog.warning("cellOskDialogAbort()");
|
||||
|
||||
const auto dlg = fxm::get<MsgDialogBase>();
|
||||
|
||||
if (!dlg)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (!dlg->state.compare_and_swap_test(MsgDialogState::Open, MsgDialogState::Abort))
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
verify(HERE), fxm::remove<MsgDialogBase>();
|
||||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -220,9 +254,9 @@ s32 cellOskDialogExtSetPointerEnable(b8 enable)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellOskDialogExtUpdatePointerDisplayPos()
|
||||
s32 cellOskDialogExtUpdatePointerDisplayPos(/*const CellOskDialogPoint pos*/)
|
||||
{
|
||||
cellOskDialog.todo("cellOskDialogExtUpdatePointerDisplayPos"); // Missing arguments
|
||||
cellOskDialog.todo("cellOskDialogExtUpdatePointerDisplayPos(posX=%f, posY=%f)"/*, pos.x, pos.y*/);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ enum CellOskDialogType
|
|||
|
||||
enum
|
||||
{
|
||||
CELL_OSKDIALOG_STRING_SIZE = 512, //Theroretical maxium for osk input, games can specify a lower limit
|
||||
CELL_OSKDIALOG_STRING_SIZE = 512, // Theroretical maximum for osk input, games can specify a lower limit
|
||||
};
|
||||
|
||||
struct CellOskDialogInputFieldInfo
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
|
||||
// TODO: HLE info (constants, structs, etc.) should not be available here
|
||||
|
||||
enum SystemInfo
|
||||
{
|
||||
CELL_PAD_INFO_INTERCEPTED = 0x00000001
|
||||
};
|
||||
|
||||
enum PortStatus
|
||||
{
|
||||
CELL_PAD_STATUS_DISCONNECTED = 0x00000000,
|
||||
|
|
|
@ -9,6 +9,134 @@ namespace rsx
|
|||
// Singleton instance declaration
|
||||
fontmgr* fontmgr::m_instance = nullptr;
|
||||
|
||||
s32 user_interface::run_input_loop()
|
||||
{
|
||||
std::array<std::chrono::steady_clock::time_point, CELL_PAD_MAX_PORT_NUM> timestamp;
|
||||
timestamp.fill(std::chrono::steady_clock::now());
|
||||
|
||||
std::array<std::array<bool, 8>, CELL_PAD_MAX_PORT_NUM> button_state;
|
||||
for (auto& state : button_state)
|
||||
{
|
||||
state.fill(true);
|
||||
}
|
||||
|
||||
input_timer.Start();
|
||||
|
||||
{
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
const auto handler = pad::get_current_handler();
|
||||
handler->SetIntercepted(true);
|
||||
}
|
||||
|
||||
while (!exit)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
return selection_code::canceled;
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
|
||||
const auto handler = pad::get_current_handler();
|
||||
|
||||
const PadInfo& rinfo = handler->GetInfo();
|
||||
|
||||
if (Emu.IsPaused() || !rinfo.now_connect)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int pad_index = -1;
|
||||
for (const auto &pad : handler->GetPads())
|
||||
{
|
||||
if (++pad_index >= CELL_PAD_MAX_PORT_NUM)
|
||||
{
|
||||
LOG_FATAL(RSX, "The native overlay cannot handle more than 7 pads! Current number of pads: %d", pad_index + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &button : pad->m_buttons)
|
||||
{
|
||||
u8 button_id = 255;
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_LEFT:
|
||||
button_id = pad_button::dpad_left;
|
||||
break;
|
||||
case CELL_PAD_CTRL_RIGHT:
|
||||
button_id = pad_button::dpad_right;
|
||||
break;
|
||||
case CELL_PAD_CTRL_DOWN:
|
||||
button_id = pad_button::dpad_down;
|
||||
break;
|
||||
case CELL_PAD_CTRL_UP:
|
||||
button_id = pad_button::dpad_up;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_TRIANGLE:
|
||||
button_id = pad_button::triangle;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CIRCLE:
|
||||
button_id = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::cross : pad_button::circle;
|
||||
break;
|
||||
case CELL_PAD_CTRL_SQUARE:
|
||||
button_id = pad_button::square;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CROSS:
|
||||
button_id = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::circle : pad_button::cross;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (button_id < 255)
|
||||
{
|
||||
if (button.m_pressed)
|
||||
{
|
||||
if (button_id < 4) // d-pad button
|
||||
{
|
||||
if (!button_state[pad_index][button_id] || input_timer.GetMsSince(timestamp[pad_index]) > 400)
|
||||
{
|
||||
// d-pad button was not pressed, or was pressed more than 400ms ago
|
||||
timestamp[pad_index] = std::chrono::steady_clock::now();
|
||||
on_button_pressed(static_cast<pad_button>(button_id));
|
||||
}
|
||||
}
|
||||
else if (!button_state[pad_index][button_id])
|
||||
{
|
||||
// button was not pressed
|
||||
on_button_pressed(static_cast<pad_button>(button_id));
|
||||
}
|
||||
}
|
||||
|
||||
button_state[pad_index][button_id] = button.m_pressed;
|
||||
}
|
||||
|
||||
if (button.m_flush)
|
||||
{
|
||||
button.m_pressed = false;
|
||||
button.m_flush = false;
|
||||
button.m_value = 0;
|
||||
}
|
||||
|
||||
if (exit)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
// Unreachable
|
||||
return 0;
|
||||
}
|
||||
|
||||
void user_interface::close()
|
||||
{
|
||||
// Force unload
|
||||
|
@ -24,6 +152,12 @@ namespace rsx
|
|||
manager->remove(uid);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
const auto handler = pad::get_current_handler();
|
||||
handler->SetIntercepted(false);
|
||||
}
|
||||
|
||||
if (on_close)
|
||||
on_close(return_code);
|
||||
}
|
||||
|
|
|
@ -80,127 +80,7 @@ namespace rsx
|
|||
|
||||
void close();
|
||||
|
||||
s32 run_input_loop()
|
||||
{
|
||||
std::array<std::chrono::steady_clock::time_point, CELL_PAD_MAX_PORT_NUM> timestamp;
|
||||
timestamp.fill(std::chrono::steady_clock::now());
|
||||
|
||||
std::array<std::array<bool, 8>, CELL_PAD_MAX_PORT_NUM> button_state;
|
||||
for (auto& state : button_state)
|
||||
{
|
||||
state.fill(true);
|
||||
}
|
||||
|
||||
input_timer.Start();
|
||||
|
||||
while (!exit)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
return selection_code::canceled;
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
|
||||
const auto handler = pad::get_current_handler();
|
||||
|
||||
const PadInfo& rinfo = handler->GetInfo();
|
||||
|
||||
if (Emu.IsPaused() || !rinfo.now_connect)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int pad_index = -1;
|
||||
for (const auto &pad : handler->GetPads())
|
||||
{
|
||||
if (++pad_index >= CELL_PAD_MAX_PORT_NUM)
|
||||
{
|
||||
LOG_FATAL(RSX, "The native overlay cannot handle more than 7 pads! Current number of pads: %d", pad_index + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &button : pad->m_buttons)
|
||||
{
|
||||
u8 button_id = 255;
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_LEFT:
|
||||
button_id = pad_button::dpad_left;
|
||||
break;
|
||||
case CELL_PAD_CTRL_RIGHT:
|
||||
button_id = pad_button::dpad_right;
|
||||
break;
|
||||
case CELL_PAD_CTRL_DOWN:
|
||||
button_id = pad_button::dpad_down;
|
||||
break;
|
||||
case CELL_PAD_CTRL_UP:
|
||||
button_id = pad_button::dpad_up;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_TRIANGLE:
|
||||
button_id = pad_button::triangle;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CIRCLE:
|
||||
button_id = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::cross : pad_button::circle;
|
||||
break;
|
||||
case CELL_PAD_CTRL_SQUARE:
|
||||
button_id = pad_button::square;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CROSS:
|
||||
button_id = g_cfg.sys.enter_button_assignment == enter_button_assign::circle ? pad_button::circle : pad_button::cross;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (button_id < 255)
|
||||
{
|
||||
if (button.m_pressed)
|
||||
{
|
||||
if (button_id < 4) // d-pad button
|
||||
{
|
||||
if (!button_state[pad_index][button_id] || input_timer.GetMsSince(timestamp[pad_index]) > 400)
|
||||
{
|
||||
// d-pad button was not pressed, or was pressed more than 400ms ago
|
||||
timestamp[pad_index] = std::chrono::steady_clock::now();
|
||||
on_button_pressed(static_cast<pad_button>(button_id));
|
||||
}
|
||||
}
|
||||
else if (!button_state[pad_index][button_id])
|
||||
{
|
||||
// button was not pressed
|
||||
on_button_pressed(static_cast<pad_button>(button_id));
|
||||
}
|
||||
}
|
||||
|
||||
button_state[pad_index][button_id] = button.m_pressed;
|
||||
}
|
||||
|
||||
if (button.m_flush)
|
||||
{
|
||||
button.m_pressed = false;
|
||||
button.m_flush = false;
|
||||
button.m_value = 0;
|
||||
}
|
||||
|
||||
if (exit)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
// Unreachable
|
||||
return 0;
|
||||
}
|
||||
s32 run_input_loop();
|
||||
};
|
||||
|
||||
class display_manager
|
||||
|
|
|
@ -316,9 +316,11 @@ void mm_joystick_handler::GetNextButtonPress(const std::string& padId, const std
|
|||
switch (status)
|
||||
{
|
||||
case JOYERR_UNPLUGGED:
|
||||
{
|
||||
return fail_callback(padId);
|
||||
|
||||
}
|
||||
case JOYERR_NOERROR:
|
||||
{
|
||||
auto data = GetButtonValues(js_info, js_caps);
|
||||
|
||||
// Check for each button in our list if its corresponding (maybe remapped) button or axis was pressed.
|
||||
|
@ -421,6 +423,9 @@ void mm_joystick_handler::GetNextButtonPress(const std::string& padId, const std
|
|||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mm_joystick_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold)
|
||||
|
|
|
@ -57,8 +57,10 @@ void pad_thread::Init()
|
|||
}
|
||||
}
|
||||
|
||||
const u32 system_info = m_info.system_info;
|
||||
std::memset(&m_info, 0, sizeof(m_info));
|
||||
m_info.now_connect = 0;
|
||||
m_info.system_info |= system_info;
|
||||
|
||||
m_pads.clear();
|
||||
handlers.clear();
|
||||
|
@ -147,6 +149,18 @@ void pad_thread::SetEnabled(bool enabled)
|
|||
is_enabled = enabled;
|
||||
}
|
||||
|
||||
void pad_thread::SetIntercepted(bool intercepted)
|
||||
{
|
||||
if (intercepted)
|
||||
{
|
||||
m_info.system_info |= CELL_PAD_INFO_INTERCEPTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info.system_info &= ~CELL_PAD_INFO_INTERCEPTED;
|
||||
}
|
||||
}
|
||||
|
||||
void pad_thread::ThreadFunc()
|
||||
{
|
||||
active = true;
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
void SetEnabled(bool enabled);
|
||||
void SetIntercepted(bool intercepted);
|
||||
|
||||
protected:
|
||||
void ThreadFunc();
|
||||
|
@ -36,7 +37,7 @@ protected:
|
|||
void *curthread;
|
||||
void *curwindow;
|
||||
|
||||
PadInfo m_info;
|
||||
PadInfo m_info{ 0, 0 };
|
||||
std::vector<std::shared_ptr<Pad>> m_pads;
|
||||
|
||||
atomic_t<bool> active{ false };
|
||||
|
@ -54,4 +55,11 @@ namespace pad
|
|||
{
|
||||
return verify(HERE, g_current.load());
|
||||
};
|
||||
|
||||
static inline void SetIntercepted(bool intercepted)
|
||||
{
|
||||
std::lock_guard lock(g_pad_mutex);
|
||||
const auto handler = get_current_handler();
|
||||
handler->SetIntercepted(intercepted);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries,
|
|||
atomic_t<bool> dlg_result(false);
|
||||
atomic_t<s32> selection;
|
||||
|
||||
pad::SetIntercepted(true);
|
||||
|
||||
Emu.CallAfter([&]()
|
||||
{
|
||||
save_data_list_dialog sdid(save_entries, focused, op, listSet);
|
||||
|
@ -31,5 +33,7 @@ s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries,
|
|||
thread_ctrl::wait_for(1000);
|
||||
}
|
||||
|
||||
pad::SetIntercepted(false);
|
||||
|
||||
return selection.load();
|
||||
}
|
||||
|
|
|
@ -328,6 +328,7 @@ void xinput_pad_handler::ThreadProc()
|
|||
switch (result)
|
||||
{
|
||||
case ERROR_DEVICE_NOT_CONNECTED:
|
||||
{
|
||||
if (last_connection_status[i] == true)
|
||||
{
|
||||
LOG_ERROR(HLE, "XInput device %d disconnected", padnum);
|
||||
|
@ -337,8 +338,9 @@ void xinput_pad_handler::ThreadProc()
|
|||
connected--;
|
||||
}
|
||||
continue;
|
||||
|
||||
}
|
||||
case ERROR_SUCCESS:
|
||||
{
|
||||
if (last_connection_status[i] == false)
|
||||
{
|
||||
LOG_SUCCESS(HLE, "XInput device %d reconnected", padnum);
|
||||
|
@ -437,7 +439,9 @@ void xinput_pad_handler::ThreadProc()
|
|||
m_dev->last_vibration = clock();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue