diff --git a/CMakeLists.txt b/CMakeLists.txt index 35425a6..823736a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -543,7 +543,7 @@ else() set_source_files_properties(source/conversions.cpp PROPERTIES COMPILE_OPTIONS "$<$:-O3;-funroll-loops>") endif() -set(EXECUTABLE_SOURCE_FILES source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/TextRectanglePool.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/PartnerCTRMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp source/Menus/SeparatorMenu.cpp source/Menus/ColorCorrectionMenu.cpp source/Menus/Main3DMenu.cpp source/Menus/SecondScreen3DRelativePositionMenu.cpp source/Menus/USBConflictResolutionMenu.cpp source/Menus/Optimize3DSMenu.cpp source/Menus/OptimizeSerialKeyAddMenu.cpp source/Menus/OptimizeOldFWConfigMenu.cpp source/libgpiod_compat.cpp ${TOOLS_DATA_DIR}/optimize_serial_key_add_table.cpp ${TOOLS_DATA_DIR}/optimize_serial_key_next_char_table.cpp ${TOOLS_DATA_DIR}/optimize_serial_key_prev_char_table.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/font_mono_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES}) +set(EXECUTABLE_SOURCE_FILES source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/TextRectanglePool.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/PartnerCTRMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp source/Menus/SeparatorMenu.cpp source/Menus/ColorCorrectionMenu.cpp source/Menus/Main3DMenu.cpp source/Menus/SecondScreen3DRelativePositionMenu.cpp source/Menus/USBConflictResolutionMenu.cpp source/Menus/Optimize3DSMenu.cpp source/Menus/Optimize3DSDowngradeV2Menu.cpp source/Menus/OptimizeSerialKeyAddMenu.cpp source/Menus/OptimizeOldFWConfigMenu.cpp source/libgpiod_compat.cpp ${TOOLS_DATA_DIR}/optimize_serial_key_add_table.cpp ${TOOLS_DATA_DIR}/optimize_serial_key_next_char_table.cpp ${TOOLS_DATA_DIR}/optimize_serial_key_prev_char_table.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/font_mono_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES}) if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") add_compile_flag("SFML_SYSTEM_ANDROID") diff --git a/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.hpp b/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.hpp index d472140..bb923ee 100644 --- a/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.hpp +++ b/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.hpp @@ -24,6 +24,7 @@ bool is_device_optimize_3ds(CaptureDevice* device); bool is_device_optimize_o3ds(CaptureDevice* device); bool is_device_optimize_n3ds(CaptureDevice* device); bool is_device_optimize_o2ds(CaptureDevice* device); +bool is_device_optimize_n3dsv2(CaptureDevice* device); bool is_device_optimize_old_fw(CaptureDevice* device); bool cyop_is_key_for_device_id(CaptureDevice* device, std::string key); KeySaveError add_key_to_file(std::string key, bool is_for_new_3ds); diff --git a/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.hpp b/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.hpp index 2ee48a0..745875f 100644 --- a/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.hpp +++ b/include/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.hpp @@ -12,6 +12,8 @@ enum cypress_optimize_device_type { CYPRESS_OPTIMIZE_NEW_3DS_BLANK_DEVICE, CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE, + CYPRESS_OPTIMIZE_NEW_3DSV2_BLANK_DEVICE, + CYPRESS_OPTIMIZE_NEW_3DSV2_INSTANTIATED_DEVICE, CYPRESS_OPTIMIZE_OLD_3DS_BLANK_DEVICE, CYPRESS_OPTIMIZE_OLD_3DS_INSTANTIATED_DEVICE, CYPRESS_OPTIMIZE_OLD_OLD_2DS_BLANK_DEVICE, @@ -29,6 +31,7 @@ struct cyop_device_usb_device { uint8_t* fpga_pl_888; size_t fpga_pl_888_size; bool is_new_device; + bool has_eeprom; bool is_old_firmware; bool is_o2ds; cypress_optimize_device_type next_device; @@ -56,5 +59,7 @@ bool check_key_matches_device_id(uint64_t device_id, std::string key, bool is_ne bool check_key_matches_device_id(uint64_t device_id, std::string key, const cyop_device_usb_device* device); bool check_key_valid(std::string key, bool is_new_device); bool check_key_valid(std::string key, const cyop_device_usb_device* device); +int set_eeprom_boot_id_n3ds(cy_device_device_handlers* handlers, const cyop_device_usb_device* device); +int remove_eeprom_boot_id(cy_device_device_handlers* handlers, const cyop_device_usb_device* device); #endif diff --git a/include/Menus/Optimize3DSDowngradeV2Menu.hpp b/include/Menus/Optimize3DSDowngradeV2Menu.hpp new file mode 100644 index 0000000..a069029 --- /dev/null +++ b/include/Menus/Optimize3DSDowngradeV2Menu.hpp @@ -0,0 +1,37 @@ +#ifndef __OPTIMIZE3DSDOWNGRADEV2MENU_HPP +#define __OPTIMIZE3DSDOWNGRADEV2MENU_HPP + +#include "OptionSelectionMenu.hpp" +#include + +#include "TextRectangle.hpp" +#include "sfml_gfx_structs.hpp" +#include "display_structs.hpp" +#include "capture_structs.hpp" + +enum Optimize3DSDowngradeV2MenuOutAction{ + OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION, + OPTIMIZE3DS_DOWNGRADEV2_MENU_BACK, + OPTIMIZE3DS_DOWNGRADEV2_MENU_CONFIRM, +}; + +class Optimize3DSDowngradeV2Menu : public OptionSelectionMenu { +public: + Optimize3DSDowngradeV2Menu(TextRectanglePool* text_pool); + ~Optimize3DSDowngradeV2Menu(); + void prepare(float scaling_factor, int view_size_x, int view_size_y); + void insert_data(); + Optimize3DSDowngradeV2MenuOutAction selected_index = Optimize3DSDowngradeV2MenuOutAction::OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION; + void reset_output_option(); +protected: + bool is_option_selectable(int index, int action); + bool is_option_inc_dec(int index); + void set_output_option(int index, int action); + size_t get_num_options(); + std::string get_string_option(int index, int action); + void class_setup(); +private: + int *options_indexes; + size_t num_enabled_options; +}; +#endif diff --git a/include/Menus/Optimize3DSMenu.hpp b/include/Menus/Optimize3DSMenu.hpp index b7e5922..84f375b 100644 --- a/include/Menus/Optimize3DSMenu.hpp +++ b/include/Menus/Optimize3DSMenu.hpp @@ -21,6 +21,8 @@ enum Optimize3DSMenuOutAction{ OPTIMIZE3DS_MENU_OPTIMIZE_SERIAL_KEY, OPTIMIZE3DS_MENU_OPTIMIZE_SERIAL_KEY_MENU, OPTIMIZE3DS_MENU_OLD_FW_SETTINGS_MENU, + OPTIMIZE3DS_MENU_N3DS_DOWNGRADEV2_MENU, + OPTIMIZE3DS_MENU_N3DSV2_UPGRADE_MENU, }; class Optimize3DSMenu : public OptionSelectionMenu { diff --git a/include/capture_structs.hpp b/include/capture_structs.hpp index 3edfc65..d3f57d6 100755 --- a/include/capture_structs.hpp +++ b/include/capture_structs.hpp @@ -28,7 +28,7 @@ enum CaptureConnectionType { CAPTURE_CONN_FTD3, CAPTURE_CONN_USB, CAPTURE_CONN_F enum InputVideoDataType { VIDEO_DATA_RGB, VIDEO_DATA_BGR, VIDEO_DATA_RGB16, VIDEO_DATA_BGR16 }; enum CaptureScreensType { CAPTURE_SCREENS_BOTH, CAPTURE_SCREENS_TOP, CAPTURE_SCREENS_BOTTOM, CAPTURE_SCREENS_ENUM_END }; enum CaptureSpeedsType { CAPTURE_SPEEDS_FULL, CAPTURE_SPEEDS_HALF, CAPTURE_SPEEDS_THIRD, CAPTURE_SPEEDS_QUARTER, CAPTURE_SPEEDS_ENUM_END }; -enum PossibleCaptureDevices { CC_LOOPY_OLD_DS, CC_LOOPY_NEW_DS, CC_LOOPY_OLD_3DS, CC_LOOPY_NEW_N3DSXL, CC_IS_NITRO_EMULATOR, CC_IS_NITRO_CAPTURE, CC_IS_TWL_CAPTURE, CC_NISETRO_DS, CC_OPTIMIZE_O3DS, CC_OPTIMIZE_N3DS, CC_OPTIMIZE_O_O2DS, CC_PARTNER_CTR, CC_POSSIBLE_DEVICES_END }; +enum PossibleCaptureDevices { CC_LOOPY_OLD_DS, CC_LOOPY_NEW_DS, CC_LOOPY_OLD_3DS, CC_LOOPY_NEW_N3DSXL, CC_IS_NITRO_EMULATOR, CC_IS_NITRO_CAPTURE, CC_IS_TWL_CAPTURE, CC_NISETRO_DS, CC_OPTIMIZE_O3DS, CC_OPTIMIZE_N3DS, CC_OPTIMIZE_N3DSV2, CC_OPTIMIZE_O_O2DS, CC_PARTNER_CTR, CC_POSSIBLE_DEVICES_END }; // Readers are Audio and Video. So 2. // Use 6 extra buffers. 5 for async writing in case the other 2 are busy, @@ -422,6 +422,8 @@ struct CaptureStatusOptimize { bool request_low_bw_format = true; bool request_low_bw_format_old_2ds = false; bool key_updated = false; + bool request_optimize_n3ds_downgradev2 = false; + bool request_optimize_n3dsv2_upgrade = false; CaptureOptimizeOldFirmwareConfig old_fw_config_full_bw_format = {}; CaptureOptimizeOldFirmwareConfig old_fw_config_low_bw_format = {}; }; diff --git a/include/display_structs.hpp b/include/display_structs.hpp index ee5e401..5a67209 100755 --- a/include/display_structs.hpp +++ b/include/display_structs.hpp @@ -26,7 +26,7 @@ enum ScreenType { TOP, BOTTOM, JOINT }; enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END }; enum SecondScreen3DRelativePosition { UNDER_FIRST, LEFT_FIRST, ABOVE_FIRST, RIGHT_FIRST, SECOND_SCREEN_3D_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, SEPARATOR_MENU_TYPE, COLOR_CORRECTION_MENU_TYPE, MAIN_3D_MENU_TYPE, SECOND_SCREEN_RELATIVE_POS_MENU_TYPE, USB_CONFLICT_RESOLUTION_MENU_TYPE, OPTIMIZE_3DS_MENU_TYPE, OPTIMIZE_SERIAL_KEY_ADD_MENU_TYPE, OPTIMIZE_OLD_FW_CONFIG_MENU, RECONNECT_MENU_TYPE, PARTNER_CTR_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, COLOR_CORRECTION_MENU_TYPE, MAIN_3D_MENU_TYPE, SECOND_SCREEN_RELATIVE_POS_MENU_TYPE, USB_CONFLICT_RESOLUTION_MENU_TYPE, OPTIMIZE_3DS_MENU_TYPE, OPTIMIZE_SERIAL_KEY_ADD_MENU_TYPE, OPTIMIZE_OLD_FW_CONFIG_MENU, OPTIMIZE_3DS_DOWNGRADEV2_MENU_TYPE, RECONNECT_MENU_TYPE, PARTNER_CTR_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 }; diff --git a/include/frontend.hpp b/include/frontend.hpp index cfa750b..52b0838 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -44,6 +44,7 @@ #include "Optimize3DSMenu.hpp" #include "OptimizeSerialKeyAddMenu.hpp" #include "OptimizeOldFWConfigMenu.hpp" +#include "Optimize3DSDowngradeV2Menu.hpp" #include "display_structs.hpp" #include "event_structs.hpp" #include "shaders_list.hpp" @@ -214,6 +215,7 @@ private: Optimize3DSMenu* optimize_3ds_menu; OptimizeSerialKeyAddMenu* optimize_serial_key_add_menu; OptimizeOldFWConfigMenu* optimize_old_fw_config_menu; + Optimize3DSDowngradeV2Menu* optimize_3ds_downgradev2_menu; std::vector possible_crops; std::vector possible_crops_ds; @@ -439,6 +441,7 @@ private: void setup_optimize_3ds_menu(bool reset_data = true); void setup_optimize_serial_key_add_menu(bool reset_data = true); void setup_optimize_old_fw_config_menu(bool reset_data = true); + void setup_optimize_n3ds_downgradev2_menu(bool reset_data = true); void update_connection(); bool has_menu_textbox(); }; diff --git a/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.cpp b/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.cpp index eb9647c..8d57b7c 100644 --- a/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.cpp +++ b/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_acquisition.cpp @@ -310,6 +310,10 @@ bool is_device_optimize_n3ds(CaptureDevice* device) { return does_device_match_type(device, CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE); } +bool is_device_optimize_n3dsv2(CaptureDevice* device) { + return does_device_match_type(device, CYPRESS_OPTIMIZE_NEW_3DSV2_INSTANTIATED_DEVICE); +} + static InputVideoDataType extract_wanted_input_video_data_type(CaptureStatus* capture_status) { const cyop_device_usb_device* usb_device_info = (const cyop_device_usb_device*)capture_status->device.descriptor; if(usb_device_info->is_o2ds) @@ -1030,6 +1034,8 @@ static bool cyop_device_acquisition_loop(CaptureData* capture_data, CypressOptim int ret = capture_start(handlers, usb_device_desc, true, stored_video_data_type == OPTIMIZE_RGB888_FORMAT, device_id, read_key); capture_data->status.title_check_id += 1; capture_data->status.device_specific_status.optimize_status.key_updated = false; + capture_data->status.device_specific_status.optimize_status.request_optimize_n3ds_downgradev2 = false; + capture_data->status.device_specific_status.optimize_status.request_optimize_n3dsv2_upgrade = false; std::chrono::time_point clock_last_capture_start = std::chrono::high_resolution_clock::now(); std::chrono::time_point clock_last_param_edit = std::chrono::high_resolution_clock::now(); @@ -1080,12 +1086,32 @@ static bool cyop_device_acquisition_loop(CaptureData* capture_data, CypressOptim bool is_new_3d = could_use_3d && get_3d_enabled(&capture_data->status); bool present_new_old_fw_config = are_there_changes_present_to_old_fw_config(capture_data, stored_video_data_type, stored_old_fw_cfg_full, stored_old_fw_cfg_limited); + bool n3ds_downgradev2 = is_device_optimize_n3ds(&capture_data->status.device) && capture_data->status.device_specific_status.optimize_status.request_optimize_n3ds_downgradev2; + bool n3dsv2_upgrade = false && is_device_optimize_n3dsv2(&capture_data->status.device) && capture_data->status.device_specific_status.optimize_status.request_optimize_n3dsv2_upgrade; InputVideoDataType wanted_input_video_data_type = extract_wanted_input_video_data_type(capture_data); force_capture_start_key = (!is_key_valid) && (!check_key_matches_device_id(device_id, read_key, usb_device_desc)) && key_missing_capture_start_again_check_time(clock_last_capture_start); - if((wanted_input_video_data_type != stored_video_data_type) || (is_new_3d != stored_is_3d) || force_capture_start_key || capture_data->status.device_specific_status.optimize_status.key_updated || present_new_old_fw_config) { + if((wanted_input_video_data_type != stored_video_data_type) || (is_new_3d != stored_is_3d) || force_capture_start_key || capture_data->status.device_specific_status.optimize_status.key_updated || present_new_old_fw_config || n3ds_downgradev2 || n3dsv2_upgrade) { capture_data->status.cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM + NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; wait_all_cypress_device_buffers_free(capture_data, cypress_device_capture_recv_data); cyop_key_check_and_interrogate_file(&capture_data->status, usb_device_desc, device_id, is_key_valid, read_key); + if(n3ds_downgradev2) { + ret = remove_eeprom_boot_id(handlers, usb_device_desc); + capture_data->status.device_specific_status.optimize_status.request_optimize_n3ds_downgradev2 = false; + if(ret < 0) { + capture_error_print(true, capture_data, "Disconnected: Boot param removal error"); + return false; + } + capture_warning_print(capture_data, "Downgraded device to V2\nPlease reconnect to the USB\nport to see changes"); + } + if(n3dsv2_upgrade) { + ret = set_eeprom_boot_id_n3ds(handlers, usb_device_desc); + capture_data->status.device_specific_status.optimize_status.request_optimize_n3dsv2_upgrade = false; + if(ret < 0) { + capture_error_print(true, capture_data, "Disconnected: Boot param storage error"); + return false; + } + capture_warning_print(capture_data, "Upgraded device to V1\nPlease reconnect to the USB\nport to see changes"); + } ret = restart_captures_cc_reads(capture_data, cypress_device_capture_recv_data, device_id, index, stored_video_data_type, stored_is_3d, could_use_3d, stored_old_fw_cfg_full, stored_old_fw_cfg_limited, force_capture_start_key, read_key, clock_last_capture_start, clock_last_param_edit); if(ret < 0) { capture_error_print(true, capture_data, "Disconnected: Update mode error"); diff --git a/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.cpp b/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.cpp index 5d38a52..f1b157b 100644 --- a/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.cpp +++ b/source/CaptureDeviceSpecific/Optimize_3DS/cypress_optimize_3ds_communications.cpp @@ -44,6 +44,7 @@ #define OPTIMIZE_NEW_3DS_WANTED_VALUE_BASE 0xFE00 #define OPTIMIZE_OLD_3DS_WANTED_VALUE_BASE 0xFD00 #define OPTIMIZE_OLD_2DS_2014_WANTED_VALUE_BASE 0xFB00 +#define OPTIMIZE_NEW_3DSV2_WANTED_VALUE_BASE 0xFA00 #define OPTIMIZE_NUM_KEY_CHARS SERIAL_KEY_OPTIMIZE_NO_DASHES_SIZE #define OPTIMIZE_NUM_KEY_CHARS_WITH_DASHES SERIAL_KEY_OPTIMIZE_WITH_DASHES_SIZE @@ -51,6 +52,11 @@ #define OPTIMIZE_EEPROM_NEW_SIZE 0x80 #define OPTIMIZE_EEPROM_STRUCT_SIZE 0x79 +#define OPTIMIZE_EEPROM_CRC_POS 0x7C +#define OPTIMIZE_EEPROM_OPERATION_SIZE 0x10 + +#define OPTIMIZE_N3DS_VID 0x0752 +#define OPTIMIZE_N3DS_PID 0x8613 const size_t key_bytes_to_serial_bytes_map[OPTIMIZE_NUM_KEY_BYTES] = {0, 7, 8, 9, 1, 4, 6, 3, 10, 2, 11, 5}; @@ -71,12 +77,13 @@ static const cyop_device_usb_device cypress_optimize_new_3ds_generic_device = { .firmware_to_load = optimize_new_3ds_fw, .firmware_size = optimize_new_3ds_fw_len, .fpga_pl_565 = NULL, .fpga_pl_565_size = 0, .fpga_pl_888 = NULL, .fpga_pl_888_size = 0, -.is_new_device = true, .is_old_firmware = false, .is_o2ds = false, +.is_new_device = true, .has_eeprom = true, +.is_old_firmware = false, .is_o2ds = false, .next_device = CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE, .has_bcd_device_serial = false, .index_in_allowed_scan = CC_OPTIMIZE_N3DS, .usb_device_info = { - .vid = 0x0752, .pid = 0x8613, + .vid = OPTIMIZE_N3DS_VID, .pid = OPTIMIZE_N3DS_PID, .default_config = 1, .default_interface = 0, .bulk_timeout = 500, .ep_ctrl_bulk_in = 0, .ep_ctrl_bulk_out = 0, @@ -99,7 +106,8 @@ static const cyop_device_usb_device cypress_optimize_new_3ds_instantiated_device .firmware_to_load = NULL, .firmware_size = 0, .fpga_pl_565 = optimize_new_3ds_565_fpga_pl, .fpga_pl_565_size = optimize_new_3ds_565_fpga_pl_len, .fpga_pl_888 = optimize_new_3ds_888_fpga_pl, .fpga_pl_888_size = optimize_new_3ds_888_fpga_pl_len, -.is_new_device = true, .is_old_firmware = false, .is_o2ds = false, +.is_new_device = true, .has_eeprom = true, +.is_old_firmware = false, .is_o2ds = false, .next_device = CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE, .has_bcd_device_serial = true, .index_in_allowed_scan = CC_OPTIMIZE_N3DS, @@ -127,7 +135,8 @@ static const cyop_device_usb_device cypress_optimize_old_3ds_generic_device = { .firmware_to_load = optimize_old_3ds_fw, .firmware_size = optimize_old_3ds_fw_len, .fpga_pl_565 = NULL, .fpga_pl_565_size = 0, .fpga_pl_888 = NULL, .fpga_pl_888_size = 0, -.is_new_device = false, .is_old_firmware = false, .is_o2ds = false, +.is_new_device = false, .has_eeprom = false, +.is_old_firmware = false, .is_o2ds = false, .next_device = CYPRESS_OPTIMIZE_OLD_3DS_INSTANTIATED_DEVICE, .has_bcd_device_serial = false, .index_in_allowed_scan = CC_OPTIMIZE_O3DS, @@ -155,7 +164,8 @@ static const cyop_device_usb_device cypress_optimize_old_3ds_instantiated_device .firmware_to_load = NULL, .firmware_size = 0, .fpga_pl_565 = optimize_old_3ds_565_fpga_pl, .fpga_pl_565_size = optimize_old_3ds_565_fpga_pl_len, .fpga_pl_888 = optimize_old_3ds_888_fpga_pl, .fpga_pl_888_size = optimize_old_3ds_888_fpga_pl_len, -.is_new_device = false, .is_old_firmware = false, .is_o2ds = false, +.is_new_device = false, .has_eeprom = false, +.is_old_firmware = false, .is_o2ds = false, .next_device = CYPRESS_OPTIMIZE_OLD_3DS_INSTANTIATED_DEVICE, .has_bcd_device_serial = true, .index_in_allowed_scan = CC_OPTIMIZE_O3DS, @@ -183,7 +193,8 @@ static const cyop_device_usb_device cypress_optimize_old_old_2ds_generic_device .firmware_to_load = optimize_old_2ds_2014_fw, .firmware_size = optimize_old_2ds_2014_fw_len, .fpga_pl_565 = NULL, .fpga_pl_565_size = 0, .fpga_pl_888 = NULL, .fpga_pl_888_size = 0, -.is_new_device = false, .is_old_firmware = true, .is_o2ds = true, +.is_new_device = false, .has_eeprom = false, +.is_old_firmware = true, .is_o2ds = true, .next_device = CYPRESS_OPTIMIZE_OLD_OLD_2DS_INSTANTIATED_DEVICE, .has_bcd_device_serial = false, .index_in_allowed_scan = CC_OPTIMIZE_O_O2DS, @@ -211,7 +222,8 @@ static const cyop_device_usb_device cypress_optimize_old_old_2ds_instantiated_de .firmware_to_load = NULL, .firmware_size = 0, .fpga_pl_565 = optimize_old_2ds_2014_565_fpga_pl, .fpga_pl_565_size = optimize_old_2ds_2014_565_fpga_pl_len, .fpga_pl_888 = optimize_old_2ds_2014_888_fpga_pl, .fpga_pl_888_size = optimize_old_2ds_2014_888_fpga_pl_len, -.is_new_device = false, .is_old_firmware = true, .is_o2ds = true, +.is_new_device = false, .has_eeprom = false, +.is_old_firmware = true, .is_o2ds = true, .next_device = CYPRESS_OPTIMIZE_OLD_OLD_2DS_INSTANTIATED_DEVICE, .has_bcd_device_serial = true, .index_in_allowed_scan = CC_OPTIMIZE_O_O2DS, @@ -426,7 +438,7 @@ bool reset_cpu(cy_device_device_handlers* handlers, const cyop_device_usb_device static bool is_eeprom_data_valid(uint8_t* eeprom_data) { uint32_t crc = calc_crc32_adler(eeprom_data, OPTIMIZE_EEPROM_STRUCT_SIZE); - return crc == read_le32(eeprom_data + 0x7C); + return crc == read_le32(eeprom_data + OPTIMIZE_EEPROM_CRC_POS); } static std::string extract_key_from_eeprom(uint8_t* eeprom_data) { @@ -438,7 +450,7 @@ static std::string extract_key_from_eeprom(uint8_t* eeprom_data) { } static int read_device_eeprom(cy_device_device_handlers* handlers, const cyop_device_usb_device* device, uint8_t* in_buffer, size_t read_size) { - const size_t read_block_size = 0x10; + const size_t read_block_size = OPTIMIZE_EEPROM_OPERATION_SIZE; const size_t num_reads = (read_size + read_block_size - 1) / read_block_size; int transferred = 0; int ret = 0; @@ -461,7 +473,7 @@ static int read_device_eeprom(cy_device_device_handlers* handlers, const cyop_de } static int write_device_eeprom(cy_device_device_handlers* handlers, const cyop_device_usb_device* device, uint8_t* out_buffer, size_t write_size) { - const size_t write_block_size = 0x10; + const size_t write_block_size = OPTIMIZE_EEPROM_OPERATION_SIZE; const size_t num_writes = (write_size + write_block_size - 1) / write_block_size; int transferred = 0; int ret = 0; @@ -486,6 +498,39 @@ static int write_device_eeprom(cy_device_device_handlers* handlers, const cyop_d return ret; } +static int set_eeprom_boot_id(cy_device_device_handlers* handlers, const cyop_device_usb_device* device, uint16_t vid, uint16_t pid, uint16_t device_id) { + uint8_t buffer[OPTIMIZE_EEPROM_NEW_SIZE]; + + int ret = read_device_eeprom(handlers, device, buffer, OPTIMIZE_EEPROM_NEW_SIZE); + if(ret < 0) + return ret; + + buffer[0] = 0xC0; //0xC0 makes it use the boot IDs we set + write_le16(buffer + 1, vid); + write_le16(buffer + 3, pid); + write_le16(buffer + 5, device_id); + write_le16(buffer + 7, 0); + + uint32_t crc = calc_crc32_adler(buffer, OPTIMIZE_EEPROM_STRUCT_SIZE); + write_le32(buffer + OPTIMIZE_EEPROM_CRC_POS, crc); + + return write_device_eeprom(handlers, device, buffer, OPTIMIZE_EEPROM_NEW_SIZE); +} + +int set_eeprom_boot_id_n3ds(cy_device_device_handlers* handlers, const cyop_device_usb_device* device) { + return set_eeprom_boot_id(handlers, device, OPTIMIZE_N3DS_VID, OPTIMIZE_N3DS_PID, 0); +} +int remove_eeprom_boot_id(cy_device_device_handlers* handlers, const cyop_device_usb_device* device) { + uint8_t buffer[OPTIMIZE_EEPROM_OPERATION_SIZE]; + + int ret = read_device_eeprom(handlers, device, buffer, OPTIMIZE_EEPROM_OPERATION_SIZE); + if(ret < 0) + return ret; + + buffer[0] = 0x00; //0xC0 and 0xC2 are reserved, writing 0x00 should remove the boot ID + return write_device_eeprom(handlers, device, buffer, OPTIMIZE_EEPROM_OPERATION_SIZE); +} + static uint64_t bytes_to_serial_device_id(uint8_t* in_buffer) { // From multiple dumps, this seems to be the algorithm. // There may be something missing. diff --git a/source/Menus/Optimize3DSDowngradeV2Menu.cpp b/source/Menus/Optimize3DSDowngradeV2Menu.cpp new file mode 100644 index 0000000..9079ff6 --- /dev/null +++ b/source/Menus/Optimize3DSDowngradeV2Menu.cpp @@ -0,0 +1,140 @@ +#include "Optimize3DSDowngradeV2Menu.hpp" +#include "cypress_optimize_3ds_acquisition.hpp" + +#define NUM_TOTAL_MENU_OPTIONS (sizeof(pollable_options)/sizeof(pollable_options[0])) + +struct Optimize3DSDowngradeV2MenuOptionInfo { + const std::string base_name; + const bool is_selectable; + const bool is_inc; + const std::string dec_str; + const std::string inc_str; + const Optimize3DSDowngradeV2MenuOutAction inc_out_action; + const Optimize3DSDowngradeV2MenuOutAction out_action; +}; + +static const Optimize3DSDowngradeV2MenuOptionInfo optimize_n3ds_downgrade_desc1_menu = { +.base_name = "This operation removes the", .is_selectable = false, +.is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION, +.out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION}; + +static const Optimize3DSDowngradeV2MenuOptionInfo optimize_n3ds_downgrade_desc2_menu = { +.base_name = "Capture Card EEPROM config.", .is_selectable = false, +.is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION, +.out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION}; + +static const Optimize3DSDowngradeV2MenuOptionInfo optimize_n3ds_downgrade_desc3_menu = { +.base_name = "This will make it incompatible", .is_selectable = false, +.is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION, +.out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION}; + +static const Optimize3DSDowngradeV2MenuOptionInfo optimize_n3ds_downgrade_desc4_menu = { +.base_name = "with older software, as well", .is_selectable = false, +.is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION, +.out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION}; + +static const Optimize3DSDowngradeV2MenuOptionInfo optimize_n3ds_downgrade_desc5_menu = { +.base_name = "as other downsides...", .is_selectable = false, +.is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION, +.out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION}; + +static const Optimize3DSDowngradeV2MenuOptionInfo optimize_n3ds_downgrade_confirm_menu = { +.base_name = "Continue anyway?", .is_selectable = true, +.is_inc = true, .dec_str = "No", .inc_str = "Yes", .inc_out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_CONFIRM, +.out_action = OPTIMIZE3DS_DOWNGRADEV2_MENU_BACK}; + +static const Optimize3DSDowngradeV2MenuOptionInfo* pollable_options[] = { +&optimize_n3ds_downgrade_desc1_menu, +&optimize_n3ds_downgrade_desc2_menu, +&optimize_n3ds_downgrade_desc3_menu, +&optimize_n3ds_downgrade_desc4_menu, +&optimize_n3ds_downgrade_desc5_menu, +&optimize_n3ds_downgrade_confirm_menu, +}; + +Optimize3DSDowngradeV2Menu::Optimize3DSDowngradeV2Menu(TextRectanglePool* text_rectangle_pool) : OptionSelectionMenu(){ + this->options_indexes = new int[NUM_TOTAL_MENU_OPTIONS]; + this->initialize(text_rectangle_pool); + this->num_enabled_options = 0; +} + +Optimize3DSDowngradeV2Menu::~Optimize3DSDowngradeV2Menu() { + delete []this->options_indexes; +} + +void Optimize3DSDowngradeV2Menu::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.3f; + this->max_width_slack = 1.1f; + this->menu_color = sf::Color(30, 30, 60, 192); + this->title = "Downgrade V2 Menu"; + this->show_back_x = true; + this->show_x = false; + this->show_title = true; +} + +void Optimize3DSDowngradeV2Menu::insert_data() { + this->num_enabled_options = 0; + for(size_t i = 0; i < NUM_TOTAL_MENU_OPTIONS; i++) { + bool valid = true; + if(valid) { + this->options_indexes[this->num_enabled_options] = (int)i; + this->num_enabled_options++; + } + } + this->prepare_options(); +} + +void Optimize3DSDowngradeV2Menu::reset_output_option() { + this->selected_index = Optimize3DSDowngradeV2MenuOutAction::OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION; +} + +void Optimize3DSDowngradeV2Menu::set_output_option(int index, int action) { + if(index == BACK_X_OUTPUT_OPTION) + this->selected_index = OPTIMIZE3DS_DOWNGRADEV2_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; +} + +size_t Optimize3DSDowngradeV2Menu::get_num_options() { + return this->num_enabled_options; +} + +std::string Optimize3DSDowngradeV2Menu::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 Optimize3DSDowngradeV2Menu::is_option_selectable(int index, int action) { + return pollable_options[this->options_indexes[index]]->is_selectable; +} + +bool Optimize3DSDowngradeV2Menu::is_option_inc_dec(int index) { + return pollable_options[this->options_indexes[index]]->is_inc; +} + +void Optimize3DSDowngradeV2Menu::prepare(float menu_scaling_factor, int view_size_x, int view_size_y) { + 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]; + } + + this->base_prepare(menu_scaling_factor, view_size_x, view_size_y); +} diff --git a/source/Menus/Optimize3DSMenu.cpp b/source/Menus/Optimize3DSMenu.cpp index 8a6bd94..2df8f3e 100644 --- a/source/Menus/Optimize3DSMenu.cpp +++ b/source/Menus/Optimize3DSMenu.cpp @@ -10,6 +10,7 @@ struct Optimize3DSMenuOptionInfo { const bool optimize_o3ds_valid; const bool optimize_n3ds_valid; const bool optimize_o2ds_valid; + const bool optimize_n3dsv2_valid; const bool is_inc; const std::string dec_str; const std::string inc_str; @@ -20,99 +21,122 @@ struct Optimize3DSMenuOptionInfo { static const Optimize3DSMenuOptionInfo optimize_o3ds_device_id_option = { .base_name = "Old 3DS Device ID:", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = false, .optimize_o2ds_valid = false, +.optimize_n3dsv2_valid = false, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_n3ds_device_id_option = { .base_name = "New 3DS Device ID:", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = false, .optimize_n3ds_valid = true, .optimize_o2ds_valid = false, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_device_id_option = { .base_name = "Device ID", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_INFO_DEVICE_ID}; static const Optimize3DSMenuOptionInfo optimize_copy_3ds_device_id_option = { .base_name = "Copy Device ID to clipboard", .false_name = "", .is_selectable = true, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_COPY_DEVICE_ID}; static const Optimize3DSMenuOptionInfo optimize_serial_key_info_option = { .base_name = "Serial Key:", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_serial_key_option = { .base_name = "", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_OPTIMIZE_SERIAL_KEY}; static const Optimize3DSMenuOptionInfo optimize_serial_key_menu_option = { .base_name = "Add New Serial Key", .false_name = "", .is_selectable = true, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_OPTIMIZE_SERIAL_KEY_MENU}; static const Optimize3DSMenuOptionInfo optimize_3ds_format_explanation_0 = { .base_name = "Possible Data Types:", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_format_explanation_1 = { .base_name = "RGB888 - Full color", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_format_explanation_2 = { .base_name = "more demanding on USB host.", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_format_explanation_3 = { .base_name = "RGB565 - Reduced color", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = false, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_format_explanation_3_alt = { .base_name = "RGB565 - No Sound", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = false, .optimize_n3ds_valid = false, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = false, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_format_explanation_4 = { .base_name = "less demanding on USB host.", .false_name = "", .is_selectable = false, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = true, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_NO_ACTION}; static const Optimize3DSMenuOptionInfo optimize_3ds_change_format = { .base_name = "Data Type", .false_name = "", .is_selectable = true, .optimize_o3ds_valid = true, .optimize_n3ds_valid = true, .optimize_o2ds_valid = false, +.optimize_n3dsv2_valid = true, .is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_INPUT_VIDEO_FORMAT_INC, .out_action = OPTIMIZE3DS_MENU_INPUT_VIDEO_FORMAT_DEC}; static const Optimize3DSMenuOptionInfo optimize_2ds_change_format = { .base_name = "Data Type", .false_name = "", .is_selectable = true, .optimize_o3ds_valid = false, .optimize_n3ds_valid = false, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = false, .is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE2DS_MENU_INPUT_VIDEO_FORMAT_INC, .out_action = OPTIMIZE2DS_MENU_INPUT_VIDEO_FORMAT_DEC}; static const Optimize3DSMenuOptionInfo optimize_old_fw_settings_menu = { .base_name = "Synch Settings", .false_name = "", .is_selectable = true, .optimize_o3ds_valid = false, .optimize_n3ds_valid = false, .optimize_o2ds_valid = true, +.optimize_n3dsv2_valid = false, .is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, .out_action = OPTIMIZE3DS_MENU_OLD_FW_SETTINGS_MENU}; +static const Optimize3DSMenuOptionInfo optimize_n3ds_downgrade_menu = { +.base_name = "Downgrade to V2", .false_name = "", .is_selectable = true, +.optimize_o3ds_valid = false, .optimize_n3ds_valid = true, .optimize_o2ds_valid = false, +.optimize_n3dsv2_valid = false, +.is_inc = false, .dec_str = "<", .inc_str = ">", .inc_out_action = OPTIMIZE3DS_MENU_NO_ACTION, +.out_action = OPTIMIZE3DS_MENU_N3DS_DOWNGRADEV2_MENU}; + static const Optimize3DSMenuOptionInfo* pollable_options[] = { //&optimize_o3ds_device_id_option, //&optimize_n3ds_device_id_option, @@ -130,6 +154,7 @@ static const Optimize3DSMenuOptionInfo* pollable_options[] = { &optimize_3ds_change_format, &optimize_2ds_change_format, &optimize_old_fw_settings_menu, +&optimize_n3ds_downgrade_menu, }; Optimize3DSMenu::Optimize3DSMenu(TextRectanglePool* text_rectangle_pool) : OptionSelectionMenu(){ @@ -161,10 +186,12 @@ void Optimize3DSMenu::class_setup() { void Optimize3DSMenu::insert_data(CaptureDevice* device) { bool is_o3ds = false; bool is_n3ds = false; + bool is_n3dsv2 = false; bool is_o2ds = false; #ifdef USE_CYPRESS_OPTIMIZE is_o3ds = is_device_optimize_o3ds(device); is_n3ds = is_device_optimize_n3ds(device); + is_n3dsv2 = is_device_optimize_n3dsv2(device); is_o2ds = is_device_optimize_o2ds(device); #endif this->num_enabled_options = 0; @@ -176,6 +203,8 @@ void Optimize3DSMenu::insert_data(CaptureDevice* device) { valid = valid && pollable_options[i]->optimize_n3ds_valid; if(is_o2ds) valid = valid && pollable_options[i]->optimize_o2ds_valid; + if(is_n3dsv2) + valid = valid && pollable_options[i]->optimize_n3dsv2_valid; if(valid) { this->options_indexes[this->num_enabled_options] = (int)i; this->num_enabled_options++; diff --git a/source/WindowScreen_Menu.cpp b/source/WindowScreen_Menu.cpp index 27f1bfc..6409fe1 100755 --- a/source/WindowScreen_Menu.cpp +++ b/source/WindowScreen_Menu.cpp @@ -134,6 +134,7 @@ void WindowScreen::init_menus() { this->optimize_3ds_menu = new Optimize3DSMenu(this->text_rectangle_pool); this->optimize_serial_key_add_menu = new OptimizeSerialKeyAddMenu(this->text_rectangle_pool); this->optimize_old_fw_config_menu = new OptimizeOldFWConfigMenu(this->text_rectangle_pool); + this->optimize_3ds_downgradev2_menu = new Optimize3DSDowngradeV2Menu(this->text_rectangle_pool); } void WindowScreen::destroy_menus() { @@ -168,6 +169,7 @@ void WindowScreen::destroy_menus() { delete this->optimize_3ds_menu; delete this->optimize_serial_key_add_menu; delete this->optimize_old_fw_config_menu; + delete this->optimize_3ds_downgradev2_menu; } void WindowScreen::set_close(int ret_val) { @@ -1319,6 +1321,15 @@ void WindowScreen::setup_optimize_old_fw_config_menu(bool reset_data) { } } +void WindowScreen::setup_optimize_n3ds_downgradev2_menu(bool reset_data) { + if(!this->can_setup_menu()) + return; + if(this->curr_menu != OPTIMIZE_3DS_DOWNGRADEV2_MENU_TYPE) { + this->switch_to_menu(OPTIMIZE_3DS_DOWNGRADEV2_MENU_TYPE, this->optimize_3ds_downgradev2_menu, reset_data); + this->optimize_3ds_downgradev2_menu->insert_data(); + } +} + void WindowScreen::update_save_menu() { if(this->curr_menu == SAVE_MENU_TYPE) { this->curr_menu = DEFAULT_MENU_TYPE; @@ -2500,6 +2511,9 @@ void WindowScreen::poll(bool do_everything) { case OPTIMIZE2DS_MENU_INPUT_VIDEO_FORMAT_DEC: this->input_video_data_format_request_change(false, this->capture_status->device_specific_status.optimize_status.request_low_bw_format_old_2ds); break; + case OPTIMIZE3DS_MENU_N3DS_DOWNGRADEV2_MENU: + this->setup_optimize_n3ds_downgradev2_menu(); + break; default: break; } @@ -2556,6 +2570,23 @@ void WindowScreen::poll(bool do_everything) { } this->loaded_menu_ptr->reset_output_option(); break; + case OPTIMIZE_3DS_DOWNGRADEV2_MENU_TYPE: + switch(this->optimize_3ds_downgradev2_menu->selected_index) { + case OPTIMIZE3DS_DOWNGRADEV2_MENU_BACK: + this->setup_optimize_3ds_menu(false); + done = true; + break; + case OPTIMIZE3DS_DOWNGRADEV2_MENU_NO_ACTION: + break; + case OPTIMIZE3DS_DOWNGRADEV2_MENU_CONFIRM: + this->capture_status->device_specific_status.optimize_status.request_optimize_n3ds_downgradev2 = true; + this->setup_no_menu(); + break; + default: + break; + } + this->loaded_menu_ptr->reset_output_option(); + break; default: break; } @@ -2599,6 +2630,8 @@ void WindowScreen::update_capture_specific_settings() { this->setup_no_menu(); if(this->curr_menu == OPTIMIZE_OLD_FW_CONFIG_MENU) this->setup_no_menu(); + if(this->curr_menu == OPTIMIZE_3DS_DOWNGRADEV2_MENU_TYPE) + this->setup_no_menu(); } int WindowScreen::load_data() { @@ -2887,6 +2920,9 @@ void WindowScreen::prepare_menu_draws(int view_size_x, int view_size_y) { case OPTIMIZE_OLD_FW_CONFIG_MENU: this->optimize_old_fw_config_menu->prepare(menu_scaling_factor, view_size_x, view_size_y, this->capture_status); break; + case OPTIMIZE_3DS_DOWNGRADEV2_MENU_TYPE: + this->optimize_3ds_downgradev2_menu->prepare(menu_scaling_factor, view_size_x, view_size_y); + break; default: break; }