mirror of
https://github.com/Vita3K/Vita3K-Android.git
synced 2024-12-13 16:25:46 +00:00
touch: Add touchpad support.
- Allow double touch in pc with using touchpad of DS/4. - Add draw touchpad cursor when is used. - Add config for allow disable show this cursor per game.
This commit is contained in:
parent
32344c2a25
commit
b8ae624f73
@ -95,6 +95,7 @@ enum PerfomanceOverleyPosition {
|
||||
code(bool, "discord-rich-presence", true, discord_rich_presence) \
|
||||
code(bool, "wait-for-debugger", false, wait_for_debugger) \
|
||||
code(bool, "color-surface-debug", false, color_surface_debug) \
|
||||
code(bool, "show-touchpad-cursor", true, show_touchpad_cursor) \
|
||||
code(bool, "performance-overlay", false, performance_overlay) \
|
||||
code(int, "perfomance-overlay-detail", static_cast<int>(MINIMUM), performance_overlay_detail) \
|
||||
code(int, "perfomance-overlay-position", static_cast<int>(TOP_LEFT), performance_overlay_position) \
|
||||
|
@ -180,6 +180,7 @@ public:
|
||||
bool v_sync = true;
|
||||
int anisotropic_filtering = 1;
|
||||
bool stretch_the_display_area = false;
|
||||
bool show_touchpad_cursor = true;
|
||||
int psn_status = SCE_NP_SERVICE_STATE_UNKNOWN;
|
||||
};
|
||||
|
||||
|
@ -51,5 +51,5 @@ add_library(
|
||||
|
||||
target_include_directories(gui PUBLIC include ${CMAKE_SOURCE_DIR}/vita3k)
|
||||
target_link_libraries(gui PUBLIC app compat config dialog emuenv https ime imgui glutil lang regmgr np)
|
||||
target_link_libraries(gui PRIVATE audio ctrl kernel miniz psvpfsparser pugixml::pugixml stb renderer packages sdl2 vkutil host::dialog)
|
||||
target_link_libraries(gui PRIVATE audio ctrl kernel miniz psvpfsparser pugixml::pugixml stb renderer packages sdl2 touch vkutil host::dialog)
|
||||
target_link_libraries(gui PUBLIC tracy)
|
||||
|
@ -124,6 +124,7 @@ void draw_reinstall_dialog(GenericDialogState *status, GuiState &gui, EmuEnvStat
|
||||
void draw_pre_compiling_shaders_progress(GuiState &gui, EmuEnvState &emuenv, const uint32_t &total);
|
||||
void draw_shaders_count_compiled(GuiState &gui, EmuEnvState &emuenv);
|
||||
void draw_trophies_unlocked(GuiState &gui, EmuEnvState &emuenv);
|
||||
void draw_touchpad_cursor(EmuEnvState &emuenv);
|
||||
void draw_perf_overlay(GuiState &gui, EmuEnvState &emuenv);
|
||||
|
||||
ImTextureID load_image(GuiState &gui, const char *data, const std::uint32_t size);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <lang/functions.h>
|
||||
#include <packages/sfo.h>
|
||||
#include <regmgr/functions.h>
|
||||
#include <touch/functions.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/log.h>
|
||||
#include <util/string_utils.h>
|
||||
@ -738,6 +739,23 @@ void draw_end(GuiState &gui, SDL_Window *window) {
|
||||
ImGui_ImplSdl_RenderDrawData(gui.imgui_state.get());
|
||||
}
|
||||
|
||||
void draw_touchpad_cursor(EmuEnvState &emuenv) {
|
||||
SceTouchPortType port;
|
||||
const auto touchpad_fingers_pos = get_touchpad_fingers_pos(port);
|
||||
if (touchpad_fingers_pos.empty())
|
||||
return;
|
||||
|
||||
const ImVec2 RES_SCALE(emuenv.viewport_size.x / emuenv.res_width_dpi_scale, emuenv.viewport_size.y / emuenv.res_height_dpi_scale);
|
||||
const ImVec2 SCALE(RES_SCALE.x * emuenv.dpi_scale, RES_SCALE.y * emuenv.dpi_scale);
|
||||
|
||||
const auto color = (port == SCE_TOUCH_PORT_FRONT) ? IM_COL32(0.f, 102.f, 204.f, 255.f) : IM_COL32(255.f, 0.f, 0.f, 255.f);
|
||||
for (const auto &pos : touchpad_fingers_pos) {
|
||||
auto x = emuenv.viewport_pos.x + (pos.x * emuenv.viewport_size.x);
|
||||
auto y = emuenv.viewport_pos.y + (pos.y * emuenv.viewport_size.y);
|
||||
ImGui::GetForegroundDrawList()->AddCircle(ImVec2(x, y), 20.f * SCALE.x, color, 0, 4.f * SCALE.x);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_vita_area(GuiState &gui, EmuEnvState &emuenv) {
|
||||
if (gui.vita_area.start_screen)
|
||||
draw_start_screen(gui, emuenv);
|
||||
|
@ -180,6 +180,7 @@ static bool get_custom_config(GuiState &gui, EmuEnvState &emuenv, const std::str
|
||||
if (!config_child.child("emulator").empty()) {
|
||||
const auto emulator_child = config_child.child("emulator");
|
||||
config.ngs_enable = emulator_child.attribute("enable-ngs").as_bool();
|
||||
config.show_touchpad_cursor = emulator_child.attribute("show-touchpad-cursor").as_bool();
|
||||
}
|
||||
|
||||
// Load Network Config
|
||||
@ -227,6 +228,7 @@ void init_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path
|
||||
config.anisotropic_filtering = emuenv.cfg.anisotropic_filtering;
|
||||
config.pstv_mode = emuenv.cfg.pstv_mode;
|
||||
config.ngs_enable = emuenv.cfg.ngs_enable;
|
||||
config.show_touchpad_cursor = emuenv.cfg.show_touchpad_cursor;
|
||||
config.psn_status = emuenv.cfg.psn_status;
|
||||
}
|
||||
get_modules_list(gui, emuenv);
|
||||
@ -292,6 +294,7 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) {
|
||||
// Emulator
|
||||
auto emulator_child = config_child.append_child("emulator");
|
||||
emulator_child.append_attribute("enable-ngs") = config.ngs_enable;
|
||||
emulator_child.append_attribute("show-touchpad-cursor") = config.show_touchpad_cursor;
|
||||
|
||||
// Network
|
||||
auto network_child = config_child.append_child("network");
|
||||
@ -312,6 +315,7 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) {
|
||||
emuenv.cfg.v_sync = config.v_sync;
|
||||
emuenv.cfg.anisotropic_filtering = config.anisotropic_filtering;
|
||||
emuenv.cfg.ngs_enable = config.ngs_enable;
|
||||
emuenv.cfg.show_touchpad_cursor = config.show_touchpad_cursor;
|
||||
emuenv.cfg.psn_status = config.psn_status;
|
||||
}
|
||||
|
||||
@ -369,6 +373,7 @@ void set_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path)
|
||||
emuenv.cfg.current_config.v_sync = emuenv.cfg.v_sync;
|
||||
emuenv.cfg.current_config.anisotropic_filtering = emuenv.cfg.anisotropic_filtering;
|
||||
emuenv.cfg.current_config.ngs_enable = emuenv.cfg.ngs_enable;
|
||||
emuenv.cfg.current_config.show_touchpad_cursor = emuenv.cfg.show_touchpad_cursor;
|
||||
emuenv.cfg.current_config.psn_status = emuenv.cfg.psn_status;
|
||||
}
|
||||
|
||||
@ -764,6 +769,10 @@ void draw_settings_dialog(GuiState &gui, EmuEnvState &emuenv) {
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Uncheck the box to disable the display of the compile shaders dialog.");
|
||||
ImGui::Spacing();
|
||||
ImGui::Checkbox("Show Touchpad Cursor", &config.show_touchpad_cursor);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Uncheck the box to disable showing the touchpad cursor on-screen.");
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Log Compatibility Warnings", &emuenv.cfg.log_compat_warn);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Check the box to log issues related to the app compatibility database.");
|
||||
|
@ -714,6 +714,9 @@ bool handle_events(EmuEnvState &emuenv, GuiState &gui) {
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
if (!emuenv.kernel.is_threads_paused() && (event.cbutton.button == SDL_CONTROLLER_BUTTON_TOUCHPAD))
|
||||
toggle_touchscreen();
|
||||
|
||||
if (ImGui::GetIO().WantTextInput)
|
||||
continue;
|
||||
|
||||
@ -759,18 +762,18 @@ bool handle_events(EmuEnvState &emuenv, GuiState &gui) {
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
handle_touchpad_event(event.ctouchpad);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
handle_window_event(emuenv, event.window);
|
||||
break;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
handle_touch_event(event.tfinger);
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
handle_touch_event(event.tfinger);
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
handle_touch_event(event.tfinger);
|
||||
break;
|
||||
|
@ -432,6 +432,9 @@ int main(int argc, char *argv[]) {
|
||||
if (emuenv.cfg.performance_overlay && !emuenv.kernel.is_threads_paused() && (emuenv.common_dialog.status != SCE_COMMON_DIALOG_STATUS_RUNNING))
|
||||
gui::draw_perf_overlay(gui, emuenv);
|
||||
|
||||
if (emuenv.cfg.current_config.show_touchpad_cursor && !emuenv.kernel.is_threads_paused())
|
||||
gui::draw_touchpad_cursor(emuenv);
|
||||
|
||||
if (emuenv.display.imgui_render) {
|
||||
gui::draw_ui(gui, emuenv);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <emuenv/state.h>
|
||||
#include <touch/touch.h>
|
||||
|
||||
std::vector<SceFVector2> get_touchpad_fingers_pos(SceTouchPortType &port);
|
||||
int handle_touchpad_event(SDL_ControllerTouchpadEvent &touchpad);
|
||||
void touch_vsync_update(const EmuEnvState &emuenv);
|
||||
int handle_touch_event(SDL_TouchFingerEvent &finger);
|
||||
int toggle_touchscreen();
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#define SCE_TOUCH_MAX_REPORT 8
|
||||
|
||||
struct SDL_ControllerTouchpadEvent;
|
||||
struct SDL_TouchFingerEvent;
|
||||
|
||||
enum SceTouchSamplingState {
|
||||
|
@ -30,11 +30,12 @@
|
||||
constexpr int MAX_TOUCH_BUFFER_SAVED = 64;
|
||||
|
||||
static SceTouchData touch_buffers[MAX_TOUCH_BUFFER_SAVED][2];
|
||||
int touch_buffer_idx = 0;
|
||||
|
||||
static int touch_buffer_idx = 0;
|
||||
static bool is_touchpad = false;
|
||||
static SDL_TouchFingerEvent finger_buffer[8];
|
||||
static SDL_ControllerTouchpadEvent touchpad_buffer[8];
|
||||
static uint8_t finger_count = 0;
|
||||
static auto touchscreen_port = SCE_TOUCH_PORT_FRONT;
|
||||
static SceTouchPortType touchscreen_port = SCE_TOUCH_PORT_FRONT;
|
||||
static bool is_touched[2] = { false, false };
|
||||
// Used for mouse support
|
||||
static int curr_touch_id[2] = { 0, 0 };
|
||||
@ -67,12 +68,33 @@ static SceTouchData recover_touch_events(const EmuEnvState &emuenv) {
|
||||
return touch_data;
|
||||
}
|
||||
|
||||
static SceTouchData recover_touchpad_events(const EmuEnvState &emuenv) {
|
||||
SceTouchData touch_data;
|
||||
touch_data.status = 0;
|
||||
|
||||
for (uint8_t i = 0; i < finger_count; i++) {
|
||||
touch_data.report[i].id = static_cast<uint8_t>(touchpad_buffer[i].which);
|
||||
touch_data.report[i].force = forceTouchEnabled[touchscreen_port] ? 128 : 0;
|
||||
|
||||
touch_data.report[i].x = static_cast<uint16_t>(touchpad_buffer[i].x * 1920);
|
||||
if (touchscreen_port == SCE_TOUCH_PORT_FRONT) {
|
||||
touch_data.report[i].y = static_cast<uint16_t>(touchpad_buffer[i].y * 1088);
|
||||
} else {
|
||||
touch_data.report[i].y = static_cast<uint16_t>(108 + touchpad_buffer[i].y * 781);
|
||||
}
|
||||
}
|
||||
|
||||
touch_data.reportNum = finger_count;
|
||||
|
||||
return touch_data;
|
||||
}
|
||||
|
||||
void touch_vsync_update(const EmuEnvState &emuenv) {
|
||||
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
|
||||
uint64_t timestamp = std::chrono::duration_cast<std::chrono::microseconds>(ts.time_since_epoch()).count();
|
||||
|
||||
if (finger_count > 0) {
|
||||
SceTouchData touch_data = recover_touch_events(emuenv);
|
||||
SceTouchData touch_data = is_touchpad ? recover_touchpad_events(emuenv) : recover_touch_events(emuenv);
|
||||
touch_data.timeStamp = timestamp;
|
||||
|
||||
SceTouchData *buffers = touch_buffers[(touch_buffer_idx + 1) % MAX_TOUCH_BUFFER_SAVED];
|
||||
@ -189,6 +211,57 @@ int handle_touch_event(SDL_TouchFingerEvent &finger) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_touchpad_event(SDL_ControllerTouchpadEvent &touchpad) {
|
||||
switch (touchpad.type) {
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
if (finger_count >= 8) // best we can do is clean everything
|
||||
finger_count = 0;
|
||||
|
||||
touchpad_buffer[finger_count] = touchpad;
|
||||
touchpad_buffer[finger_count].which = next_touch_id;
|
||||
next_touch_id = (next_touch_id + 1) % 128;
|
||||
finger_count++;
|
||||
break;
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
if (touchpad.finger == touchpad_buffer[i].finger) {
|
||||
if (i < (finger_count - 1))
|
||||
touchpad_buffer[i] = touchpad_buffer[i + 1];
|
||||
}
|
||||
}
|
||||
if (finger_count > 0)
|
||||
finger_count--;
|
||||
break;
|
||||
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||
for (int i = 0; i < finger_count; i++) {
|
||||
if (touchpad.finger == touchpad_buffer[i].finger) {
|
||||
const auto touch_id = touchpad_buffer[i].which;
|
||||
touchpad_buffer[i] = touchpad;
|
||||
touchpad_buffer[i].which = touch_id;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
is_touchpad = finger_count > 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<SceFVector2> get_touchpad_fingers_pos(SceTouchPortType &port) {
|
||||
if (!is_touchpad)
|
||||
return {};
|
||||
|
||||
std::vector<SceFVector2> touchpad_fingers_pos;
|
||||
for (int i = 0; i < finger_count; i++) {
|
||||
touchpad_fingers_pos.push_back({ touchpad_buffer[i].x, touchpad_buffer[i].y });
|
||||
}
|
||||
|
||||
port = touchscreen_port;
|
||||
|
||||
return touchpad_fingers_pos;
|
||||
}
|
||||
|
||||
int toggle_touchscreen() {
|
||||
if (touchscreen_port == SCE_TOUCH_PORT_FRONT) {
|
||||
touchscreen_port = SCE_TOUCH_PORT_BACK;
|
||||
|
Loading…
Reference in New Issue
Block a user