mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-07 10:38:11 -07:00
0169fe1e31
## Link to GitHub Issue or related Pull Request, if one exists Continues #899 ## Description of change #899 added the ability to display the gitadora subscreen in lanscape mode with black bars on the side. With the new option the black bars can instead display the LEFT / RIGHT screens, completing the two-monitor full screen use case for arena model. ## Testing
115 lines
4.5 KiB
C++
115 lines
4.5 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
|
|
#include <d3d9.h>
|
|
|
|
#include "games/gitadora/gitadora.h"
|
|
|
|
inline constexpr UINT GFDM_SIDE_WIDTH = 1080;
|
|
inline constexpr UINT GFDM_SIDE_HEIGHT = 1920;
|
|
inline constexpr UINT GFDM_SMALL_WIDTH = games::gitadora::ARENA_SUBSCREEN_WIDTH;
|
|
inline constexpr UINT GFDM_SMALL_HEIGHT = games::gitadora::ARENA_SUBSCREEN_HEIGHT;
|
|
inline constexpr UINT GFDM_LOGICAL_HEAD_COUNT = 4;
|
|
inline constexpr UINT GFDM_NATIVE_SMALL_SWAPCHAIN = 1;
|
|
|
|
struct WrappedIDirect3DDevice9;
|
|
|
|
// Owns the portrait surface the game draws into while the SMALL head is scanned out at a
|
|
// different resolution, and composes it onto the real head. Allocates nothing and reports
|
|
// nothing until resolve() finds a head that is not the panel size.
|
|
struct GfdmSmallHead {
|
|
GfdmSmallHead() = default;
|
|
~GfdmSmallHead() { release(); }
|
|
GfdmSmallHead(const GfdmSmallHead &) = delete;
|
|
GfdmSmallHead &operator=(const GfdmSmallHead &) = delete;
|
|
|
|
// settled with the device, so it cannot change under the game mid-session
|
|
void resolve(const D3DPRESENT_PARAMETERS *logical_small_parameters);
|
|
bool scaled() const { return active; }
|
|
|
|
HRESULT backbuffer(IDirect3DDevice9 *device, IDirect3DSurface9 **out);
|
|
HRESULT compose(WrappedIDirect3DDevice9 *device);
|
|
void release();
|
|
|
|
// the game only ever sees the portrait size it asked for
|
|
void apply_logical_size(UINT *width, UINT *height) const;
|
|
|
|
private:
|
|
bool active = false;
|
|
D3DFORMAT format = D3DFMT_X8R8G8B8;
|
|
D3DMULTISAMPLE_TYPE multisample = D3DMULTISAMPLE_NONE;
|
|
DWORD multisample_quality = 0;
|
|
IDirect3DSurface9 *surface = nullptr;
|
|
};
|
|
|
|
struct GfdmTwoHeadDeviceState {
|
|
explicit GfdmTwoHeadDeviceState(
|
|
D3DPRESENT_PARAMETERS *presentation_parameters,
|
|
D3DDISPLAYMODEEX *fullscreen_display_modes,
|
|
UINT logical_small_swapchain = 2)
|
|
: presentation_parameters(presentation_parameters),
|
|
fullscreen_display_modes(fullscreen_display_modes),
|
|
logical_small_swapchain(logical_small_swapchain) {}
|
|
|
|
void use_native_parameters() {
|
|
presentation_parameters = native_presentation_parameters.data();
|
|
fullscreen_display_modes = source_fullscreen_display_modes != nullptr
|
|
? native_fullscreen_display_modes.data()
|
|
: nullptr;
|
|
}
|
|
|
|
std::array<D3DPRESENT_PARAMETERS, 2> native_presentation_parameters {};
|
|
std::array<D3DDISPLAYMODEEX, 2> native_fullscreen_display_modes {};
|
|
std::array<D3DPRESENT_PARAMETERS, 2> recovery_parameters {};
|
|
std::array<D3DDISPLAYMODEEX, 2> recovery_modes {};
|
|
D3DPRESENT_PARAMETERS *presentation_parameters;
|
|
D3DDISPLAYMODEEX *fullscreen_display_modes;
|
|
D3DDISPLAYMODEEX *const source_fullscreen_display_modes = fullscreen_display_modes;
|
|
UINT logical_small_swapchain;
|
|
bool recovery_candidate = false;
|
|
};
|
|
|
|
bool gfdm_two_head_exclusive();
|
|
void gfdm_publish_two_head_parameters(
|
|
D3DPRESENT_PARAMETERS *logical_presentation_parameters,
|
|
D3DDISPLAYMODEEX *logical_fullscreen_display_modes,
|
|
const GfdmTwoHeadDeviceState &state);
|
|
bool is_fake_subscreen_adapter(UINT adapter);
|
|
void get_fake_subscreen_display_mode(UINT adapter, D3DDISPLAYMODE *mode);
|
|
void get_fake_subscreen_display_mode_ex(UINT adapter, D3DDISPLAYMODEEX *mode);
|
|
|
|
HRESULT graphics_d3d9_gfdm_select_two_head_group_parameters(
|
|
const D3DPRESENT_PARAMETERS *logical_presentation_parameters,
|
|
const D3DDISPLAYMODEEX *logical_fullscreen_display_modes,
|
|
D3DPRESENT_PARAMETERS *native_presentation_parameters,
|
|
D3DDISPLAYMODEEX *native_fullscreen_display_modes,
|
|
UINT *logical_small_swapchain,
|
|
const char *operation);
|
|
|
|
HRESULT graphics_d3d9_gfdm_remap_two_head_group_parameters(
|
|
D3DPRESENT_PARAMETERS *presentation_parameters,
|
|
D3DDISPLAYMODEEX *fullscreen_display_modes,
|
|
const char *operation);
|
|
|
|
void graphics_d3d9_gfdm_align_two_head_refresh_to_desktop(
|
|
IDirect3D9Ex *d3d,
|
|
UINT master_adapter,
|
|
D3DPRESENT_PARAMETERS *presentation_parameters,
|
|
D3DDISPLAYMODEEX *fullscreen_display_modes,
|
|
const char *operation);
|
|
|
|
HRESULT validate_gfdm_two_head_exclusive(
|
|
IDirect3D9 *d3d,
|
|
UINT adapter,
|
|
D3DDEVTYPE device_type,
|
|
DWORD behavior_flags,
|
|
const D3DPRESENT_PARAMETERS *presentation_parameters);
|
|
|
|
HRESULT graphics_d3d9_gfdm_recover_two_head_present_mode(
|
|
IDirect3D9Ex *d3d,
|
|
IDirect3DDevice9Ex *device,
|
|
UINT master_adapter,
|
|
const D3DPRESENT_PARAMETERS *desired_parameters,
|
|
const D3DDISPLAYMODEEX *desired_modes);
|