Multiple "scenes" for screen resize (#270)

## Link to GitHub Issue, if one exists
Fixes #263 

## Description of change
Add "scenes" to screen resize.

* UI changes - F11 menu now has a "scene switcher" for `Scene 1/2/3/4`.
Clean up other UI bits.
* Add hotkeys for `Screen Resize Scene 1`, `Screen Resize 2`, and so on.
* Detect hot key and trigger resizes.
* Add additional objects to screen_resize.json for saving and loading
the new scene settings.
* Existing screen resize data is backwards compatible (can be
loaded/saved to JSON), and is treated as `Scene 1`.
* Add API endpoint for `Resize`, allow toggling resize on/off, switching
active scene
* Add Python wrapper. Did not bother with the other wrappers (Dart, C++,
etc)...

## Compiling
🥇 

## Testing
Still testing, but seems to work fine for TDJ.
This commit is contained in:
bicarus-dev
2025-03-21 21:52:47 -07:00
committed by GitHub
parent e0dd371d61
commit b267ad09ac
15 changed files with 300 additions and 46 deletions
+1
View File
@@ -302,6 +302,7 @@ set(SOURCE_FILES ${SOURCE_FILES}
api/modules/drs.cpp api/modules/drs.cpp
api/modules/lcd.cpp api/modules/lcd.cpp
api/modules/ddr.cpp api/modules/ddr.cpp
api/modules/resize.cpp
# avs # avs
avs/core.cpp avs/core.cpp
+6
View File
@@ -246,6 +246,12 @@ which also means that your hex edits are applicable directly.
- info() - info()
- returns information about the serial LCD controller some games use - returns information about the serial LCD controller some games use
#### Resize
- image_resize_enable(enable: bool)
- enables or disables image resize state
- image_resize_set_scene(scene: int)
- sets the active scene for image resize state; set to 0 to disable resize
## License ## License
Unless otherwise noted, all files are licensed under the GPLv3. Unless otherwise noted, all files are licensed under the GPLv3.
See the LICENSE file for the full license text. See the LICENSE file for the full license text.
+2
View File
@@ -27,6 +27,7 @@
#include "modules/lights.h" #include "modules/lights.h"
#include "modules/memory.h" #include "modules/memory.h"
#include "modules/touch.h" #include "modules/touch.h"
#include "modules/resize.h"
#include "request.h" #include "request.h"
#include "response.h" #include "response.h"
@@ -403,6 +404,7 @@ void Controller::init_state(api::ClientState *state) {
state->modules.push_back(new modules::Lights()); state->modules.push_back(new modules::Lights());
state->modules.push_back(new modules::Memory()); state->modules.push_back(new modules::Memory());
state->modules.push_back(new modules::Touch()); state->modules.push_back(new modules::Touch());
state->modules.push_back(new modules::Resize());
} }
void Controller::free_state(api::ClientState *state) { void Controller::free_state(api::ClientState *state) {
+53
View File
@@ -0,0 +1,53 @@
#include "resize.h"
#include "external/rapidjson/document.h"
#include "cfg/screen_resize.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
static thread_local std::vector<uint8_t> CAPTURE_BUFFER;
Resize::Resize() : Module("resize") {
functions["image_resize_enable"] = std::bind(&Resize::image_resize_enable, this, _1, _2);
functions["image_resize_set_scene"] = std::bind(&Resize::image_resize_set_scene, this, _1, _2);
}
/**
* image_resize_enable(enable: bool)
*/
void Resize::image_resize_enable(Request &req, Response &res) {
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsBool()) {
return error_type(res, "enable", "bool");
}
cfg::SCREENRESIZE->enable_screen_resize = req.params[0].GetBool();
}
/**
* image_resize_set_scene(scene: int)
*/
void Resize::image_resize_set_scene(Request &req, Response &res) {
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsInt()) {
return error_type(res, "scene", "int");
}
const auto scene = req.params[0].GetInt();
if (scene < 0 || (int)std::size(cfg::SCREENRESIZE->scene_settings) < scene) {
return error(res, "invalid scene number");
}
if (scene == 0) {
cfg::SCREENRESIZE->enable_screen_resize = false;
} else {
cfg::SCREENRESIZE->enable_screen_resize = true;
cfg::SCREENRESIZE->screen_resize_current_scene = scene - 1;
}
}
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Resize : public Module {
public:
Resize();
private:
// function definitions
void image_resize_enable(Request &req, Response &res);
void image_resize_set_scene(Request &req, Response &res);
};
}
@@ -12,3 +12,4 @@ from .keypads import *
from .lights import * from .lights import *
from .memory import * from .memory import *
from .touch import * from .touch import *
from .resize import *
@@ -0,0 +1,12 @@
from .connection import Connection
from .request import Request
def image_resize_enable(con: Connection, enable: bool):
req = Request("resize", "image_resize_enable")
req.add_param(enable)
con.request(req)
def image_resize_set_scene(con: Connection, scene: int):
req = Request("resize", "image_resize_set_scene")
req.add_param(scene)
con.request(req)
@@ -397,6 +397,65 @@ class LightsTab(ttk.Frame):
# set text # set text
self.txt_lights.set_text(txt) self.txt_lights.set_text(txt)
class ResizeTab(ttk.Frame):
"""Resize tab."""
def __init__(self, app, parent, **kwargs):
# init frame
ttk.Frame.__init__(self, parent, **kwargs)
self.app = app
self.parent = parent
# scale grid
self.columnconfigure(0, weight=1)
# image resize
self.resize = ttk.Frame(self, padding=(8, 8, 8, 8))
self.resize.grid(row=0, column=0, sticky=tk.E+tk.W)
self.resize.columnconfigure(0, weight=1)
self.resize.columnconfigure(1, weight=1)
self.resize_lbl = ttk.Label(self.resize, text="Image Resize")
self.resize_lbl.grid(row=0, columnspan=2)
self.resize_off = ttk.Button(self.resize, text="Disable", command=self.action_resize_false)
self.resize_off.grid(row=2, column=0, sticky=NSEW, padx=2, pady=2)
self.resize_on = ttk.Button(self.resize, text="Enable", command=self.action_resize_on)
self.resize_on.grid(row=2, column=1, sticky=NSEW, padx=2, pady=2)
self.resize_scene_1 = ttk.Button(self.resize, text="Scene 1", command=self.action_resize_scene_1)
self.resize_scene_1.grid(row=3, column=0, sticky=NSEW, padx=2, pady=2)
self.resize_scene_2 = ttk.Button(self.resize, text="Scene 2", command=self.action_resize_scene_2)
self.resize_scene_2.grid(row=3, column=1, sticky=NSEW, padx=2, pady=2)
self.resize_scene_3 = ttk.Button(self.resize, text="Scene 3", command=self.action_resize_scene_3)
self.resize_scene_3.grid(row=4, column=0, sticky=NSEW, padx=2, pady=2)
self.resize_scene_4 = ttk.Button(self.resize, text="Scene 4", command=self.action_resize_scene_4)
self.resize_scene_4.grid(row=4, column=1, sticky=NSEW, padx=2, pady=2)
@api_action
def action_resize_on(self):
spiceapi.image_resize_enable(self.app.connection, True)
@api_action
def action_resize_false(self):
spiceapi.image_resize_enable(self.app.connection, False)
@api_action
def action_resize_scene_1(self):
spiceapi.image_resize_set_scene(self.app.connection, 1)
@api_action
def action_resize_scene_2(self):
spiceapi.image_resize_set_scene(self.app.connection, 2)
@api_action
def action_resize_scene_3(self):
spiceapi.image_resize_set_scene(self.app.connection, 3)
@api_action
def action_resize_scene_4(self):
spiceapi.image_resize_set_scene(self.app.connection, 4)
class MainApp(ttk.Frame): class MainApp(ttk.Frame):
"""The main application frame.""" """The main application frame."""
@@ -419,6 +478,8 @@ class MainApp(ttk.Frame):
self.tabs.add(self.tab_analogs, text="Analogs") self.tabs.add(self.tab_analogs, text="Analogs")
self.tab_lights = LightsTab(self, self.tabs) self.tab_lights = LightsTab(self, self.tabs)
self.tabs.add(self.tab_lights, text="Lights") self.tabs.add(self.tab_lights, text="Lights")
self.tab_resize = ResizeTab(self, self.tabs)
self.tabs.add(self.tab_resize, text="Resize")
self.tab_manual = ManualTab(self, self.tabs) self.tab_manual = ManualTab(self, self.tabs)
self.tabs.add(self.tab_manual, text="Manual") self.tabs.add(self.tab_manual, text="Manual")
self.tabs.pack(expand=True, fill=tk.BOTH) self.tabs.pack(expand=True, fill=tk.BOTH)
+27 -12
View File
@@ -76,14 +76,22 @@ namespace cfg {
eamuse_get_game(), eamuse_get_game(),
use_game_setting, use_game_setting,
root); root);
load_int_value(doc, root + "offset_x", this->offset_x);
load_int_value(doc, root + "offset_y", this->offset_y);
load_float_value(doc, root + "scale_x", this->scale_x);
load_float_value(doc, root + "scale_y", this->scale_y);
load_bool_value(doc, root + "enable_screen_resize", this->enable_screen_resize); load_bool_value(doc, root + "enable_screen_resize", this->enable_screen_resize);
load_bool_value(doc, root + "enable_linear_filter", this->enable_linear_filter); load_bool_value(doc, root + "enable_linear_filter", this->enable_linear_filter);
load_bool_value(doc, root + "keep_aspect_ratio", this->keep_aspect_ratio); for (size_t i = 0; i < std::size(this->scene_settings); i++) {
load_bool_value(doc, root + "centered", this->centered); auto& scene = this->scene_settings[i];
std::string prefix = "";
if (0 < i) {
prefix += fmt::format("scenes/{}/", i-1);
}
load_int_value(doc, root + prefix + "offset_x", scene.offset_x);
load_int_value(doc, root + prefix + "offset_y", scene.offset_y);
load_float_value(doc, root + prefix + "scale_x", scene.scale_x);
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 + "centered", scene.centered);
}
// windowed settings are always under game settings // windowed settings are always under game settings
root = "/sp2x_games/" + eamuse_get_game() + "/"; root = "/sp2x_games/" + eamuse_get_game() + "/";
@@ -189,14 +197,21 @@ namespace cfg {
root); root);
// full screen image settings // full screen image settings
rapidjson::Pointer(root + "offset_x").Set(doc, this->offset_x);
rapidjson::Pointer(root + "offset_y").Set(doc, this->offset_y);
rapidjson::Pointer(root + "scale_x").Set(doc, this->scale_x);
rapidjson::Pointer(root + "scale_y").Set(doc, this->scale_y);
rapidjson::Pointer(root + "enable_screen_resize").Set(doc, this->enable_screen_resize); rapidjson::Pointer(root + "enable_screen_resize").Set(doc, this->enable_screen_resize);
rapidjson::Pointer(root + "enable_linear_filter").Set(doc, this->enable_linear_filter); rapidjson::Pointer(root + "enable_linear_filter").Set(doc, this->enable_linear_filter);
rapidjson::Pointer(root + "keep_aspect_ratio").Set(doc, this->keep_aspect_ratio); for (size_t i = 0; i < std::size(this->scene_settings); i++) {
rapidjson::Pointer(root + "centered").Set(doc, this->centered); auto& scene = this->scene_settings[i];
std::string prefix = "";
if (0 < i) {
prefix += fmt::format("scenes/{}/", i-1);
}
rapidjson::Pointer(root + prefix + "offset_x").Set(doc, scene.offset_x);
rapidjson::Pointer(root + prefix + "offset_y").Set(doc, scene.offset_y);
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 + "keep_aspect_ratio").Set(doc, scene.keep_aspect_ratio);
rapidjson::Pointer(root + prefix + "centered").Set(doc, scene.centered);
}
// windowed mode settings // windowed mode settings
rapidjson::Pointer(root + "w_always_on_top").Set(doc, this->window_always_on_top); rapidjson::Pointer(root + "w_always_on_top").Set(doc, this->window_always_on_top);
+11 -6
View File
@@ -14,6 +14,15 @@ namespace cfg {
ResizableFrame = 2 ResizableFrame = 2
}; };
struct fullscreen_setting {
int offset_x = 0;
int offset_y = 0;
float scale_x = 1.0;
float scale_y = 1.0;
bool keep_aspect_ratio = true;
bool centered = true;
};
extern std::optional<std::string> SCREEN_RESIZE_CFG_PATH_OVERRIDE; extern std::optional<std::string> SCREEN_RESIZE_CFG_PATH_OVERRIDE;
class ScreenResize { class ScreenResize {
@@ -31,14 +40,10 @@ namespace cfg {
~ScreenResize(); ~ScreenResize();
// full screen (directx) image settings // full screen (directx) image settings
int offset_x = 0;
int offset_y = 0;
float scale_x = 1.0;
float scale_y = 1.0;
bool enable_screen_resize = false; bool enable_screen_resize = false;
int8_t screen_resize_current_scene = 0;
bool enable_linear_filter = true; bool enable_linear_filter = true;
bool keep_aspect_ratio = true; fullscreen_setting scene_settings[4];
bool centered = true;
// windowed mode sizing // windowed mode sizing
// Windows terminology: // Windows terminology:
+8
View File
@@ -439,6 +439,14 @@ namespace games {
vkey_defaults.push_back(0xFF); vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize"); names.emplace_back("Screen Resize");
vkey_defaults.push_back(0xFF); vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize Scene 1");
vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize Scene 2");
vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize Scene 3");
vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize Scene 4");
vkey_defaults.push_back(0xFF);
names.emplace_back("Force Exit Game"); names.emplace_back("Force Exit Game");
vkey_defaults.push_back(0xFF); vkey_defaults.push_back(0xFF);
names.emplace_back("Navigator Activate"); names.emplace_back("Navigator Activate");
+4
View File
@@ -23,6 +23,10 @@ namespace games {
ToggleOverlay, ToggleOverlay,
ToggleCameraControl, ToggleCameraControl,
ScreenResize, ScreenResize,
ScreenResizeScene1,
ScreenResizeScene2,
ScreenResizeScene3,
ScreenResizeScene4,
SuperExit, SuperExit,
NavigatorActivate, NavigatorActivate,
NavigatorCancel, NavigatorCancel,
@@ -740,9 +740,10 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
topSurface->UnlockRect(); topSurface->UnlockRect();
// do the actual zoom / offset math // do the actual zoom / offset math
if (cfg::SCREENRESIZE->centered) { auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene];
targetRect.right = (w + rectLeft) / cfg::SCREENRESIZE->scale_x; if (scene.centered) {
targetRect.bottom = (h + rectTop) / cfg::SCREENRESIZE->scale_y; targetRect.right = (w + rectLeft) / scene.scale_x;
targetRect.bottom = (h + rectTop) / scene.scale_y;
const LONG deltaH = ((targetRect.bottom - targetRect.top) - h) / 2; const LONG deltaH = ((targetRect.bottom - targetRect.top) - h) / 2;
const LONG deltaW = ((targetRect.right - targetRect.left) - w) / 2; const LONG deltaW = ((targetRect.right - targetRect.left) - w) / 2;
targetRect.top -= deltaH; targetRect.top -= deltaH;
@@ -750,12 +751,12 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
targetRect.left -= deltaW; targetRect.left -= deltaW;
targetRect.right -= deltaW; targetRect.right -= deltaW;
} else { } else {
targetRect.left -= cfg::SCREENRESIZE->offset_x; targetRect.left -= scene.offset_x;
targetRect.top += cfg::SCREENRESIZE->offset_y; targetRect.top += scene.offset_y;
targetRect.right = -cfg::SCREENRESIZE->offset_x; targetRect.right = -scene.offset_x;
targetRect.right += (w + rectLeft) / cfg::SCREENRESIZE->scale_x; targetRect.right += (w + rectLeft) / scene.scale_x;
targetRect.bottom = cfg::SCREENRESIZE->offset_y; targetRect.bottom = scene.offset_y;
targetRect.bottom += (h + rectTop) / cfg::SCREENRESIZE->scale_y; targetRect.bottom += (h + rectTop) / scene.scale_y;
} }
// draw to back buffer // draw to back buffer
+83 -19
View File
@@ -17,6 +17,10 @@ namespace overlay::windows {
this->init_pos = ImVec2(10, 10); this->init_pos = ImVec2(10, 10);
this->toggle_button = games::OverlayButtons::ToggleScreenResize; this->toggle_button = games::OverlayButtons::ToggleScreenResize;
this->toggle_screen_resize = games::OverlayButtons::ScreenResize; this->toggle_screen_resize = games::OverlayButtons::ScreenResize;
this->toggle_scene[0] = games::OverlayButtons::ScreenResizeScene1;
this->toggle_scene[1] = games::OverlayButtons::ScreenResizeScene2;
this->toggle_scene[2] = games::OverlayButtons::ScreenResizeScene3;
this->toggle_scene[3] = games::OverlayButtons::ScreenResizeScene4;
} }
ScreenResize::~ScreenResize() { ScreenResize::~ScreenResize() {
@@ -42,13 +46,17 @@ namespace overlay::windows {
void ScreenResize::reset_vars_to_default() { void ScreenResize::reset_vars_to_default() {
cfg::SCREENRESIZE->enable_screen_resize = false; cfg::SCREENRESIZE->enable_screen_resize = false;
cfg::SCREENRESIZE->screen_resize_current_scene = 0;
cfg::SCREENRESIZE->enable_linear_filter = true; cfg::SCREENRESIZE->enable_linear_filter = true;
cfg::SCREENRESIZE->keep_aspect_ratio = true; for (size_t i = 0; i < std::size(cfg::SCREENRESIZE->scene_settings); i++) {
cfg::SCREENRESIZE->centered = true; auto& scene = cfg::SCREENRESIZE->scene_settings[i];
cfg::SCREENRESIZE->offset_x = 0; scene.keep_aspect_ratio = true;
cfg::SCREENRESIZE->offset_y = 0; scene.centered = true;
cfg::SCREENRESIZE->scale_x = 1.f; scene.offset_x = 0;
cfg::SCREENRESIZE->scale_y = 1.f; scene.offset_y = 0;
scene.scale_x = 1.f;
scene.scale_y = 1.f;
}
cfg::SCREENRESIZE->enable_window_resize = false; cfg::SCREENRESIZE->enable_window_resize = false;
cfg::SCREENRESIZE->window_always_on_top = false; cfg::SCREENRESIZE->window_always_on_top = false;
@@ -88,28 +96,51 @@ namespace overlay::windows {
void ScreenResize::build_fullscreen_config() { void ScreenResize::build_fullscreen_config() {
// enable checkbox // enable checkbox
ImGui::TextWrapped("Hint: bind a key to Screen Resize for quickly toggling this on/off.");
ImGui::Checkbox("Enable", &cfg::SCREENRESIZE->enable_screen_resize); ImGui::Checkbox("Enable", &cfg::SCREENRESIZE->enable_screen_resize);
ImGui::SameLine();
ImGui::HelpMarker("Hint: bind a key to Screen Resize for a quick toggle.");
ImGui::BeginDisabled(!cfg::SCREENRESIZE->enable_screen_resize); ImGui::BeginDisabled(!cfg::SCREENRESIZE->enable_screen_resize);
ImGui::Checkbox("Linear Filter", &cfg::SCREENRESIZE->enable_linear_filter);
if (ImGui::RadioButton("Scene 1", cfg::SCREENRESIZE->screen_resize_current_scene == 0)) {
cfg::SCREENRESIZE->screen_resize_current_scene = 0;
}
ImGui::SameLine();
if (ImGui::RadioButton("Scene 2", cfg::SCREENRESIZE->screen_resize_current_scene == 1)) {
cfg::SCREENRESIZE->screen_resize_current_scene = 1;
}
ImGui::SameLine();
if (ImGui::RadioButton("Scene 3", cfg::SCREENRESIZE->screen_resize_current_scene == 2)) {
cfg::SCREENRESIZE->screen_resize_current_scene = 2;
}
ImGui::SameLine();
if (ImGui::RadioButton("Scene 4", cfg::SCREENRESIZE->screen_resize_current_scene == 3)) {
cfg::SCREENRESIZE->screen_resize_current_scene = 3;
}
ImGui::SameLine();
ImGui::HelpMarker(
"Hint: bind a key to Screen Resize 1/2/3/4 for quick scene switching. "
"Scene 1 is the default scene activated when starting the game.");
auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene];
// general settings // general settings
ImGui::Checkbox("Linear Filter", &cfg::SCREENRESIZE->enable_linear_filter); ImGui::Checkbox("Centered", &scene.centered);
ImGui::Checkbox("Centered", &cfg::SCREENRESIZE->centered); if (!scene.centered) {
if (!cfg::SCREENRESIZE->centered) { ImGui::InputInt("X Offset", &scene.offset_x);
ImGui::InputInt("X Offset", &cfg::SCREENRESIZE->offset_x); ImGui::InputInt("Y Offset", &scene.offset_y);
ImGui::InputInt("Y Offset", &cfg::SCREENRESIZE->offset_y);
} }
// aspect ratio // aspect ratio
ImGui::Checkbox("Keep Aspect Ratio", &cfg::SCREENRESIZE->keep_aspect_ratio); ImGui::Checkbox("Keep Aspect Ratio", &scene.keep_aspect_ratio);
if (cfg::SCREENRESIZE->keep_aspect_ratio) { if (scene.keep_aspect_ratio) {
if (ImGui::SliderFloat("Scale", &cfg::SCREENRESIZE->scale_x, 0.65f, 2.0f)) { if (ImGui::SliderFloat("Scale", &scene.scale_x, 0.65f, 2.0f)) {
cfg::SCREENRESIZE->scale_y = cfg::SCREENRESIZE->scale_x; scene.scale_y = scene.scale_x;
} }
} else { } else {
ImGui::SliderFloat("Width Scale", &cfg::SCREENRESIZE->scale_x, 0.65f, 2.0f); ImGui::SliderFloat("Width Scale", &scene.scale_x, 0.65f, 2.0f);
ImGui::SliderFloat("Height Scale", &cfg::SCREENRESIZE->scale_y, 0.65f, 2.0f); ImGui::SliderFloat("Height Scale", &scene.scale_y, 0.65f, 2.0f);
} }
ImGui::EndDisabled(); ImGui::EndDisabled();
@@ -217,8 +248,10 @@ namespace overlay::windows {
void ScreenResize::update() { void ScreenResize::update() {
Window::update(); Window::update();
auto overlay_buttons = games::get_buttons_overlay(eamuse_get_game());
// toggle
if (this->toggle_screen_resize != ~0u) { if (this->toggle_screen_resize != ~0u) {
auto overlay_buttons = games::get_buttons_overlay(eamuse_get_game());
bool toggle_screen_resize_new = overlay_buttons bool toggle_screen_resize_new = overlay_buttons
&& this->overlay->hotkeys_triggered() && this->overlay->hotkeys_triggered()
&& GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(this->toggle_screen_resize)); && GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(this->toggle_screen_resize));
@@ -228,5 +261,36 @@ namespace overlay::windows {
} }
this->toggle_screen_resize_state = toggle_screen_resize_new; this->toggle_screen_resize_state = toggle_screen_resize_new;
} }
// scene switch
auto toggle_scene_state_new = ~0u;
for (size_t i = 0; i < std::size(this->toggle_scene); i++) {
if (this->toggle_scene[i] == ~0u) {
continue;
}
bool scene_switched = overlay_buttons
&& this->overlay->hotkeys_triggered()
&& GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(this->toggle_scene[i]));
if (scene_switched) {
toggle_scene_state_new = (uint32_t)i;
}
// only detect rising edges of key presses
if (scene_switched && (this->toggle_scene_state != i)) {
if (cfg::SCREENRESIZE->screen_resize_current_scene == (int8_t)i &&
cfg::SCREENRESIZE->enable_screen_resize) {
// this scene is already active, turn scaling off
cfg::SCREENRESIZE->enable_screen_resize = false;
} else {
// switch to scene
cfg::SCREENRESIZE->enable_screen_resize = true;
cfg::SCREENRESIZE->screen_resize_current_scene = i;
}
break;
}
}
// remember if a key was pressed (or nothing pressed) this frame
this->toggle_scene_state = toggle_scene_state_new;
} }
} }
@@ -16,6 +16,9 @@ namespace overlay::windows {
size_t toggle_screen_resize = ~0u; size_t toggle_screen_resize = ~0u;
bool toggle_screen_resize_state = false; bool toggle_screen_resize_state = false;
size_t toggle_scene[4] = { ~0u, ~0u, ~0u, ~0u };
uint32_t toggle_scene_state = ~0u;
void build_fullscreen_config(); void build_fullscreen_config();
void build_windowed_config(); void build_windowed_config();
void build_footer(); void build_footer();