Files
spice2x.github.io/src/spice2x/cfg/screen_resize.h
T
bicarus-dev 104a9cbffd graphics: rewrite image scaler (#278)
## Link to GitHub Issue, if one exists
Fixes #276 

## Description of change

Note: this change is not compatible with previous screen resize config;
i.e., if you had the zoom setting dialed into a certain view, after this
change it won't be the same area, so you'll have to set up a scene
again. I think this is a worthwhile cost since the old logic is just
broken in weird ways, and preserving old settings is really tedious math
(for a feature that not many people use). Besides, this change will only
use the new Scenes values from the JSON.

Rewrite the DX9 image scaler logic.

* Previously, the rendering surface was fixed at `4096*4096 px`. Now,
this is relative to the backbuffer dimensions, which depends on the game
& respects user provided `-forceres`.
* Remove "center" option, make it the default.

Above two changes fix the aspect ratio issue (scaling in portrait games
not respecting screen ratio) and things breaking at higher res (1080p
when zoomed out far enough, or when forced to run at 4k resolution for
example)

* Use `scenes` leaf of screen resize JSON config for Scene 1 as well,
completely removing ourselves from being compatible with older spice2x
versions for these values.
* Add additional bounds check before calling `StretchRect` to avoid
users getting stuck with a bad layout, which can kill performance.

## Compiling
🦾 

## Testing
Tested 32 bit (popn / ddr), 64 bit (ldj), portrait and landscape modes
(kfc)
2025-03-28 17:23:01 -07:00

75 lines
2.2 KiB
C++

#pragma once
#include <memory>
#include <string>
#include <optional>
#include <filesystem>
#include "external/rapidjson/document.h"
namespace cfg {
enum WindowDecorationMode {
Default = 0,
Borderless = 1,
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;
};
extern std::optional<std::string> SCREEN_RESIZE_CFG_PATH_OVERRIDE;
class ScreenResize {
private:
std::filesystem::path config_path;
// bool config_dirty = false;
bool load_bool_value(rapidjson::Document& doc, std::string path, bool& value);
bool load_int_value(rapidjson::Document& doc, std::string path, int& value);
bool load_uint32_value(rapidjson::Document& doc, std::string path, uint32_t& value);
bool load_float_value(rapidjson::Document& doc, std::string path, float& value);
public:
ScreenResize();
~ScreenResize();
// full screen (directx) image settings
bool enable_screen_resize = false;
int8_t screen_resize_current_scene = 0;
bool enable_linear_filter = true;
fullscreen_setting scene_settings[4];
// windowed mode sizing
// Windows terminology:
// window = rectangle including the frame
// client = just the content area without frames.
bool window_always_on_top = false;
bool client_keep_aspect_ratio = true;
bool enable_window_resize = false;
int window_decoration = 0; // enum type WindowDecorationMode
uint32_t client_width = 0;
uint32_t client_height = 0;
int32_t window_offset_x = 0;
int32_t window_offset_y = 0;
// these are not saved by config, but used by window management
uint32_t init_client_width = 0;
uint32_t init_client_height = 0;
float init_client_aspect_ratio = 1.f;
uint32_t init_window_style = 0;
uint32_t window_deco_width = 0;
uint32_t window_deco_height = 0;
void config_load();
void config_save();
};
// globals
extern std::unique_ptr<cfg::ScreenResize> SCREENRESIZE;
}