diff --git a/CMakeLists.txt b/CMakeLists.txt index 03aac61..cd76375 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ file(MAKE_DIRECTORY ${TOOLS_DATA_DIR}) set(OUTPUT_NAME cc3dsfs) add_executable(CMakeBin2C tools/bin2c.cpp) -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/3dscapture.cpp source/conversions.cpp source/ConnectionMenu.cpp source/OptionSelectionMenu.cpp source/MainMenu.cpp source/VideoMenu.cpp source/CropMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp) +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/3dscapture.cpp source/conversions.cpp source/ConnectionMenu.cpp source/OptionSelectionMenu.cpp source/MainMenu.cpp source/VideoMenu.cpp source/CropMenu.cpp source/PARMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp) add_dependencies(${OUTPUT_NAME} FTD3XX_BUILD_PROJECT CMakeBin2C) target_link_libraries(${OUTPUT_NAME} PRIVATE sfml-graphics sfml-audio sfml-window sfml-system ${ftd3xx_BINARY_DIR}/${FTD3XX_SUBFOLDER}/${FTD3XX_LIB}) target_link_directories(${OUTPUT_NAME} PRIVATE ${ftd3xx_BINARY_DIR}/${FTD3XX_SUBFOLDER}) diff --git a/include/PARMenu.hpp b/include/PARMenu.hpp new file mode 100755 index 0000000..f2c300d --- /dev/null +++ b/include/PARMenu.hpp @@ -0,0 +1,32 @@ +#ifndef __PARMENU_HPP +#define __PARMENU_HPP + +#include "OptionSelectionMenu.hpp" +#include + +#include "TextRectangle.hpp" +#include "sfml_gfx_structs.hpp" +#include "display_structs.hpp" + +#define PAR_MENU_NO_ACTION -1 +#define PAR_MENU_BACK -2 + +class PARMenu : public OptionSelectionMenu { +public: + PARMenu(bool font_load_success, sf::Font &text_font); + ~PARMenu(); + void setup_title(std::string added_name); + void prepare(float scaling_factor, int view_size_x, int view_size_y, int current_crop); + void insert_data(std::vector* possible_pars); + int selected_index = PAR_MENU_NO_ACTION; +protected: + void reset_output_option(); + void set_output_option(int index); + int get_num_options(); + std::string get_string_option(int index); + void class_setup(); +private: + const std::string base_name = "PAR Settings"; + std::vector* possible_pars; +}; +#endif diff --git a/include/display_structs.hpp b/include/display_structs.hpp index 15c86f9..4e874f4 100755 --- a/include/display_structs.hpp +++ b/include/display_structs.hpp @@ -7,7 +7,7 @@ enum ScreenType { TOP, BOTTOM, JOINT }; enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END }; enum OffsetAlgorithm { NO_DISTANCE, HALF_DISTANCE, MAX_DISTANCE, OFF_ALGO_END }; -enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_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 }; struct ScreenInfo { bool is_blurred; diff --git a/include/frontend.hpp b/include/frontend.hpp index 0f1c280..ea7dd2a 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -16,6 +16,7 @@ #include "MainMenu.hpp" #include "VideoMenu.hpp" #include "CropMenu.hpp" +#include "PARMenu.hpp" #include "display_structs.hpp" class WindowScreen { @@ -82,6 +83,7 @@ private: MainMenu *main_menu; VideoMenu *video_menu; CropMenu *crop_menu; + PARMenu *par_menu; std::vector possible_crops; std::vector possible_pars; @@ -128,6 +130,7 @@ private: void poll_window(); void padding_change(); void crop_value_change(int new_crop_value); + void par_value_change(int new_par_value, bool is_top); bool common_poll(SFEvent &event_data); bool main_poll(SFEvent &event_data); bool no_menu_poll(SFEvent &event_data); @@ -159,6 +162,7 @@ private: void setup_main_menu(); void setup_video_menu(); void setup_crop_menu(); + void setup_par_menu(bool is_top); void update_connection(); }; diff --git a/source/OptionSelectionMenu.cpp b/source/OptionSelectionMenu.cpp index 143ee65..950f501 100755 --- a/source/OptionSelectionMenu.cpp +++ b/source/OptionSelectionMenu.cpp @@ -454,7 +454,7 @@ void OptionSelectionMenu::base_prepare(float menu_scaling_factor, int view_size_ int top_divisor = 1; int title_start_x = 0; if(this->future_enabled_labels[this->title_center_id]) { - top_divisor = 5; + top_divisor = 6; title_start_x = 1; } int num_rendered_y = 0; diff --git a/source/PARMenu.cpp b/source/PARMenu.cpp new file mode 100755 index 0000000..8d40f90 --- /dev/null +++ b/source/PARMenu.cpp @@ -0,0 +1,70 @@ +#include "PARMenu.hpp" + +PARMenu::PARMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){ + this->initialize(font_load_success, text_font); +} + +PARMenu::~PARMenu() { +} + +void PARMenu::class_setup() { + this->num_elements_per_screen = 5; + this->min_elements_text_scaling_factor = num_elements_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 = this->base_name; + this->show_back_x = true; + this->show_x = false; + this->show_title = true; +} + +void PARMenu::setup_title(std::string added_name) { + this->title = added_name + (added_name != "" ? " " : "") + this->base_name; +} + +void PARMenu::insert_data(std::vector* possible_pars) { + this->possible_pars = possible_pars; + this->prepare_options(); +} + +void PARMenu::reset_output_option() { + this->selected_index = PAR_MENU_NO_ACTION; +} + +void PARMenu::set_output_option(int index) { + if(index == -1) + this->selected_index = PAR_MENU_BACK; + else + this->selected_index = index; +} + +int PARMenu::get_num_options() { + return (*this->possible_pars).size(); +} + +std::string PARMenu::get_string_option(int index) { + return (*this->possible_pars)[index]->name; +} + +void PARMenu::prepare(float menu_scaling_factor, int view_size_x, int view_size_y, int current_par) { + 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_elements_per_screen; + for(int i = 0; i < this->num_elements_per_screen; i++) { + int index = i + this->elements_start_id; + if(!this->future_enabled_labels[index]) + continue; + int par_index = start + i; + if(par_index == current_par) + this->labels[index]->setText("<" + (*this->possible_pars)[par_index]->name + ">"); + else + this->labels[index]->setText((*this->possible_pars)[par_index]->name); + } + this->base_prepare(menu_scaling_factor, view_size_x, view_size_y); +} diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index a6feca0..002a0d0 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -24,6 +24,7 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp this->main_menu = new MainMenu(this->font_load_success, this->text_font); this->video_menu = new VideoMenu(this->font_load_success, this->text_font); this->crop_menu = new CropMenu(this->font_load_success, this->text_font); + this->par_menu = new PARMenu(this->font_load_success, this->text_font); this->in_tex.create(IN_VIDEO_WIDTH, IN_VIDEO_HEIGHT); this->m_in_rect_top.setTexture(&this->in_tex); this->m_in_rect_bot.setTexture(&this->in_tex); @@ -125,10 +126,40 @@ void WindowScreen::padding_change() { } void WindowScreen::crop_value_change(int new_crop_value) { - this->m_info.crop_kind = new_crop_value % this->possible_crops.size(); - this->print_notification("Crop: " + this->possible_crops[this->m_info.crop_kind]->name); - this->prepare_size_ratios(false, false); - this->future_operations.call_crop = true; + int new_value = new_crop_value % this->possible_crops.size(); + if(this->m_info.crop_kind != new_value) { + this->m_info.crop_kind = new_value; + this->print_notification("Crop: " + this->possible_crops[this->m_info.crop_kind]->name); + this->prepare_size_ratios(false, false); + this->future_operations.call_crop = true; + } +} + +void WindowScreen::par_value_change(int new_par_value, bool is_top) { + if(((!is_top) && (this->m_stype == ScreenType::TOP)) || ((is_top) && (this->m_stype == ScreenType::BOTTOM))) + return; + int par_index = new_par_value % this->possible_pars.size(); + std::string setting_name = "PAR: "; + bool updated = false; + if(is_top) { + if(this->m_info.top_par != par_index) + updated = true; + this->m_info.top_par = par_index; + if(this->m_stype == ScreenType::JOINT) + setting_name = "Top " + setting_name; + } + else { + if(this->m_info.bot_par != par_index) + updated = true; + this->m_info.bot_par = par_index; + if(this->m_stype == ScreenType::JOINT) + setting_name = "Bottom " + setting_name; + } + if(updated) { + this->prepare_size_ratios(false, false); + this->future_operations.call_screen_settings_update = true; + this->print_notification(setting_name + this->possible_pars[par_index]->name); + } } bool WindowScreen::common_poll(SFEvent &event_data) { @@ -279,6 +310,23 @@ void WindowScreen::setup_crop_menu() { } } +void WindowScreen::setup_par_menu(bool is_top) { + CurrMenuType wanted_type = TOP_PAR_MENU_TYPE; + if(!is_top) + wanted_type = BOTTOM_PAR_MENU_TYPE; + if(this->curr_menu != wanted_type) { + this->curr_menu = wanted_type; + this->par_menu->reset_data(); + std::string title_piece = ""; + if((is_top) && (this->m_stype == ScreenType::JOINT)) + title_piece = "Top"; + else if((!is_top) && (this->m_stype == ScreenType::JOINT)) + title_piece = "Bot."; + this->par_menu->setup_title(title_piece); + this->par_menu->insert_data(&this->possible_pars); + } +} + bool WindowScreen::no_menu_poll(SFEvent &event_data) { bool consumed = true; switch(event_data.type) { @@ -437,23 +485,11 @@ bool WindowScreen::main_poll(SFEvent &event_data) { break; case '2': - if(this->m_stype == ScreenType::BOTTOM) - break; - this->m_info.top_par = (this->m_info.top_par + 1) % this->possible_pars.size(); - this->prepare_size_ratios(false, false); - this->future_operations.call_screen_settings_update = true; - this->print_notification("Top PAR: " + this->possible_pars[this->m_info.top_par]->name); - + this->par_value_change(this->m_info.top_par + 1, true); break; case '3': - if(this->m_stype == ScreenType::TOP) - break; - this->m_info.bot_par = (this->m_info.bot_par + 1) % this->possible_pars.size(); - this->prepare_size_ratios(false, false); - this->future_operations.call_screen_settings_update = true; - this->print_notification("Bottom PAR: " + this->possible_pars[this->m_info.bot_par]->name); - + this->par_value_change(this->m_info.bot_par + 1, false); break; case 'm': @@ -607,6 +643,15 @@ void WindowScreen::poll() { case VIDEO_MENU_CROPPING: this->setup_crop_menu(); return; + case VIDEO_MENU_TOP_PAR: + this->setup_par_menu(true); + return; + case VIDEO_MENU_BOT_PAR: + this->setup_par_menu(false); + return; + case VIDEO_MENU_ONE_PAR: + this->setup_par_menu(this->m_stype == ScreenType::TOP); + return; default: break; } @@ -629,6 +674,38 @@ void WindowScreen::poll() { continue; } break; + case TOP_PAR_MENU_TYPE: + if(this->par_menu->poll(event_data)) { + switch(this->par_menu->selected_index) { + case PAR_MENU_BACK: + this->setup_video_menu(); + return; + case PAR_MENU_NO_ACTION: + break; + default: + this->par_value_change(this->par_menu->selected_index, true); + break; + } + this->par_menu->selected_index = PAR_MENU_NO_ACTION; + continue; + } + break; + case BOTTOM_PAR_MENU_TYPE: + if(this->par_menu->poll(event_data)) { + switch(this->par_menu->selected_index) { + case PAR_MENU_BACK: + this->setup_video_menu(); + return; + case PAR_MENU_NO_ACTION: + break; + default: + this->par_value_change(this->par_menu->selected_index, false); + break; + } + this->par_menu->selected_index = PAR_MENU_NO_ACTION; + continue; + } + break; default: break; } @@ -727,6 +804,12 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) { case CROP_MENU_TYPE: this->crop_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, this->loaded_info.crop_kind); break; + case TOP_PAR_MENU_TYPE: + this->par_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, this->loaded_info.top_par); + break; + case BOTTOM_PAR_MENU_TYPE: + this->par_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, this->loaded_info.bot_par); + break; default: break; } @@ -1031,6 +1114,12 @@ void WindowScreen::display_data_to_window(bool actually_draw) { case CROP_MENU_TYPE: this->crop_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win); break; + case TOP_PAR_MENU_TYPE: + this->par_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win); + break; + case BOTTOM_PAR_MENU_TYPE: + this->par_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win); + break; default: break; }