mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user