mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-05 08:10:40 -07:00
623e1e3998
## Link to GitHub Issue or related Pull Request, if one exists Part 1 of many fixes for #814. ## Description of change For the native touch hook - add code to inject synthetic touches using Windows API (`InjectTouchInput`). Note that this is Windows 8+ only, but we can make an assumption that we are running on Win10+ for these games (TDJ/UFC/High Cheers) since the cabs assume Win10. Detect mouse events and allow IIDX poke to call into this to inject synthetic touches. Also, update the nativetouchhook to independently calculate window size and rotation, instead of relying on rawinput layer. ## Testing Tested to work with native touch option on IIDX, SDVX, POPN, all full screen / windowed / sub on/off combinations. Edge cases: * sdvx main monitor rotated 270 deg * touch invert option * windowed mode resize / moved All seem to work.
94 lines
3.9 KiB
C++
94 lines
3.9 KiB
C++
#undef CINTERFACE
|
|
|
|
#include "avs/game.h"
|
|
#include "sdvx_sub.h"
|
|
#include "games/sdvx/sdvx.h"
|
|
#include "hooks/graphics/graphics.h"
|
|
|
|
namespace overlay::windows {
|
|
|
|
SDVXSubScreen::SDVXSubScreen(SpiceOverlay *overlay) : GenericSubScreen(overlay) {
|
|
this->title = "SDVX Subscreen";
|
|
|
|
if (!games::sdvx::is_valkyrie_model()) {
|
|
this->disabled_message = "Valkyrie Model mode is not enabled!";
|
|
} else if (games::sdvx::SHOW_VM_MONITOR_WARNING) {
|
|
this->disabled_message = "VM mode subscreen overlay is not compatible with -dxmainadapter option, use -mainmonitor instead";
|
|
} else if (GRAPHICS_WINDOWED) {
|
|
if (GRAPHICS_PREVENT_SECONDARY_WINDOWS) {
|
|
this->disabled_message = "Subscreen has been disabled by the user (-sdvxnosub).";
|
|
} else {
|
|
this->disabled_message = "Overlay unavailable in windowed mode! Use the second window instead. (ALT+TAB)";
|
|
}
|
|
}
|
|
|
|
const auto padding = ImGui::GetFrameHeight() / 2;
|
|
|
|
switch (games::sdvx::OVERLAY_POS) {
|
|
case games::sdvx::SDVX_OVERLAY_BOTTOM_LEFT:
|
|
case games::sdvx::SDVX_OVERLAY_BOTTOM_RIGHT:
|
|
this->init_size.x = (ImGui::GetIO().DisplaySize.x - (ImGui::GetIO().DisplaySize.y * 9 / 16)) / 2 - padding;
|
|
this->init_size.y = (this->init_size.x * 9 / 16) + ImGui::GetFrameHeight();
|
|
break;
|
|
case games::sdvx::SDVX_OVERLAY_TOP:
|
|
case games::sdvx::SDVX_OVERLAY_BOTTOM:
|
|
case games::sdvx::SDVX_OVERLAY_MIDDLE:
|
|
default:
|
|
this->init_size = ImVec2(ImGui::GetIO().DisplaySize.x - (padding * 2), 0.f);
|
|
this->init_size.y = (this->init_size.x * 9 / 16) + ImGui::GetFrameHeight();
|
|
if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
|
this->init_size.x /= 2;
|
|
this->init_size.y /= 2;
|
|
}
|
|
break;
|
|
}
|
|
|
|
this->init_pos = ImVec2(ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2, 0);
|
|
switch (games::sdvx::OVERLAY_POS) {
|
|
case games::sdvx::SDVX_OVERLAY_BOTTOM_LEFT:
|
|
this->init_pos.x = 0;
|
|
this->init_pos.y = ImGui::GetIO().DisplaySize.y - this->init_size.y;
|
|
break;
|
|
case games::sdvx::SDVX_OVERLAY_BOTTOM_RIGHT:
|
|
this->init_pos.x = ImGui::GetIO().DisplaySize.x - this->init_size.x;
|
|
this->init_pos.y = ImGui::GetIO().DisplaySize.y - this->init_size.y;
|
|
break;
|
|
case games::sdvx::SDVX_OVERLAY_TOP:
|
|
this->init_pos.y = padding;
|
|
break;
|
|
case games::sdvx::SDVX_OVERLAY_BOTTOM:
|
|
this->init_pos.y = ImGui::GetIO().DisplaySize.y - this->init_size.y - padding;
|
|
break;
|
|
case games::sdvx::SDVX_OVERLAY_MIDDLE:
|
|
default:
|
|
this->init_pos.y = (ImGui::GetIO().DisplaySize.y / 2) - (this->init_size.y / 2);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SDVXSubScreen::touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) {
|
|
if (!this->get_active()) {
|
|
return;
|
|
}
|
|
|
|
// SDVX Valkyrie cab needs math to make things work
|
|
// what the game expects from touch screen:
|
|
// [1080, 0 1920, 1080]
|
|
// [0, 0 0, 1920]
|
|
|
|
// actual cursor position given by x_in (on the overlay, normalized):
|
|
// [0, 0 1, 0]
|
|
// [0, 1 1, 1]
|
|
|
|
// Basically, the game operates on rotated coordinates, but on top of that,
|
|
// it needs to be adjusted so they match up with the subscreen overlay.
|
|
|
|
// so the math is:
|
|
// Xin(0, 1) => Yout(0, 1920)
|
|
// Yin(0, 1) => Xout(1080, 0)
|
|
|
|
*x_out = ImGui::GetIO().DisplaySize.x * (1.f - xy_in.y);
|
|
*y_out = ImGui::GetIO().DisplaySize.y * xy_in.x;
|
|
}
|
|
}
|