Add screen separator and settings for it

This commit is contained in:
Lorenzooone 2025-03-03 02:05:15 +01:00
parent cdcb1ba297
commit 166ccab6b8
11 changed files with 445 additions and 79 deletions

View File

@ -490,7 +490,7 @@ if(MSVC)
else()
set_source_files_properties(source/conversions.cpp PROPERTIES COMPILE_OPTIONS "$<$<CONFIG:Release>:-O3>")
endif()
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES})
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp source/Menus/SeparatorMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES})
if(NOT ("${EXTRA_DEPENDENCIES}" STREQUAL ""))

View File

@ -10,8 +10,8 @@ source to prevent build errors.
Certain files which are not needed were removed from the libraries' archives
to save on space.
Feel free to contact me if you would like me to have the files removed,
if an agreement about their availability is reached.
Feel free to contact me if you would like the files to be removed,
if an agreement about their availability can be reached.
Changing FTDI\_BASE\_URL to https://ftdichip.com/wp-content/uploads will
switch to automatic download during builds.

View File

@ -0,0 +1,43 @@
#ifndef __SEPARATORMENU_HPP
#define __SEPARATORMENU_HPP
#include "OptionSelectionMenu.hpp"
#include <chrono>
#include "TextRectangle.hpp"
#include "sfml_gfx_structs.hpp"
#include "display_structs.hpp"
enum SeparatorMenuOutAction{
SEPARATOR_MENU_NO_ACTION,
SEPARATOR_MENU_BACK,
SEPARATOR_MENU_SIZE_DEC_1,
SEPARATOR_MENU_SIZE_INC_1,
SEPARATOR_MENU_SIZE_DEC_10,
SEPARATOR_MENU_SIZE_INC_10,
SEPARATOR_MENU_WINDOW_MUL_DEC,
SEPARATOR_MENU_WINDOW_MUL_INC,
SEPARATOR_MENU_FULLSCREEN_MUL_DEC,
SEPARATOR_MENU_FULLSCREEN_MUL_INC,
};
class SeparatorMenu : public OptionSelectionMenu {
public:
SeparatorMenu(bool font_load_success, sf::Font &text_font);
~SeparatorMenu();
void prepare(float scaling_factor, int view_size_x, int view_size_y, ScreenInfo *info);
void insert_data(bool is_fullscreen);
SeparatorMenuOutAction selected_index = SeparatorMenuOutAction::SEPARATOR_MENU_NO_ACTION;
void reset_output_option();
protected:
bool is_option_inc_dec(int index);
void set_output_option(int index, int action);
int get_num_options();
std::string get_string_option(int index, int action);
void class_setup();
private:
int *options_indexes;
int num_enabled_options;
std::string get_name_multiplier(int index, float value, bool is_fullscreen);
};
#endif

View File

@ -40,6 +40,7 @@ enum VideoMenuOutAction{
VIDEO_MENU_SCALING_RATIO_SETTINGS,
VIDEO_MENU_CHANGE_TITLEBAR,
VIDEO_MENU_VIDEO_EFFECTS_SETTINGS,
VIDEO_MENU_SEPARATOR_SETTINGS,
};
class VideoMenu : public OptionSelectionMenu {

View File

@ -16,10 +16,16 @@
#define MAX_WINDOW_SCALING_VALUE 45.0
#define WINDOW_SCALING_CHANGE 0.5
#define SEP_FOLLOW_SCALING_MULTIPLIER WINDOW_SCALING_CHANGE
#define SEP_WINDOW_SCALING_MIN_MULTIPLIER SEP_FOLLOW_SCALING_MULTIPLIER
#define SEP_FULLSCREEN_SCALING_MIN_MULTIPLIER DEFAULT_WINDOW_SCALING_VALUE
#define DEFAULT_SEP_SIZE 0
#define MAX_SEP_SIZE 1000
enum ScreenType { TOP, BOTTOM, JOINT };
enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END };
enum NonIntegerScalingModes { SMALLER_PRIORITY, INVERSE_PROPORTIONAL_PRIORITY, EQUAL_PRIORITY, PROPORTIONAL_PRIORITY, BIGGER_PRIORITY, END_NONINT_SCALE_MODES };
enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_MENU_TYPE, TOP_PAR_MENU_TYPE, BOTTOM_PAR_MENU_TYPE, ROTATION_MENU_TYPE, OFFSET_MENU_TYPE, BFI_MENU_TYPE, LOAD_MENU_TYPE, SAVE_MENU_TYPE, RESOLUTION_MENU_TYPE, EXTRA_MENU_TYPE, STATUS_MENU_TYPE, LICENSES_MENU_TYPE, RELATIVE_POS_MENU_TYPE, SHORTCUTS_MENU_TYPE, ACTION_SELECTION_MENU_TYPE, SCALING_RATIO_MENU_TYPE, ISN_MENU_TYPE, VIDEO_EFFECTS_MENU_TYPE, INPUT_MENU_TYPE, AUDIO_DEVICE_MENU_TYPE };
enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_MENU_TYPE, TOP_PAR_MENU_TYPE, BOTTOM_PAR_MENU_TYPE, ROTATION_MENU_TYPE, OFFSET_MENU_TYPE, BFI_MENU_TYPE, LOAD_MENU_TYPE, SAVE_MENU_TYPE, RESOLUTION_MENU_TYPE, EXTRA_MENU_TYPE, STATUS_MENU_TYPE, LICENSES_MENU_TYPE, RELATIVE_POS_MENU_TYPE, SHORTCUTS_MENU_TYPE, ACTION_SELECTION_MENU_TYPE, SCALING_RATIO_MENU_TYPE, ISN_MENU_TYPE, VIDEO_EFFECTS_MENU_TYPE, INPUT_MENU_TYPE, AUDIO_DEVICE_MENU_TYPE, SEPARATOR_MENU_TYPE };
enum InputColorspaceMode { FULL_COLORSPACE, DS_COLORSPACE, GBA_COLORSPACE, INPUT_COLORSPACE_END };
enum FrameBlendingMode { NO_FRAME_BLENDING, FULL_FRAME_BLENDING, DS_3D_BOTH_SCREENS_FRAME_BLENDING, FRAME_BLENDING_END };
@ -44,6 +50,9 @@ struct ScreenInfo {
bool v_sync_enabled;
bool async;
int top_scaling, bot_scaling;
int separator_pixel_size;
float separator_windowed_multiplier;
float separator_fullscreen_multiplier;
bool force_same_scaling;
float non_integer_top_scaling, non_integer_bot_scaling;
bool bfi;

View File

@ -34,6 +34,7 @@
#include "VideoEffectsMenu.hpp"
#include "InputMenu.hpp"
#include "AudioDeviceMenu.hpp"
#include "SeparatorMenu.hpp"
#include "display_structs.hpp"
#include "event_structs.hpp"
#include "shaders_list.hpp"
@ -155,6 +156,7 @@ private:
VideoEffectsMenu *video_effects_menu;
InputMenu *input_menu;
AudioDeviceMenu *audio_device_menu;
SeparatorMenu *separator_menu;
std::vector<const CropData*> possible_crops;
std::vector<const CropData*> possible_crops_ds;
std::vector<const CropData*> possible_crops_with_games;
@ -251,6 +253,10 @@ private:
void titlebar_change();
void input_colorspace_mode_change(bool positive);
void frame_blending_mode_change(bool positive);
void separator_size_change(int change);
void separator_multiplier_change(bool positive, float& multiplier_to_check, float lower_limit, float upper_limit);
void separator_windowed_multiplier_change(bool positive);
void separator_fullscreen_multiplier_change(bool positive);
bool query_reset_request();
void reset_held_times(bool force = true);
void poll_window(bool do_everything);
@ -269,8 +275,8 @@ private:
void window_bg_processing();
void display_data_to_window(bool actually_draw, bool is_debug = false);
void window_render_call();
void set_position_screens(sf::Vector2f &curr_top_screen_size, sf::Vector2f &curr_bot_screen_size, int offset_x, int offset_y, int max_x, int max_y, bool do_work = true);
float get_max_float_screen_multiplier(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation);
void set_position_screens(sf::Vector2f &curr_top_screen_size, sf::Vector2f &curr_bot_screen_size, int offset_x, int offset_y, int max_x, int max_y, int separator_size_x, int separator_size_y, bool do_work = true);
float get_max_float_screen_multiplier(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation, bool is_two_screens_merged = false);
int prepare_screen_ratio(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation);
float get_ratio_compared_other_screen(ResizingScreenData *own_screen, ResizingScreenData* other_screen, float other_scaling);
bool can_non_integerly_scale();
@ -283,8 +289,8 @@ private:
void merge_screens_data(ResizingScreenData* top_screen_resize_data, ResizingScreenData* bot_screen_resize_data, ResizingScreenData* merged_screen_resize_data, BottomRelativePosition bottom_pos);
bool prepare_screens_same_scaling_factor(ResizingScreenData* top_screen_resize_data, ResizingScreenData* bot_screen_resize_data);
void prepare_size_ratios(bool top_increase, bool bot_increase, bool cycle = false);
int get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height);
int get_fullscreen_offset_y(int top_width, int top_height, int bot_width, int bot_height);
int get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height, int separator_contribute);
int get_fullscreen_offset_y(int top_width, int top_height, int bot_width, int bot_height, int separator_contribute);
void resize_window_and_out_rects(bool do_work = true);
void create_window(bool re_prepare_size, bool reset_text = true);
std::string title_factory();
@ -320,6 +326,7 @@ private:
void setup_is_nitro_menu(bool reset_data = true);
void setup_video_effects_menu(bool reset_data = true);
void setup_input_menu(bool reset_data = true);
void setup_separator_menu(bool reset_data = true);
void update_connection();
};
@ -349,7 +356,6 @@ std::string save_screen_info(std::string base, const ScreenInfo &info);
const PARData* get_base_par();
void get_par_size(int &width, int &height, float multiplier_factor, const PARData *correction_factor);
void get_par_size(float &width, float &height, float multiplier_factor, const PARData *correction_factor);
float get_par_mult_factor(float width, float height, float max_width, float max_height, const PARData *correction_factor, bool is_rotated);
void update_output(FrontendData* frontend_data, double frame_time = 0.0, VideoOutputData *out_buf = NULL);
void update_connected_3ds_ds(FrontendData* frontend_data, const CaptureDevice &old_cc_device, const CaptureDevice &new_cc_device);
void update_connected_specific_settings(FrontendData* frontend_data, const CaptureDevice &cc_device);

View File

@ -0,0 +1,148 @@
#include "SeparatorMenu.hpp"
#define NUM_TOTAL_MENU_OPTIONS (sizeof(pollable_options)/sizeof(pollable_options[0]))
struct SeparatorMenuOptionInfo {
const std::string base_name;
const bool is_inc;
const std::string dec_str;
const std::string inc_str;
const SeparatorMenuOutAction inc_out_action;
const SeparatorMenuOutAction out_action;
const bool show_windowed;
const bool show_fullscreen;
};
static const SeparatorMenuOptionInfo separator_size_change_1_option = {
.base_name = "Separator Size:",
.is_inc = true, .dec_str = "-1", .inc_str = "+1", .inc_out_action = SEPARATOR_MENU_SIZE_INC_1,
.out_action = SEPARATOR_MENU_SIZE_DEC_1,
.show_windowed = true, .show_fullscreen = true};
static const SeparatorMenuOptionInfo separator_size_change_10_option = {
.base_name = "",
.is_inc = true, .dec_str = "-10", .inc_str = "+10", .inc_out_action = SEPARATOR_MENU_SIZE_INC_10,
.out_action = SEPARATOR_MENU_SIZE_DEC_10,
.show_windowed = true, .show_fullscreen = true};
static const SeparatorMenuOptionInfo separator_window_mul_change_option = {
.base_name = "Multiplier",
.is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = SEPARATOR_MENU_WINDOW_MUL_INC,
.out_action = SEPARATOR_MENU_WINDOW_MUL_DEC,
.show_windowed = true, .show_fullscreen = false};
static const SeparatorMenuOptionInfo separator_fullscreen_mul_change_option = {
.base_name = "Multiplier",
.is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = SEPARATOR_MENU_FULLSCREEN_MUL_INC,
.out_action = SEPARATOR_MENU_FULLSCREEN_MUL_DEC,
.show_windowed = false, .show_fullscreen = true};
static const SeparatorMenuOptionInfo* pollable_options[] = {
&separator_size_change_1_option,
&separator_size_change_10_option,
&separator_window_mul_change_option,
&separator_fullscreen_mul_change_option,
};
SeparatorMenu::SeparatorMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){
this->options_indexes = new int[NUM_TOTAL_MENU_OPTIONS];
this->initialize(font_load_success, text_font);
this->num_enabled_options = 0;
}
SeparatorMenu::~SeparatorMenu() {
delete []this->options_indexes;
}
void SeparatorMenu::class_setup() {
this->num_options_per_screen = 5;
this->min_elements_text_scaling_factor = num_options_per_screen + 2;
this->width_factor_menu = 16;
this->width_divisor_menu = 9;
this->base_height_factor_menu = 12;
this->base_height_divisor_menu = 6;
this->min_text_size = 0.3;
this->max_width_slack = 1.1;
this->menu_color = sf::Color(30, 30, 60, 192);
this->title = "Separator Settings";
this->show_back_x = true;
this->show_x = false;
this->show_title = true;
}
void SeparatorMenu::insert_data(bool is_fullscreen) {
this->num_enabled_options = 0;
for(int i = 0; i < NUM_TOTAL_MENU_OPTIONS; i++) {
if(is_fullscreen && (!pollable_options[i]->show_fullscreen))
continue;
if((!is_fullscreen) && (!pollable_options[i]->show_windowed))
continue;
this->options_indexes[this->num_enabled_options] = i;
this->num_enabled_options++;
}
this->prepare_options();
}
void SeparatorMenu::reset_output_option() {
this->selected_index = SeparatorMenuOutAction::SEPARATOR_MENU_NO_ACTION;
}
void SeparatorMenu::set_output_option(int index, int action) {
if(index == BACK_X_OUTPUT_OPTION)
this->selected_index = SEPARATOR_MENU_BACK;
else if((action == INC_ACTION) && this->is_option_inc_dec(index))
this->selected_index = pollable_options[this->options_indexes[index]]->inc_out_action;
else
this->selected_index = pollable_options[this->options_indexes[index]]->out_action;
}
int SeparatorMenu::get_num_options() {
return this->num_enabled_options;
}
std::string SeparatorMenu::get_string_option(int index, int action) {
if((action == INC_ACTION) && this->is_option_inc_dec(index))
return pollable_options[this->options_indexes[index]]->inc_str;
if((action == DEC_ACTION) && this->is_option_inc_dec(index))
return pollable_options[this->options_indexes[index]]->dec_str;
return pollable_options[this->options_indexes[index]]->base_name;
}
bool SeparatorMenu::is_option_inc_dec(int index) {
return pollable_options[this->options_indexes[index]]->is_inc;
}
std::string SeparatorMenu::get_name_multiplier(int index, float value, bool is_fullscreen) {
if((!is_fullscreen) && (value == SEP_FOLLOW_SCALING_MULTIPLIER))
return this->get_string_option(index, DEFAULT_ACTION) + ": " + "Scaling";
return this->setTextOptionFloat(index, value);
}
void SeparatorMenu::prepare(float menu_scaling_factor, int view_size_x, int view_size_y, ScreenInfo *info) {
int num_pages = this->get_num_pages();
if(this->future_data.page >= num_pages)
this->future_data.page = num_pages - 1;
int start = this->future_data.page * this->num_options_per_screen;
for(int i = 0; i < this->num_options_per_screen + 1; i++) {
int index = (i * this->single_option_multiplier) + this->elements_start_id;
if(!this->future_enabled_labels[index])
continue;
int real_index = start + i;
int option_index = this->options_indexes[real_index];
switch(pollable_options[option_index]->out_action) {
case SEPARATOR_MENU_SIZE_DEC_10:
this->labels[index]->setText(std::to_string(info->separator_pixel_size));
break;
case SEPARATOR_MENU_WINDOW_MUL_DEC:
this->labels[index]->setText(get_name_multiplier(real_index, info->separator_windowed_multiplier, info->is_fullscreen));
break;
case SEPARATOR_MENU_FULLSCREEN_MUL_DEC:
this->labels[index]->setText(get_name_multiplier(real_index, info->separator_fullscreen_multiplier, info->is_fullscreen));
break;
default:
break;
}
}
this->base_prepare(menu_scaling_factor, view_size_x, view_size_y);
}

View File

@ -188,6 +188,13 @@ static const VideoMenuOptionInfo video_effects_settings_option = {
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = VIDEO_MENU_NO_ACTION,
.out_action = VIDEO_MENU_VIDEO_EFFECTS_SETTINGS};
static const VideoMenuOptionInfo separator_settings_option = {
.base_name = "Separator Settings", .false_name = "",
.active_fullscreen = true, .active_windowed_screen = true, .requires_titlebar_possible = false,
.active_joint_screen = true, .active_top_screen = false, .active_bottom_screen = false,
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = VIDEO_MENU_NO_ACTION,
.out_action = VIDEO_MENU_SEPARATOR_SETTINGS};
static const VideoMenuOptionInfo* pollable_options[] = {
&crop_option,
&window_scaling_option,
@ -195,6 +202,7 @@ static const VideoMenuOptionInfo* pollable_options[] = {
&scaling_ratio_settings_option,
&menu_scaling_option,
&bottom_screen_pos_option,
&separator_settings_option,
&vsync_option,
&async_option,
&blur_option,

View File

@ -31,6 +31,10 @@ struct shader_and_data {
static std::vector<shader_and_data> usable_shaders;
static bool is_size_valid(sf::Vector2f &size) {
return (size.x > 0.0) && (size.y > 0.0);
}
WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, SharedData* shared_data, AudioData* audio_data, ConsumerMutex *draw_lock, bool created_proper_folder) {
this->draw_lock = draw_lock;
this->m_stype = stype;
@ -673,7 +677,39 @@ void WindowScreen::window_render_call() {
}
}
void WindowScreen::set_position_screens(sf::Vector2f &curr_top_screen_size, sf::Vector2f &curr_bot_screen_size, int offset_x, int offset_y, int max_x, int max_y, bool do_work) {
static bool should_have_separator(sf::Vector2f top_screen_size, sf::Vector2f bot_screen_size, float top_scaling, float bot_scaling, ScreenType stype) {
if(stype != ScreenType::JOINT)
return false;
if((!is_size_valid(top_screen_size)) || (!is_size_valid(bot_screen_size)))
return false;
if((top_scaling <= 0) || (bot_scaling <= 0))
return false;
return true;
}
static int get_separator_size_xy(float top_scaling, float bot_scaling, int separator_size, float separator_multiplier, bool is_fullscreen) {
if((!is_fullscreen) && (separator_multiplier == SEP_FOLLOW_SCALING_MULTIPLIER))
return separator_size * top_scaling;
return separator_size * separator_multiplier;
}
static int get_separator_size_x(sf::Vector2f top_screen_size, sf::Vector2f bot_screen_size, float top_scaling, float bot_scaling, ScreenType stype, BottomRelativePosition bottom_pos, int separator_size, float separator_multiplier, bool is_fullscreen) {
if(!should_have_separator(top_screen_size, bot_screen_size, top_scaling, bot_scaling, stype))
return 0;
if((bottom_pos != RIGHT_TOP) && (bottom_pos != LEFT_TOP))
return 0;
return get_separator_size_xy(top_scaling, bot_scaling, separator_size, separator_multiplier, is_fullscreen);
}
static int get_separator_size_y(sf::Vector2f top_screen_size, sf::Vector2f bot_screen_size, float top_scaling, float bot_scaling, ScreenType stype, BottomRelativePosition bottom_pos, int separator_size, float separator_multiplier, bool is_fullscreen) {
if(!should_have_separator(top_screen_size, bot_screen_size, top_scaling, bot_scaling, stype))
return 0;
if((bottom_pos != UNDER_TOP) && (bottom_pos != ABOVE_TOP))
return 0;
return get_separator_size_xy(top_scaling, bot_scaling, separator_size, separator_multiplier, is_fullscreen);
}
void WindowScreen::set_position_screens(sf::Vector2f &curr_top_screen_size, sf::Vector2f &curr_bot_screen_size, int offset_x, int offset_y, int max_x, int max_y, int separator_size_x, int separator_size_y, bool do_work) {
int top_screen_x = 0, top_screen_y = 0;
int bot_screen_x = 0, bot_screen_y = 0;
int top_screen_width = curr_top_screen_size.x;
@ -707,30 +743,30 @@ void WindowScreen::set_position_screens(sf::Vector2f &curr_top_screen_size, sf::
case UNDER_TOP:
bot_screen_x = (greatest_width - bot_screen_width) * this->loaded_info.subscreen_offset;
top_screen_x = (greatest_width - top_screen_width) * this->loaded_info.subscreen_offset;
bot_screen_y = top_screen_height;
bot_screen_y = top_screen_height + separator_size_y;
if(max_y > 0)
bot_screen_y += (max_y - bot_screen_height - top_screen_height - offset_y) * this->loaded_info.subscreen_attached_offset;
bot_screen_y += (max_y - bot_screen_height - separator_size_y - top_screen_height - offset_y) * this->loaded_info.subscreen_attached_offset;
break;
case RIGHT_TOP:
bot_screen_y = (greatest_height - bot_screen_height) * this->loaded_info.subscreen_offset;
top_screen_y = (greatest_height - top_screen_height) * this->loaded_info.subscreen_offset;
bot_screen_x = top_screen_width;
bot_screen_x = top_screen_width + separator_size_x;
if(max_x > 0)
bot_screen_x += (max_x - bot_screen_width - top_screen_width - offset_x) * this->loaded_info.subscreen_attached_offset;
bot_screen_x += (max_x - bot_screen_width - separator_size_x - top_screen_width - offset_x) * this->loaded_info.subscreen_attached_offset;
break;
case ABOVE_TOP:
bot_screen_x = (greatest_width - bot_screen_width) * this->loaded_info.subscreen_offset;
top_screen_x = (greatest_width - top_screen_width) * this->loaded_info.subscreen_offset;
top_screen_y = bot_screen_height;
top_screen_y = bot_screen_height + separator_size_y;
if(max_y > 0)
top_screen_y += (max_y - bot_screen_height - top_screen_height - offset_y) * this->loaded_info.subscreen_attached_offset;
top_screen_y += (max_y - bot_screen_height - separator_size_y - top_screen_height - offset_y) * this->loaded_info.subscreen_attached_offset;
break;
case LEFT_TOP:
bot_screen_y = (greatest_height - bot_screen_height) * this->loaded_info.subscreen_offset;
top_screen_y = (greatest_height - top_screen_height) * this->loaded_info.subscreen_offset;
top_screen_x = bot_screen_width;
top_screen_x = bot_screen_width + separator_size_x;
if(max_x > 0)
top_screen_x += (max_x - bot_screen_width - top_screen_width - offset_x) * this->loaded_info.subscreen_attached_offset;
top_screen_x += (max_x - bot_screen_width - separator_size_x - top_screen_width - offset_x) * this->loaded_info.subscreen_attached_offset;
break;
default:
break;
@ -754,18 +790,17 @@ void WindowScreen::set_position_screens(sf::Vector2f &curr_top_screen_size, sf::
this->m_height = bot_end_y;
}
static bool is_size_valid(sf::Vector2f &size) {
return (size.x > 0.0) && (size.y > 0.0);
}
float WindowScreen::get_max_float_screen_multiplier(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation) {
float WindowScreen::get_max_float_screen_multiplier(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation, bool is_two_screens_merged) {
if(!is_size_valid(own_screen->size))
return 0;
if((other_rotation / 10) % 2)
std::swap(width_limit, height_limit);
int desk_height = curr_desk_mode.size.y;
int desk_width = curr_desk_mode.size.x;
sf::Vector2f other_screen_size = sf::Vector2f(width_limit, height_limit);
if((!is_size_valid(other_screen_size)) && is_two_screens_merged)
other_screen_size = sf::Vector2f(1, 1);
int desk_height = curr_desk_mode.size.y - get_separator_size_y(own_screen->size, other_screen_size, 1.0, 1.0, this->m_stype, this->m_info.bottom_pos, this->m_info.separator_pixel_size, this->m_info.separator_fullscreen_multiplier, true);
int desk_width = curr_desk_mode.size.x - get_separator_size_x(own_screen->size, other_screen_size, 1.0, 1.0, this->m_stype, this->m_info.bottom_pos, this->m_info.separator_pixel_size, this->m_info.separator_fullscreen_multiplier, true);
int height_max = desk_height;
int width_max = desk_width;
switch(this->m_info.bottom_pos) {
@ -781,7 +816,18 @@ float WindowScreen::get_max_float_screen_multiplier(ResizingScreenData *own_scre
break;
}
return get_par_mult_factor(own_screen->size.x, own_screen->size.y, width_max, height_max, own_screen->par, (own_screen->rotation / 10) % 2);
float own_width = own_screen->size.x;
float own_height = own_screen->size.y;
get_par_size(own_width, own_height, 1.0, own_screen->par);
if((own_screen->rotation / 10) % 2)
std::swap(own_width, own_height);
if((own_height == 0) || (own_width == 0))
return 0;
float factor_width = width_max / own_width;
float factor_height = height_max / own_height;
if(factor_height < factor_width)
return factor_height;
return factor_width;
}
int WindowScreen::prepare_screen_ratio(ResizingScreenData *own_screen, int width_limit, int height_limit, int other_rotation) {
@ -992,7 +1038,7 @@ bool WindowScreen::prepare_screens_same_scaling_factor(ResizingScreenData* top_s
float non_int_scaling_merged = 1.0;
ResizingScreenData merged_screen_resize_data = {.size = {}, .scaling = &scaling_merged, .non_int_scaling = &non_int_scaling_merged, .use_non_int_scaling = false, .rotation = 0, .par = NULL};
merge_screens_data(top_screen_resize_data, bot_screen_resize_data, &merged_screen_resize_data, this->m_info.bottom_pos);
non_int_scaling_merged = this->get_max_float_screen_multiplier(&merged_screen_resize_data, 0, 0, 0);
non_int_scaling_merged = this->get_max_float_screen_multiplier(&merged_screen_resize_data, 0, 0, 0, true);
scaling_merged = non_int_scaling_merged;
if(non_int_scaling_merged < 1.0)
return false;
@ -1047,14 +1093,12 @@ void WindowScreen::prepare_size_ratios(bool top_increase, bool bot_increase, boo
}
}
int WindowScreen::get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height) {
int WindowScreen::get_fullscreen_offset_x(int top_width, int top_height, int bot_width, int bot_height, int separator_contribute) {
if((this->loaded_info.top_rotation / 10) % 2)
std::swap(top_width, top_height);
if((this->loaded_info.bot_rotation / 10) % 2)
std::swap(bot_width, bot_height);
int greatest_width = top_width;
if(bot_width > top_width)
greatest_width = bot_width;
int greatest_width = std::max(top_width, bot_width);
int offset_contribute = 0;
switch(this->loaded_info.bottom_pos) {
case UNDER_TOP:
@ -1063,7 +1107,7 @@ int WindowScreen::get_fullscreen_offset_x(int top_width, int top_height, int bot
break;
case LEFT_TOP:
case RIGHT_TOP:
offset_contribute = top_width + bot_width;
offset_contribute = top_width + bot_width + separator_contribute;
break;
default:
return 0;
@ -1071,19 +1115,17 @@ int WindowScreen::get_fullscreen_offset_x(int top_width, int top_height, int bot
return (curr_desk_mode.size.x - offset_contribute) * this->loaded_info.total_offset_x;
}
int WindowScreen::get_fullscreen_offset_y(int top_width, int top_height, int bot_width, int bot_height) {
int WindowScreen::get_fullscreen_offset_y(int top_width, int top_height, int bot_width, int bot_height, int separator_contribute) {
if((this->loaded_info.top_rotation / 10) % 2)
std::swap(top_width, top_height);
if((this->loaded_info.bot_rotation / 10) % 2)
std::swap(bot_width, bot_height);
int greatest_height = top_height;
if(bot_height > top_height)
greatest_height = bot_height;
int greatest_height = std::max(top_height, bot_height);
int offset_contribute = 0;
switch(this->loaded_info.bottom_pos) {
case UNDER_TOP:
case ABOVE_TOP:
offset_contribute = top_height + bot_height;
offset_contribute = top_height + bot_height + separator_contribute;
break;
case LEFT_TOP:
case RIGHT_TOP:
@ -1108,10 +1150,14 @@ void WindowScreen::resize_window_and_out_rects(bool do_work) {
int offset_y = 0;
int max_x = 0;
int max_y = 0;
int separator_size_x = 0;
int separator_size_y = 0;
float sep_multiplier = this->loaded_info.separator_windowed_multiplier;
if(this->loaded_info.is_fullscreen) {
top_scaling = this->loaded_info.non_integer_top_scaling;
bot_scaling = this->loaded_info.non_integer_bot_scaling;
sep_multiplier = this->loaded_info.separator_fullscreen_multiplier;
}
if((this->loaded_info.top_par >= this->possible_pars.size()) || (this->loaded_info.top_par < 0))
this->loaded_info.top_par = 0;
@ -1125,9 +1171,11 @@ void WindowScreen::resize_window_and_out_rects(bool do_work) {
offset_x = LEFT_ROUNDED_PADDING;
}
separator_size_x = get_separator_size_x(top_screen_size, bot_screen_size, top_scaling, bot_scaling, this->m_stype, this->loaded_info.bottom_pos, this->loaded_info.separator_pixel_size, sep_multiplier, this->loaded_info.is_fullscreen);
separator_size_y = get_separator_size_y(top_screen_size, bot_screen_size, top_scaling, bot_scaling, this->m_stype, this->loaded_info.bottom_pos, this->loaded_info.separator_pixel_size, sep_multiplier, this->loaded_info.is_fullscreen);
if(this->loaded_info.is_fullscreen) {
offset_x = get_fullscreen_offset_x(top_width, top_height, bot_width, bot_height);
offset_y = get_fullscreen_offset_y(top_width, top_height, bot_width, bot_height);
offset_x = get_fullscreen_offset_x(top_width, top_height, bot_width, bot_height, separator_size_x);
offset_y = get_fullscreen_offset_y(top_width, top_height, bot_width, bot_height, separator_size_y);
max_x = curr_desk_mode.size.x;
max_y = curr_desk_mode.size.y;
}
@ -1139,7 +1187,7 @@ void WindowScreen::resize_window_and_out_rects(bool do_work) {
this->m_out_rect_bot.out_rect.setSize(new_bot_screen_size);
this->m_out_rect_bot.out_rect.setTextureRect(sf::IntRect({0, 0}, {(int)bot_screen_size.x, (int)bot_screen_size.y}));
}
this->set_position_screens(new_top_screen_size, new_bot_screen_size, offset_x, offset_y, max_x, max_y, do_work);
this->set_position_screens(new_top_screen_size, new_bot_screen_size, offset_x, offset_y, max_x, max_y, separator_size_x, separator_size_y, do_work);
if((!this->loaded_info.is_fullscreen) && this->loaded_info.rounded_corners_fix) {
this->m_height += BOTTOM_ROUNDED_PADDING;
this->m_width += RIGHT_ROUNDED_PADDING;

View File

@ -118,6 +118,7 @@ void WindowScreen::init_menus() {
this->video_effects_menu = new VideoEffectsMenu(this->font_load_success, this->text_font);
this->input_menu = new InputMenu(this->font_load_success, this->text_font);
this->audio_device_menu = new AudioDeviceMenu(this->font_load_success, this->text_font);
this->separator_menu = new SeparatorMenu(this->font_load_success, this->text_font);
}
void WindowScreen::destroy_menus() {
@ -143,6 +144,7 @@ void WindowScreen::destroy_menus() {
delete this->video_effects_menu;
delete this->input_menu;
delete this->audio_device_menu;
delete this->separator_menu;
}
void WindowScreen::set_close(int ret_val) {
@ -378,7 +380,7 @@ void WindowScreen::rotation_change(int &value, bool right) {
void WindowScreen::force_same_scaling_change() {
this->m_info.force_same_scaling = !this->m_info.force_same_scaling;
this->prepare_size_ratios(true, true, false);
this->prepare_size_ratios(true, true);
this->future_operations.call_screen_settings_update = true;
}
@ -453,6 +455,51 @@ void WindowScreen::frame_blending_mode_change(bool positive) {
this->m_info.frame_blending_bot = this->m_info.frame_blending_top;
}
void WindowScreen::separator_size_change(int change) {
if(this->m_stype != ScreenType::JOINT)
return;
int new_size = this->m_info.separator_pixel_size + change;
if(new_size < 0)
new_size = 0;
if(new_size > MAX_SEP_SIZE)
new_size = MAX_SEP_SIZE;
if(new_size != this->m_info.separator_pixel_size) {
this->m_info.separator_pixel_size = new_size;
this->prepare_size_ratios(true, true);
this->future_operations.call_screen_settings_update = true;
}
}
void WindowScreen::separator_multiplier_change(bool positive, float& multiplier_to_check, float lower_limit, float upper_limit) {
if(this->m_stype != ScreenType::JOINT)
return;
float change = WINDOW_SCALING_CHANGE;
if(!positive)
change = -WINDOW_SCALING_CHANGE;
float new_value = multiplier_to_check + change;
if(new_value < lower_limit)
new_value = lower_limit;
if(new_value > upper_limit)
new_value = upper_limit;
if(new_value != multiplier_to_check) {
multiplier_to_check = new_value;
this->prepare_size_ratios(true, true);
this->future_operations.call_screen_settings_update = true;
}
}
void WindowScreen::separator_windowed_multiplier_change(bool positive) {
if(this->m_info.is_fullscreen)
return;
this->separator_multiplier_change(positive, this->m_info.separator_windowed_multiplier, SEP_WINDOW_SCALING_MIN_MULTIPLIER, MAX_WINDOW_SCALING_VALUE);
}
void WindowScreen::separator_fullscreen_multiplier_change(bool positive) {
if(!this->m_info.is_fullscreen)
return;
this->separator_multiplier_change(positive, this->m_info.separator_fullscreen_multiplier, SEP_FULLSCREEN_SCALING_MIN_MULTIPLIER, MAX_WINDOW_SCALING_VALUE);
}
bool WindowScreen::can_execute_cmd(const WindowCommand* window_cmd, bool is_extra, bool is_always) {
if((!window_cmd->usable_always) && is_always)
return false;
@ -1056,6 +1103,18 @@ void WindowScreen::setup_video_effects_menu(bool reset_data) {
}
}
void WindowScreen::setup_separator_menu(bool reset_data) {
if(!this->can_setup_menu())
return;
if(this->curr_menu != SEPARATOR_MENU_TYPE) {
this->curr_menu = SEPARATOR_MENU_TYPE;
if(reset_data)
this->separator_menu->reset_data();
this->separator_menu->insert_data(this->m_info.is_fullscreen);
this->last_menu_change_time = std::chrono::high_resolution_clock::now();
}
}
void WindowScreen::update_save_menu() {
if(this->curr_menu == SAVE_MENU_TYPE) {
this->curr_menu = DEFAULT_MENU_TYPE;
@ -1594,6 +1653,9 @@ void WindowScreen::poll(bool do_everything) {
case VIDEO_MENU_VIDEO_EFFECTS_SETTINGS:
this->setup_video_effects_menu();
break;
case VIDEO_MENU_SEPARATOR_SETTINGS:
this->setup_separator_menu();
break;
default:
break;
}
@ -2070,6 +2132,46 @@ void WindowScreen::poll(bool do_everything) {
continue;
}
break;
case SEPARATOR_MENU_TYPE:
if(this->separator_menu->poll(event_data)) {
switch(this->separator_menu->selected_index) {
case SEPARATOR_MENU_BACK:
this->setup_video_menu(false);
done = true;
break;
case SEPARATOR_MENU_NO_ACTION:
break;
case SEPARATOR_MENU_SIZE_DEC_1:
this->separator_size_change(-1);
break;
case SEPARATOR_MENU_SIZE_INC_1:
this->separator_size_change(1);
break;
case SEPARATOR_MENU_SIZE_DEC_10:
this->separator_size_change(-10);
break;
case SEPARATOR_MENU_SIZE_INC_10:
this->separator_size_change(10);
break;
case SEPARATOR_MENU_WINDOW_MUL_DEC:
this->separator_windowed_multiplier_change(false);
break;
case SEPARATOR_MENU_WINDOW_MUL_INC:
this->separator_windowed_multiplier_change(true);
break;
case SEPARATOR_MENU_FULLSCREEN_MUL_DEC:
this->separator_fullscreen_multiplier_change(false);
break;
case SEPARATOR_MENU_FULLSCREEN_MUL_INC:
this->separator_fullscreen_multiplier_change(true);
break;
default:
break;
}
this->separator_menu->reset_output_option();
continue;
}
break;
default:
break;
}
@ -2346,6 +2448,9 @@ void WindowScreen::prepare_menu_draws(int view_size_x, int view_size_y) {
case AUDIO_DEVICE_MENU_TYPE:
this->audio_device_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, this->audio_data->get_audio_output_device_data());
break;
case SEPARATOR_MENU_TYPE:
this->separator_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, &this->loaded_info);
break;
default:
break;
}
@ -2425,6 +2530,9 @@ void WindowScreen::execute_menu_draws() {
case AUDIO_DEVICE_MENU_TYPE:
this->audio_device_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win);
break;
case SEPARATOR_MENU_TYPE:
this->separator_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win);
break;
default:
break;
}

View File

@ -1,5 +1,5 @@
#include "frontend.hpp"
#include <iostream>
#include <cmath>
#include <thread>
#include <SFML/System.hpp>
@ -464,6 +464,9 @@ void reset_screen_info(ScreenInfo &info) {
info.window_enabled = false;
info.initial_pos_x = DEFAULT_NO_POS_WINDOW_VALUE;
info.initial_pos_y = DEFAULT_NO_POS_WINDOW_VALUE;
info.separator_pixel_size = DEFAULT_SEP_SIZE;
info.separator_windowed_multiplier = SEP_FOLLOW_SCALING_MULTIPLIER;
info.separator_fullscreen_multiplier = DEFAULT_WINDOW_SCALING_VALUE;
}
void override_set_data_to_screen_info(override_win_data &override_win, ScreenInfo &info) {
@ -612,6 +615,32 @@ bool load_screen_info(std::string key, std::string value, std::string base, Scre
info.force_same_scaling = std::stoi(value);
return true;
}
if(key == (base + "separator_pixel_size")) {
info.separator_pixel_size = std::stoi(value);
if(info.separator_pixel_size > MAX_SEP_SIZE)
info.separator_pixel_size = MAX_SEP_SIZE;
if(info.separator_pixel_size < 0)
info.separator_pixel_size = 0;
return true;
}
if(key == (base + "separator_windowed_multiplier")) {
info.separator_windowed_multiplier = std::stof(value);
if(info.separator_windowed_multiplier < SEP_WINDOW_SCALING_MIN_MULTIPLIER)
info.separator_windowed_multiplier = SEP_WINDOW_SCALING_MIN_MULTIPLIER;
if(info.separator_windowed_multiplier > MAX_WINDOW_SCALING_VALUE)
info.separator_windowed_multiplier = MAX_WINDOW_SCALING_VALUE;
info.separator_windowed_multiplier = std::round(info.separator_windowed_multiplier / WINDOW_SCALING_CHANGE) * WINDOW_SCALING_CHANGE;
return true;
}
if(key == (base + "separator_fullscreen_multiplier")) {
info.separator_fullscreen_multiplier = std::stof(value);
if(info.separator_fullscreen_multiplier < SEP_FULLSCREEN_SCALING_MIN_MULTIPLIER)
info.separator_fullscreen_multiplier = SEP_FULLSCREEN_SCALING_MIN_MULTIPLIER;
if(info.separator_fullscreen_multiplier > MAX_WINDOW_SCALING_VALUE)
info.separator_fullscreen_multiplier = MAX_WINDOW_SCALING_VALUE;
info.separator_fullscreen_multiplier = std::round(info.separator_fullscreen_multiplier / WINDOW_SCALING_CHANGE) * WINDOW_SCALING_CHANGE;
return true;
}
if(key == (base + "top_par")) {
info.top_par = std::stoi(value);
return true;
@ -713,6 +742,9 @@ std::string save_screen_info(std::string base, const ScreenInfo &info) {
out += base + "frame_blending_bot=" + std::to_string(info.frame_blending_bot) + "\n";
out += base + "window_enabled=" + std::to_string(info.window_enabled) + "\n";
out += base + "force_same_scaling=" + std::to_string(info.force_same_scaling) + "\n";
out += base + "separator_pixel_size=" + std::to_string(info.separator_pixel_size) + "\n";
out += base + "separator_windowed_multiplier=" + std::to_string(info.separator_windowed_multiplier) + "\n";
out += base + "separator_fullscreen_multiplier=" + std::to_string(info.separator_fullscreen_multiplier) + "\n";
return out;
}
@ -773,43 +805,6 @@ void get_par_size(float &width, float &height, float multiplier_factor, const PA
}
}
float get_par_mult_factor(float width, float height, float max_width, float max_height, const PARData *correction_factor, bool is_rotated) {
float correction_factor_divisor = correction_factor->width_multiplier;
float correction_factor_multiplier = correction_factor->width_divisor;
if(correction_factor->is_width_main) {
correction_factor_divisor = correction_factor->width_divisor;
correction_factor_multiplier = correction_factor->width_multiplier;
}
if(correction_factor->is_fit) {
if(correction_factor->is_width_main)
width = height * correction_factor_multiplier;
else
height = width * correction_factor_multiplier;
}
else {
if(correction_factor->is_width_main)
width = width * correction_factor_multiplier;
else
height = height * correction_factor_multiplier;
}
bool apply_to_max_width = correction_factor->is_width_main;
if(is_rotated) {
std::swap(width, height);
apply_to_max_width = !apply_to_max_width;
}
if(apply_to_max_width)
max_width = max_width * correction_factor_divisor;
else
max_height = max_height * correction_factor_divisor;
if((height == 0) || (width == 0))
return 0;
float factor_width = max_width / width;
float factor_height = max_height / height;
if(factor_height < factor_width)
return factor_height;
return factor_width;
}
JoystickDirection get_joystick_direction(uint32_t joystickId, sf::Joystick::Axis axis, float position) {
bool is_horizontal = false;
if((axis == sf::Joystick::Axis::Z) || (axis == sf::Joystick::Axis::R))