## Link to GitHub Issue, if one exists Fixes #276 ## Description of change Note: this change is not compatible with previous screen resize config; i.e., if you had the zoom setting dialed into a certain view, after this change it won't be the same area, so you'll have to set up a scene again. I think this is a worthwhile cost since the old logic is just broken in weird ways, and preserving old settings is really tedious math (for a feature that not many people use). Besides, this change will only use the new Scenes values from the JSON. Rewrite the DX9 image scaler logic. * Previously, the rendering surface was fixed at `4096*4096 px`. Now, this is relative to the backbuffer dimensions, which depends on the game & respects user provided `-forceres`. * Remove "center" option, make it the default. Above two changes fix the aspect ratio issue (scaling in portrait games not respecting screen ratio) and things breaking at higher res (1080p when zoomed out far enough, or when forced to run at 4k resolution for example) * Use `scenes` leaf of screen resize JSON config for Scene 1 as well, completely removing ourselves from being compatible with older spice2x versions for these values. * Add additional bounds check before calling `StretchRect` to avoid users getting stuck with a bad layout, which can kill performance. ## Compiling 🦾 ## Testing Tested 32 bit (popn / ddr), 64 bit (ldj), portrait and landscape modes (kfc)
93 lines
3.7 KiB
C++
93 lines
3.7 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 Sub Screen";
|
|
|
|
bool isValkyrieCabinetMode = avs::game::SPEC[0] == 'G' || avs::game::SPEC[0] == 'H';
|
|
if (!isValkyrieCabinetMode) {
|
|
this->disabled_message = "Valkyrie Model mode is not enabled!";
|
|
} else if (GRAPHICS_WINDOWED) {
|
|
if (GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
|
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.";
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|