mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-03 00:38:14 -07:00
gitadora: show LEFT / RIGHT screens on sub screen in landscape mode (#900)
## 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
This commit is contained in:
@@ -39,7 +39,7 @@ namespace games::gitadora {
|
|||||||
std::optional<socd::SocdAlgorithm> PICK_ALGO = socd::SocdAlgorithm::PreferRecent;
|
std::optional<socd::SocdAlgorithm> PICK_ALGO = socd::SocdAlgorithm::PreferRecent;
|
||||||
std::optional<uint8_t> ARENA_WINDOW_COUNT = std::nullopt;
|
std::optional<uint8_t> ARENA_WINDOW_COUNT = std::nullopt;
|
||||||
bool ARENA_TWO_HEAD_EXCLUSIVE = false;
|
bool ARENA_TWO_HEAD_EXCLUSIVE = false;
|
||||||
bool ARENA_SUBSCREEN_LANDSCAPE = false;
|
ArenaSubscreenLandscape ARENA_SUBSCREEN_LANDSCAPE = ArenaSubscreenLandscape::Off;
|
||||||
std::optional<std::string> ASIO_DRIVER = std::nullopt;
|
std::optional<std::string> ASIO_DRIVER = std::nullopt;
|
||||||
bool ALLOW_REALTEK_AUDIO = false;
|
bool ALLOW_REALTEK_AUDIO = false;
|
||||||
bool NATIVE_TOUCH = false;
|
bool NATIVE_TOUCH = false;
|
||||||
@@ -48,7 +48,7 @@ namespace games::gitadora {
|
|||||||
if (GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.has_value()) {
|
if (GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.has_value()) {
|
||||||
return GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value();
|
return GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value();
|
||||||
}
|
}
|
||||||
if (ARENA_SUBSCREEN_LANDSCAPE) {
|
if (arena_subscreen_landscape()) {
|
||||||
return { ARENA_SUBSCREEN_LANDSCAPE_WIDTH, ARENA_SUBSCREEN_LANDSCAPE_HEIGHT };
|
return { ARENA_SUBSCREEN_LANDSCAPE_WIDTH, ARENA_SUBSCREEN_LANDSCAPE_HEIGHT };
|
||||||
}
|
}
|
||||||
return { ARENA_SUBSCREEN_WIDTH, ARENA_SUBSCREEN_HEIGHT };
|
return { ARENA_SUBSCREEN_WIDTH, ARENA_SUBSCREEN_HEIGHT };
|
||||||
@@ -372,11 +372,11 @@ namespace games::gitadora {
|
|||||||
"arena model: unsupported window count: {}", count);
|
"arena model: unsupported window count: {}", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARENA_SUBSCREEN_LANDSCAPE && !ARENA_TWO_HEAD_EXCLUSIVE) {
|
if (arena_subscreen_landscape() && !ARENA_TWO_HEAD_EXCLUSIVE) {
|
||||||
log_warning(
|
log_warning(
|
||||||
"gitadora",
|
"gitadora",
|
||||||
"arena model: landscape subscreen needs full screen two-window mode, ignoring");
|
"arena model: landscape subscreen needs full screen two-window mode, ignoring");
|
||||||
ARENA_SUBSCREEN_LANDSCAPE = false;
|
ARENA_SUBSCREEN_LANDSCAPE = ArenaSubscreenLandscape::Off;
|
||||||
}
|
}
|
||||||
if (ARENA_TWO_HEAD_EXCLUSIVE) {
|
if (ARENA_TWO_HEAD_EXCLUSIVE) {
|
||||||
const auto [host_width, host_height] = arena_subscreen_host_size();
|
const auto [host_width, host_height] = arena_subscreen_host_size();
|
||||||
|
|||||||
@@ -12,6 +12,14 @@
|
|||||||
|
|
||||||
namespace games::gitadora {
|
namespace games::gitadora {
|
||||||
|
|
||||||
|
// what a landscape monitor driving the SMALL head does with the space beside the
|
||||||
|
// portrait subscreen image
|
||||||
|
enum class ArenaSubscreenLandscape {
|
||||||
|
Off, // SMALL head stays portrait
|
||||||
|
Small, // subscreen centered, the space either side stays black
|
||||||
|
All, // that space shows the LEFT and RIGHT heads instead
|
||||||
|
};
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
extern bool TWOCHANNEL;
|
extern bool TWOCHANNEL;
|
||||||
extern bool DISABLE_FRAME_LIMITER;
|
extern bool DISABLE_FRAME_LIMITER;
|
||||||
@@ -22,11 +30,19 @@ namespace games::gitadora {
|
|||||||
extern std::optional<socd::SocdAlgorithm> PICK_ALGO;
|
extern std::optional<socd::SocdAlgorithm> PICK_ALGO;
|
||||||
extern std::optional<uint8_t> ARENA_WINDOW_COUNT;
|
extern std::optional<uint8_t> ARENA_WINDOW_COUNT;
|
||||||
extern bool ARENA_TWO_HEAD_EXCLUSIVE;
|
extern bool ARENA_TWO_HEAD_EXCLUSIVE;
|
||||||
extern bool ARENA_SUBSCREEN_LANDSCAPE;
|
extern ArenaSubscreenLandscape ARENA_SUBSCREEN_LANDSCAPE;
|
||||||
extern std::optional<std::string> ASIO_DRIVER;
|
extern std::optional<std::string> ASIO_DRIVER;
|
||||||
extern bool ALLOW_REALTEK_AUDIO;
|
extern bool ALLOW_REALTEK_AUDIO;
|
||||||
extern bool NATIVE_TOUCH;
|
extern bool NATIVE_TOUCH;
|
||||||
|
|
||||||
|
static inline bool arena_subscreen_landscape() {
|
||||||
|
return ARENA_SUBSCREEN_LANDSCAPE != ArenaSubscreenLandscape::Off;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool arena_subscreen_shows_sides() {
|
||||||
|
return ARENA_SUBSCREEN_LANDSCAPE == ArenaSubscreenLandscape::All;
|
||||||
|
}
|
||||||
|
|
||||||
// arena SMALL subscreen (touch panel) resolution
|
// arena SMALL subscreen (touch panel) resolution
|
||||||
static constexpr int ARENA_SUBSCREEN_WIDTH = 800;
|
static constexpr int ARENA_SUBSCREEN_WIDTH = 800;
|
||||||
static constexpr int ARENA_SUBSCREEN_HEIGHT = 1280;
|
static constexpr int ARENA_SUBSCREEN_HEIGHT = 1280;
|
||||||
|
|||||||
@@ -670,7 +670,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::Present(
|
|||||||
// an adapter group device presents every head at once, so the SMALL head has to be
|
// an adapter group device presents every head at once, so the SMALL head has to be
|
||||||
// composed here as well as in its own swap chain
|
// composed here as well as in its own swap chain
|
||||||
if (gfdm_small_head.scaled()) {
|
if (gfdm_small_head.scaled()) {
|
||||||
gfdm_small_head.compose(pReal);
|
gfdm_small_head.compose(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_RESULT(pReal->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion));
|
CHECK_RESULT(pReal->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion));
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "games/gitadora/gitadora.h"
|
#include "games/gitadora/gitadora.h"
|
||||||
@@ -739,15 +740,118 @@ void GfdmSmallHead::release() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT GfdmSmallHead::compose(IDirect3DDevice9 *device) {
|
// largest centered rect inside bounds that keeps the source's aspect ratio
|
||||||
|
static RECT gfdm_fit_centered(const RECT &bounds, LONG source_width, LONG source_height) {
|
||||||
|
const LONG bounds_width = bounds.right - bounds.left;
|
||||||
|
const LONG bounds_height = bounds.bottom - bounds.top;
|
||||||
|
if (bounds_width <= 0 || bounds_height <= 0 || source_width <= 0 || source_height <= 0) {
|
||||||
|
return RECT {};
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG width = MulDiv(bounds_height, source_width, source_height);
|
||||||
|
LONG height = bounds_height;
|
||||||
|
if (width > bounds_width) {
|
||||||
|
width = bounds_width;
|
||||||
|
height = MulDiv(bounds_width, source_height, source_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LONG left = bounds.left + (bounds_width - width) / 2;
|
||||||
|
const LONG top = bounds.top + (bounds_height - height) / 2;
|
||||||
|
return RECT { left, top, left + width, top + height };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfdm_compose_side_heads(
|
||||||
|
WrappedIDirect3DDevice9 *device,
|
||||||
|
IDirect3DSurface9 *head,
|
||||||
|
LONG host_width,
|
||||||
|
LONG host_height,
|
||||||
|
const RECT &content)
|
||||||
|
{
|
||||||
|
if (!games::gitadora::arena_subscreen_shows_sides()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RECT bars[2] = {
|
||||||
|
{ 0, 0, content.left, host_height },
|
||||||
|
{ content.right, 0, host_width, host_height },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (UINT swapchain = 1; swapchain < GFDM_LOGICAL_HEAD_COUNT; swapchain++) {
|
||||||
|
if (!device->is_gfdm_logical_side_swapchain(swapchain)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing has been drawn yet if the game never asked for this head's back buffer
|
||||||
|
const auto *chain = device->fake_sub_swapchain[
|
||||||
|
device->gfdm_hidden_side_swapchain_slot(swapchain)];
|
||||||
|
if (chain == nullptr || chain->render_targets.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the head's own window is the only thing that says which side it is, so an
|
||||||
|
// unnamed one is left out rather than guessed at and possibly mirrored
|
||||||
|
const char *name = graphics_gitadora_window_name(
|
||||||
|
device->gfdm_logical_group_parameters[swapchain].hDeviceWindow);
|
||||||
|
const bool named_left = name != nullptr && strcmp(name, "LEFT") == 0;
|
||||||
|
const bool named_right = name != nullptr && strcmp(name, "RIGHT") == 0;
|
||||||
|
if (!named_left && !named_right) {
|
||||||
|
static std::once_flag warned;
|
||||||
|
std::call_once(warned, [] {
|
||||||
|
log_warning(
|
||||||
|
"graphics::d3d9",
|
||||||
|
"two-head exclusive: a side head has no LEFT or RIGHT window, "
|
||||||
|
"leaving its bar black");
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RECT &bar = bars[named_left ? 0 : 1];
|
||||||
|
if (bar.right <= bar.left) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirect3DSurface9 *source = chain->render_targets[0];
|
||||||
|
D3DSURFACE_DESC source_desc {};
|
||||||
|
if (FAILED(source->GetDesc(&source_desc))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RECT target = gfdm_fit_centered(
|
||||||
|
bar,
|
||||||
|
static_cast<LONG>(source_desc.Width),
|
||||||
|
static_cast<LONG>(source_desc.Height));
|
||||||
|
const HRESULT result = device->pReal->StretchRect(
|
||||||
|
source,
|
||||||
|
nullptr,
|
||||||
|
head,
|
||||||
|
&target,
|
||||||
|
D3DTEXF_LINEAR);
|
||||||
|
if (FAILED(result)) {
|
||||||
|
static std::once_flag warned;
|
||||||
|
std::call_once(warned, [result] {
|
||||||
|
log_warning(
|
||||||
|
"graphics::d3d9",
|
||||||
|
"two-head exclusive: could not draw a side head into the bars, hr={}",
|
||||||
|
FMT_HRESULT(result));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT GfdmSmallHead::compose(WrappedIDirect3DDevice9 *device) {
|
||||||
|
if (device == nullptr || device->pReal == nullptr) {
|
||||||
|
return D3DERR_INVALIDCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirect3DDevice9 *real = device->pReal;
|
||||||
IDirect3DSurface9 *proxy = nullptr;
|
IDirect3DSurface9 *proxy = nullptr;
|
||||||
HRESULT result = backbuffer(device, &proxy);
|
HRESULT result = backbuffer(real, &proxy);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DSurface9 *head = nullptr;
|
IDirect3DSurface9 *head = nullptr;
|
||||||
result = device->GetBackBuffer(
|
result = real->GetBackBuffer(
|
||||||
GFDM_NATIVE_SMALL_SWAPCHAIN,
|
GFDM_NATIVE_SMALL_SWAPCHAIN,
|
||||||
0,
|
0,
|
||||||
D3DBACKBUFFER_TYPE_MONO,
|
D3DBACKBUFFER_TYPE_MONO,
|
||||||
@@ -760,14 +864,18 @@ HRESULT GfdmSmallHead::compose(IDirect3DDevice9 *device) {
|
|||||||
D3DSURFACE_DESC desc {};
|
D3DSURFACE_DESC desc {};
|
||||||
result = head->GetDesc(&desc);
|
result = head->GetDesc(&desc);
|
||||||
if (SUCCEEDED(result)) {
|
if (SUCCEEDED(result)) {
|
||||||
|
const auto host_width = static_cast<LONG>(desc.Width);
|
||||||
|
const auto host_height = static_cast<LONG>(desc.Height);
|
||||||
const RECT content = games::gitadora::arena_subscreen_content_rect(
|
const RECT content = games::gitadora::arena_subscreen_content_rect(
|
||||||
static_cast<LONG>(desc.Width),
|
host_width,
|
||||||
static_cast<LONG>(desc.Height));
|
host_height);
|
||||||
|
|
||||||
// discard swap effect leaves the whole head undefined every frame, so the bars
|
// discard swap effect leaves the whole head undefined every frame, so the bars
|
||||||
// have to be repainted along with the image
|
// have to be repainted along with the image
|
||||||
device->ColorFill(head, nullptr, D3DCOLOR_XRGB(0, 0, 0));
|
real->ColorFill(head, nullptr, D3DCOLOR_XRGB(0, 0, 0));
|
||||||
result = device->StretchRect(proxy, nullptr, head, &content, D3DTEXF_LINEAR);
|
result = real->StretchRect(proxy, nullptr, head, &content, D3DTEXF_LINEAR);
|
||||||
|
|
||||||
|
gfdm_compose_side_heads(device, head, host_width, host_height, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
head->Release();
|
head->Release();
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ inline constexpr UINT GFDM_SMALL_HEIGHT = games::gitadora::ARENA_SUBSCREEN_HEIGH
|
|||||||
inline constexpr UINT GFDM_LOGICAL_HEAD_COUNT = 4;
|
inline constexpr UINT GFDM_LOGICAL_HEAD_COUNT = 4;
|
||||||
inline constexpr UINT GFDM_NATIVE_SMALL_SWAPCHAIN = 1;
|
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
|
// 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
|
// 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.
|
// nothing until resolve() finds a head that is not the panel size.
|
||||||
@@ -27,7 +29,7 @@ struct GfdmSmallHead {
|
|||||||
bool scaled() const { return active; }
|
bool scaled() const { return active; }
|
||||||
|
|
||||||
HRESULT backbuffer(IDirect3DDevice9 *device, IDirect3DSurface9 **out);
|
HRESULT backbuffer(IDirect3DDevice9 *device, IDirect3DSurface9 **out);
|
||||||
HRESULT compose(IDirect3DDevice9 *device);
|
HRESULT compose(WrappedIDirect3DDevice9 *device);
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
// the game only ever sees the portrait size it asked for
|
// the game only ever sees the portrait size it asked for
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3DSwapChain9::Present(const RECT *pSourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scales_small_head(this)) {
|
if (scales_small_head(this)) {
|
||||||
pDev->gfdm_small_head.compose(pDev->pReal);
|
pDev->gfdm_small_head.compose(pDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT result = pReal->Present(
|
HRESULT result = pReal->Present(
|
||||||
|
|||||||
@@ -233,6 +233,10 @@ bool graphics_gitadora_has_dedicated_subscreen() {
|
|||||||
return GFDM_SUBSCREEN_WINDOW != nullptr;
|
return GFDM_SUBSCREEN_WINDOW != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *graphics_gitadora_window_name(HWND hWnd) {
|
||||||
|
return gitadora_window_name_for_hwnd(hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
bool graphics_gitadora_prepare_two_head_device_window(
|
bool graphics_gitadora_prepare_two_head_device_window(
|
||||||
HWND hWnd, HMONITOR target_monitor, UINT desired_width, UINT desired_height) {
|
HWND hWnd, HMONITOR target_monitor, UINT desired_width, UINT desired_height) {
|
||||||
if (hWnd == nullptr || !IsWindow(hWnd)) {
|
if (hWnd == nullptr || !IsWindow(hWnd)) {
|
||||||
|
|||||||
@@ -122,6 +122,9 @@ extern bool D3D9_DEVICE_HOOK_DISABLE;
|
|||||||
void graphics_init();
|
void graphics_init();
|
||||||
void graphics_hook_window(HWND hWnd, D3DPRESENT_PARAMETERS *pPresentationParameters);
|
void graphics_hook_window(HWND hWnd, D3DPRESENT_PARAMETERS *pPresentationParameters);
|
||||||
bool graphics_gitadora_has_dedicated_subscreen();
|
bool graphics_gitadora_has_dedicated_subscreen();
|
||||||
|
|
||||||
|
// "GITADORA", "LEFT", "RIGHT", "SMALL", or nullptr for anything else
|
||||||
|
const char *graphics_gitadora_window_name(HWND hWnd);
|
||||||
// The native GITADORA two-head D3D9 group uses the game's named SMALL
|
// The native GITADORA two-head D3D9 group uses the game's named SMALL
|
||||||
// device window for the native physical SMALL head. The game requests
|
// device window for the native physical SMALL head. The game requests
|
||||||
// D3DCREATE_NOWINDOWCHANGES, so this host must be made borderless and sized
|
// D3DCREATE_NOWINDOWCHANGES, so this host must be made borderless and sized
|
||||||
|
|||||||
@@ -671,6 +671,16 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gitadora arena sub layout
|
||||||
|
if (options[launcher::Options::GitaDoraArenaSubLayout].is_active()) {
|
||||||
|
const auto text = options[launcher::Options::GitaDoraArenaSubLayout].value_text();
|
||||||
|
if (text == "landscape") {
|
||||||
|
games::gitadora::ARENA_SUBSCREEN_LANDSCAPE = games::gitadora::ArenaSubscreenLandscape::Small;
|
||||||
|
} else if (text == "combine") {
|
||||||
|
games::gitadora::ARENA_SUBSCREEN_LANDSCAPE = games::gitadora::ArenaSubscreenLandscape::All;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options[launcher::Options::GitaDoraWailHold].is_active()) {
|
if (options[launcher::Options::GitaDoraWailHold].is_active()) {
|
||||||
socd::TILT_HOLD_MS = options[launcher::Options::GitaDoraWailHold].value_uint32();
|
socd::TILT_HOLD_MS = options[launcher::Options::GitaDoraWailHold].value_uint32();
|
||||||
}
|
}
|
||||||
@@ -693,9 +703,6 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
if (options[launcher::Options::GitaDoraArenaRealtekAccess].value_bool()) {
|
if (options[launcher::Options::GitaDoraArenaRealtekAccess].value_bool()) {
|
||||||
games::gitadora::ALLOW_REALTEK_AUDIO = true;
|
games::gitadora::ALLOW_REALTEK_AUDIO = true;
|
||||||
}
|
}
|
||||||
if (options[launcher::Options::GitaDoraSubscreenLandscape].value_bool()) {
|
|
||||||
games::gitadora::ARENA_SUBSCREEN_LANDSCAPE = true;
|
|
||||||
}
|
|
||||||
if (options[launcher::Options::LoadNostalgiaModule].value_bool()) {
|
if (options[launcher::Options::LoadNostalgiaModule].value_bool()) {
|
||||||
attach_nostalgia = true;
|
attach_nostalgia = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1330,6 +1330,25 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
},
|
},
|
||||||
.quick_setting_category = "Game",
|
.quick_setting_category = "Game",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// GitaDoraArenaSubLayout
|
||||||
|
.title = "GitaDora Arena Subscreen Layout (EXPERIMENTAL)",
|
||||||
|
.name = "gdasublayout",
|
||||||
|
.desc = "For Arena Model full screen two-window mode: select the image layout on the second monitor.\n\n"
|
||||||
|
"portrait (default): default subscreen @ 800x1280\n\n"
|
||||||
|
"landscape: pillarboxed subscreen @ 1920x1080\n\n"
|
||||||
|
"combine: LEFT + SMALL + RIGHT screens side by side @ 1920x1080\n\n"
|
||||||
|
"For landscape and combine, -forceressub can be used to override the resolution.",
|
||||||
|
.type = OptionType::Enum,
|
||||||
|
.game_name = "GitaDora",
|
||||||
|
.category = "Game Options",
|
||||||
|
.elements = {
|
||||||
|
{"portrait", ""},
|
||||||
|
{"landscape", ""},
|
||||||
|
{"combine", ""}
|
||||||
|
},
|
||||||
|
.quick_setting_category = "Game",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// GitaDoraArenaAsioDriver
|
// GitaDoraArenaAsioDriver
|
||||||
.title = "GitaDora Arena ASIO driver",
|
.title = "GitaDora Arena ASIO driver",
|
||||||
@@ -3425,19 +3444,6 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.type = OptionType::Bool,
|
.type = OptionType::Bool,
|
||||||
.category = "General Overlay",
|
.category = "General Overlay",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
// GitaDoraSubscreenLandscape
|
|
||||||
.title = "GitaDora Arena Landscape Subscreen (EXPERIMENTAL)",
|
|
||||||
.name = "gdsublandscape",
|
|
||||||
.desc = "For Arena Model full screen two-window mode: drive the SMALL touch subscreen "
|
|
||||||
"with a landscape monitor instead of a portrait one.\n\n"
|
|
||||||
"The portrait image is centered and black bars fill the space on either side.\n\n"
|
|
||||||
"Launches at 1920x1080; use -forceressub if you need a different resolution.",
|
|
||||||
.type = OptionType::Bool,
|
|
||||||
.game_name = "GitaDora",
|
|
||||||
.category = "Game Options",
|
|
||||||
.quick_setting_category = "Game",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<std::string> &launcher::get_categories(Options::OptionsCategory category) {
|
const std::vector<std::string> &launcher::get_categories(Options::OptionsCategory category) {
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ namespace launcher {
|
|||||||
GitaDoraSubOverlaySize,
|
GitaDoraSubOverlaySize,
|
||||||
GitaDoraArenaSingleWindow,
|
GitaDoraArenaSingleWindow,
|
||||||
GitaDoraArenaWindowLayout,
|
GitaDoraArenaWindowLayout,
|
||||||
|
GitaDoraArenaSubLayout,
|
||||||
GitaDoraArenaAsioDriver,
|
GitaDoraArenaAsioDriver,
|
||||||
GitaDoraArenaRealtekAccess,
|
GitaDoraArenaRealtekAccess,
|
||||||
LoadJubeatModule,
|
LoadJubeatModule,
|
||||||
@@ -324,7 +325,6 @@ namespace launcher {
|
|||||||
OBSWebSocketDebug,
|
OBSWebSocketDebug,
|
||||||
ScreenshotIncludeOverlay,
|
ScreenshotIncludeOverlay,
|
||||||
ScreenshotSubscreens,
|
ScreenshotSubscreens,
|
||||||
GitaDoraSubscreenLandscape
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OptionsCategory {
|
enum class OptionsCategory {
|
||||||
|
|||||||
Reference in New Issue
Block a user