mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
Image duplication for screen resize (#401)
## Link to GitHub Issue, if one exists #399 ## Description of change Add image duplication option to screen resize, allowing overflow images to wrap around the other side. ## Testing Tested with DDR, IIDX (windowed and full screen TDJ), SDVX (orientation swap)
This commit is contained in:
@@ -87,6 +87,10 @@ namespace cfg {
|
|||||||
load_float_value(doc, root + prefix + "scale_x", scene.scale_x);
|
load_float_value(doc, root + prefix + "scale_x", scene.scale_x);
|
||||||
load_float_value(doc, root + prefix + "scale_y", scene.scale_y);
|
load_float_value(doc, root + prefix + "scale_y", scene.scale_y);
|
||||||
load_bool_value(doc, root + prefix + "keep_aspect_ratio", scene.keep_aspect_ratio);
|
load_bool_value(doc, root + prefix + "keep_aspect_ratio", scene.keep_aspect_ratio);
|
||||||
|
|
||||||
|
int duplicate = 0;
|
||||||
|
load_int_value(doc, root + prefix + "duplicate", duplicate);
|
||||||
|
scene.duplicate = static_cast<cfg::ScreenDuplicateMode>(duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// windowed settings are always under game settings
|
// windowed settings are always under game settings
|
||||||
@@ -201,6 +205,7 @@ namespace cfg {
|
|||||||
rapidjson::Pointer(root + prefix + "scale_x").Set(doc, scene.scale_x);
|
rapidjson::Pointer(root + prefix + "scale_x").Set(doc, scene.scale_x);
|
||||||
rapidjson::Pointer(root + prefix + "scale_y").Set(doc, scene.scale_y);
|
rapidjson::Pointer(root + prefix + "scale_y").Set(doc, scene.scale_y);
|
||||||
rapidjson::Pointer(root + prefix + "keep_aspect_ratio").Set(doc, scene.keep_aspect_ratio);
|
rapidjson::Pointer(root + prefix + "keep_aspect_ratio").Set(doc, scene.keep_aspect_ratio);
|
||||||
|
rapidjson::Pointer(root + prefix + "duplicate").Set(doc, scene.duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// windowed mode settings
|
// windowed mode settings
|
||||||
|
|||||||
@@ -14,12 +14,19 @@ namespace cfg {
|
|||||||
ResizableFrame = 2
|
ResizableFrame = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ScreenDuplicateMode {
|
||||||
|
None = 0,
|
||||||
|
CopyLeft = 1,
|
||||||
|
CopyRight = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct fullscreen_setting {
|
struct fullscreen_setting {
|
||||||
int offset_x = 0;
|
int offset_x = 0;
|
||||||
int offset_y = 0;
|
int offset_y = 0;
|
||||||
float scale_x = 1.0;
|
float scale_x = 1.0;
|
||||||
float scale_y = 1.0;
|
float scale_y = 1.0;
|
||||||
bool keep_aspect_ratio = true;
|
bool keep_aspect_ratio = true;
|
||||||
|
ScreenDuplicateMode duplicate = ScreenDuplicateMode::None;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::optional<std::string> SCREEN_RESIZE_CFG_PATH_OVERRIDE;
|
extern std::optional<std::string> SCREEN_RESIZE_CFG_PATH_OVERRIDE;
|
||||||
|
|||||||
@@ -734,6 +734,16 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
|||||||
const int w = param.BackBufferWidth;
|
const int w = param.BackBufferWidth;
|
||||||
const int h = param.BackBufferHeight;
|
const int h = param.BackBufferHeight;
|
||||||
|
|
||||||
|
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||||
|
RECT rect {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(LONG)topSurface_width,
|
||||||
|
(LONG)topSurface_height,
|
||||||
|
};
|
||||||
|
pReal->ColorFill(topSurface, &rect, D3DCOLOR_XRGB(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
topSurface->LockRect(&rect, NULL, D3DLOCK_DONOTWAIT);
|
topSurface->LockRect(&rect, NULL, D3DLOCK_DONOTWAIT);
|
||||||
@@ -750,6 +760,7 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
|||||||
(LONG)(rectLeft + w),
|
(LONG)(rectLeft + w),
|
||||||
(LONG)(rectTop + h),
|
(LONG)(rectTop + h),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
||||||
originRect.left = (topSurface_width / 2) - (GRAPHICS_FS_ORIGINAL_WIDTH / 2);
|
originRect.left = (topSurface_width / 2) - (GRAPHICS_FS_ORIGINAL_WIDTH / 2);
|
||||||
originRect.top = (topSurface_height / 2) - (GRAPHICS_FS_ORIGINAL_HEIGHT / 2);
|
originRect.top = (topSurface_height / 2) - (GRAPHICS_FS_ORIGINAL_HEIGHT / 2);
|
||||||
@@ -757,6 +768,21 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
|||||||
originRect.bottom = originRect.top + GRAPHICS_FS_ORIGINAL_HEIGHT;
|
originRect.bottom = originRect.top + GRAPHICS_FS_ORIGINAL_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool duplicate = false;
|
||||||
|
RECT originRect2 = originRect;
|
||||||
|
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||||
|
auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene];
|
||||||
|
if (scene.duplicate == cfg::ScreenDuplicateMode::CopyLeft) {
|
||||||
|
duplicate = true;
|
||||||
|
originRect2.right = originRect.left;
|
||||||
|
originRect2.left = (LONG)(originRect2.left - (originRect.right - originRect.left));
|
||||||
|
} else if (scene.duplicate == cfg::ScreenDuplicateMode::CopyRight) {
|
||||||
|
duplicate = true;
|
||||||
|
originRect2.left = originRect.right;
|
||||||
|
originRect2.right = (LONG)(originRect2.left + (originRect.right - originRect.left));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// log_misc(
|
// log_misc(
|
||||||
// "graphics::d3d9", "originRect: {} {} {} {}",
|
// "graphics::d3d9", "originRect: {} {} {} {}",
|
||||||
// originRect.left, originRect.top, originRect.right, originRect.bottom);
|
// originRect.left, originRect.top, originRect.right, originRect.bottom);
|
||||||
@@ -768,9 +794,21 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
|||||||
if (hr != D3D_OK) {
|
if (hr != D3D_OK) {
|
||||||
log_warning(
|
log_warning(
|
||||||
"graphics::d3d9",
|
"graphics::d3d9",
|
||||||
"SurfaceHook - StretchRect backbuffer failed, rect: {} {} {} {}",
|
"SurfaceHook - StretchRect backbuffer failed for main image, rect: {} {} {} {}",
|
||||||
originRect.left, originRect.top, originRect.right, originRect.bottom);
|
originRect.left, originRect.top, originRect.right, originRect.bottom);
|
||||||
}
|
}
|
||||||
|
if (duplicate) {
|
||||||
|
hr = pReal->StretchRect(
|
||||||
|
backbuffer, nullptr,
|
||||||
|
topSurface, &originRect2,
|
||||||
|
D3DTEXF_LINEAR);
|
||||||
|
if (hr != D3D_OK) {
|
||||||
|
log_warning(
|
||||||
|
"graphics::d3d9",
|
||||||
|
"SurfaceHook - StretchRect backbuffer failed for the duplicate, rect: {} {} {} {}",
|
||||||
|
originRect2.left, originRect2.top, originRect2.right, originRect2.bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
topSurface->UnlockRect();
|
topSurface->UnlockRect();
|
||||||
|
|
||||||
// phase 2 - viewport calculation - do the actual zoom / offset math
|
// phase 2 - viewport calculation - do the actual zoom / offset math
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ namespace overlay::windows {
|
|||||||
scene.offset_y = 0;
|
scene.offset_y = 0;
|
||||||
scene.scale_x = 1.f;
|
scene.scale_x = 1.f;
|
||||||
scene.scale_y = 1.f;
|
scene.scale_y = 1.f;
|
||||||
|
scene.duplicate = cfg::ScreenDuplicateMode::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg::SCREENRESIZE->enable_window_resize = false;
|
cfg::SCREENRESIZE->enable_window_resize = false;
|
||||||
@@ -149,6 +150,17 @@ namespace overlay::windows {
|
|||||||
ImGui::HelpMarker("Hint: ctrl + click on the slider to type in a numeric value.");
|
ImGui::HelpMarker("Hint: ctrl + click on the slider to type in a numeric value.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* dupe_items[] = { "None", "Copy Left", "Copy Right" };
|
||||||
|
ImGui::Combo(
|
||||||
|
"Duplicate",
|
||||||
|
reinterpret_cast<int *>(&scene.duplicate),
|
||||||
|
dupe_items,
|
||||||
|
ARRAYSIZE(dupe_items));
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::HelpMarker(
|
||||||
|
"Show an identical copy of the image on the left or right, allowing you to achieve "
|
||||||
|
"wrap-around effect when an offset is set.");
|
||||||
|
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user