From b3ac69cb23b2150ec94c06704bd12bad2186d3f0 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Sat, 26 Oct 2024 04:43:53 +0200 Subject: [PATCH] Add Reset Hardware option for IS Nitro Capture --- .../ISNitro/usb_is_nitro_acquisition.hpp | 1 + .../ISNitro/usb_is_nitro_communications.hpp | 7 +- include/Menus/ISNitroMenu.hpp | 3 +- include/capture_structs.hpp | 1 + include/frontend.hpp | 1 + .../ISNitro/usb_is_nitro_acquisition.cpp | 6 ++ .../usb_is_nitro_acquisition_capture.cpp | 75 ++++++++++++++----- .../usb_is_nitro_acquisition_emulator.cpp | 3 +- .../ISNitro/usb_is_nitro_communications.cpp | 69 ++++++++++++++--- source/Menus/ISNitroMenu.cpp | 29 ++++++- source/WindowScreen_Menu.cpp | 9 ++- 11 files changed, 169 insertions(+), 35 deletions(-) diff --git a/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.hpp b/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.hpp index 96632bc..9bbecb8 100644 --- a/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.hpp +++ b/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.hpp @@ -13,6 +13,7 @@ void is_nitro_acquisition_main_loop(CaptureData* capture_data); void usb_is_nitro_acquisition_cleanup(CaptureData* capture_data); void usb_is_nitro_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, CaptureScreensType capture_type); uint64_t usb_is_nitro_get_video_in_size(CaptureData* capture_data); +bool is_nitro_is_capture(CaptureDevice* device); void usb_is_nitro_init(); void usb_is_nitro_close(); diff --git a/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.hpp b/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.hpp index 691a0f4..f791342 100644 --- a/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.hpp +++ b/include/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.hpp @@ -57,7 +57,12 @@ int GetFrameCounter(is_nitro_device_handlers* handlers, uint16_t* out, const is_ int GetDeviceSerial(is_nitro_device_handlers* handlers, uint8_t* buf, const is_nitro_usb_device* device_desc); int UpdateFrameForwardConfig(is_nitro_device_handlers* handlers, is_nitro_forward_config_values_colors colors, is_nitro_forward_config_values_screens screens, is_nitro_forward_config_values_rate rate, const is_nitro_usb_device* device_desc); int UpdateFrameForwardEnable(is_nitro_device_handlers* handlers, bool enable, bool restart, const is_nitro_usb_device* device_desc); -int ReadLidState(is_nitro_device_handlers* handlers, uint32_t* out, const is_nitro_usb_device* device_desc); +int ReadLidState(is_nitro_device_handlers* handlers, bool* out, const is_nitro_usb_device* device_desc); +int ReadDebugButtonState(is_nitro_device_handlers* handlers, bool* out, const is_nitro_usb_device* device_desc); +int ReadPowerButtonState(is_nitro_device_handlers* handlers, bool* out, const is_nitro_usb_device* device_desc); +int ResetCPUStart(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc); +int ResetCPUEnd(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc); +int ResetFullHardware(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc); int ReadFrame(is_nitro_device_handlers* handlers, uint8_t* buf, int length, const is_nitro_usb_device* device_desc); #endif diff --git a/include/Menus/ISNitroMenu.hpp b/include/Menus/ISNitroMenu.hpp index 153e088..6484fc5 100644 --- a/include/Menus/ISNitroMenu.hpp +++ b/include/Menus/ISNitroMenu.hpp @@ -15,6 +15,7 @@ enum ISNitroMenuOutAction{ ISN_MENU_DELAY, ISN_MENU_TYPE_DEC, ISN_MENU_TYPE_INC, + ISN_MENU_RESET, }; class ISNitroMenu : public OptionSelectionMenu { @@ -22,7 +23,7 @@ public: ISNitroMenu(bool font_load_success, sf::Font &text_font); ~ISNitroMenu(); void prepare(float scaling_factor, int view_size_x, int view_size_y, CaptureStatus* capture_status); - void insert_data(); + void insert_data(CaptureDevice* device); ISNitroMenuOutAction selected_index = ISNitroMenuOutAction::ISN_MENU_NO_ACTION; void reset_output_option(); protected: diff --git a/include/capture_structs.hpp b/include/capture_structs.hpp index c04202f..24c4bf8 100755 --- a/include/capture_structs.hpp +++ b/include/capture_structs.hpp @@ -134,6 +134,7 @@ struct CaptureStatus { volatile bool running = true; volatile bool close_success = true; volatile int curr_delay = 0; + volatile bool reset_hardware = false; bool enabled_3d = false; CaptureScreensType capture_type; ConsumerMutex video_wait; diff --git a/include/frontend.hpp b/include/frontend.hpp index ba1ded5..cbe58a0 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -224,6 +224,7 @@ private: void padding_change(); void game_crop_enable_change(); void is_nitro_capture_type_change(bool positive); + void is_nitro_capture_reset_hw(); void crop_value_change(int new_crop_value, bool do_print_notification = true, bool do_cycle = true); void par_value_change(int new_par_value, bool is_top); void offset_change(float &value, float change); diff --git a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.cpp b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.cpp index 513226f..2f4d3a9 100644 --- a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.cpp +++ b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition.cpp @@ -171,6 +171,7 @@ int is_nitro_read_frame_and_output(CaptureData* capture_data, int &inner_curr_in void is_nitro_acquisition_main_loop(CaptureData* capture_data) { if(!usb_is_initialized()) return; + capture_data->status.reset_hardware = false; if(((const is_nitro_usb_device*)(capture_data->status.device.descriptor))->is_capture) is_nitro_acquisition_capture_main_loop(capture_data); else @@ -203,6 +204,11 @@ void usb_is_nitro_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p } } +bool is_nitro_is_capture(CaptureDevice* device) { + const is_nitro_usb_device* usb_device_info = (const is_nitro_usb_device*)device->descriptor; + return usb_device_info->is_capture; +} + void usb_is_nitro_init() { return usb_init(); } diff --git a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_capture.cpp b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_capture.cpp index 58f2e5c..f397838 100644 --- a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_capture.cpp +++ b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_capture.cpp @@ -9,13 +9,15 @@ // For this reason, the code was split into two device-specific files. #define CAPTURE_SKIP_LID_REOPEN_FRAMES 32 +#define RESET_TIMEOUT 4.0 +#define SLEEP_CHECKS_TIME 20 -static int StartAcquisitionCapture(is_nitro_device_handlers* handlers, CaptureScreensType capture_type, uint32_t* lid_state, const is_nitro_usb_device* usb_device_desc) { +static int StartAcquisitionCapture(is_nitro_device_handlers* handlers, CaptureScreensType capture_type, bool* is_acquisition_off, const is_nitro_usb_device* usb_device_desc) { int ret = 0; - ret = ReadLidState(handlers, lid_state, usb_device_desc); + ret = ReadLidState(handlers, is_acquisition_off, usb_device_desc); if(ret < 0) return ret; - if((*lid_state) & 1) + if(*is_acquisition_off) return LIBUSB_SUCCESS; ret = set_acquisition_mode(handlers, capture_type, usb_device_desc); if(ret < 0) @@ -29,18 +31,52 @@ static int StartAcquisitionCapture(is_nitro_device_handlers* handlers, CaptureSc return StartUsbCaptureDma(handlers, usb_device_desc); } -static int LidReopenCaptureCheck(CaptureData* capture_data, CaptureScreensType &curr_capture_type, uint32_t* lid_state) { +static int LidReopenCaptureCheck(CaptureData* capture_data, CaptureScreensType &curr_capture_type, bool* is_acquisition_off) { is_nitro_device_handlers* handlers = (is_nitro_device_handlers*)capture_data->handle; const is_nitro_usb_device* usb_device_desc = (const is_nitro_usb_device*)capture_data->status.device.descriptor; curr_capture_type = capture_data->status.capture_type; - int ret = StartAcquisitionCapture(handlers, curr_capture_type, lid_state, usb_device_desc); + int ret = StartAcquisitionCapture(handlers, curr_capture_type, is_acquisition_off, usb_device_desc); if(ret < 0) return ret; - if(!((*lid_state) & 1)) + if(!(*is_acquisition_off)) capture_data->status.cooldown_curr_in = CAPTURE_SKIP_LID_REOPEN_FRAMES; return ret; } +static int CaptureResetHardware(CaptureData* capture_data, CaptureScreensType &curr_capture_type, bool *is_acquisition_off, std::chrono::time_point &clock_last_reset) { + is_nitro_device_handlers* handlers = (is_nitro_device_handlers*)capture_data->handle; + const is_nitro_usb_device* usb_device_desc = (const is_nitro_usb_device*)capture_data->status.device.descriptor; + bool reset_hardware = capture_data->status.reset_hardware; + capture_data->status.reset_hardware = false; + int ret = LIBUSB_SUCCESS; + if(!reset_hardware) + return ret; + const auto curr_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration diff = curr_time - clock_last_reset; + // Do not reset too fast... In general. + if(diff.count() < RESET_TIMEOUT) + return ret; + clock_last_reset = curr_time; + + if(!(*is_acquisition_off)) + ret = EndAcquisitionCapture(handlers, usb_device_desc); + if(ret < 0) + return ret; + ret = ResetCPUStart(handlers, usb_device_desc); + if(ret < 0) + return ret; + ret = ResetCPUEnd(handlers, usb_device_desc); + if(ret < 0) + return ret; + if(!(*is_acquisition_off)) { + curr_capture_type = capture_data->status.capture_type; + ret = StartAcquisitionCapture(handlers, curr_capture_type, is_acquisition_off, usb_device_desc); + } + if(ret < 0) + return ret; + return ret; +} + int initial_cleanup_capture(const is_nitro_usb_device* usb_device_desc, is_nitro_device_handlers* handlers) { //EndAcquisition(handlers, false, 0, CAPTURE_SCREENS_BOTH, usb_device_desc); return LIBUSB_SUCCESS; @@ -53,9 +89,9 @@ int EndAcquisitionCapture(is_nitro_device_handlers* handlers, const is_nitro_usb void is_nitro_acquisition_capture_main_loop(CaptureData* capture_data) { is_nitro_device_handlers* handlers = (is_nitro_device_handlers*)capture_data->handle; const is_nitro_usb_device* usb_device_desc = (const is_nitro_usb_device*)capture_data->status.device.descriptor; - uint32_t lid_state = 0; + bool is_acquisition_off = true; CaptureScreensType curr_capture_type = capture_data->status.capture_type; - int ret = StartAcquisitionCapture(handlers, curr_capture_type, &lid_state, usb_device_desc); + int ret = StartAcquisitionCapture(handlers, curr_capture_type, &is_acquisition_off, usb_device_desc); if(ret < 0) { capture_error_print(true, capture_data, "Capture Start: Failed"); return; @@ -65,15 +101,20 @@ void is_nitro_acquisition_capture_main_loop(CaptureData* capture_data) { auto clock_last_reset = std::chrono::high_resolution_clock::now(); while(capture_data->status.connected && capture_data->status.running) { - if(lid_state & 1) { - default_sleep(20); - ret = LidReopenCaptureCheck(capture_data, curr_capture_type, &lid_state); + ret = CaptureResetHardware(capture_data, curr_capture_type, &is_acquisition_off, clock_last_reset); + if(ret < 0) { + capture_error_print(true, capture_data, "Hardware reset: Failed"); + return; + } + if(is_acquisition_off) { + default_sleep(SLEEP_CHECKS_TIME); + ret = LidReopenCaptureCheck(capture_data, curr_capture_type, &is_acquisition_off); if(ret < 0) { capture_error_print(true, capture_data, "Lid Reopen: Failed"); return; } } - if(lid_state & 1) + if(is_acquisition_off) continue; ret = is_nitro_read_frame_and_output(capture_data, inner_curr_in, curr_capture_type, clock_start); if(ret < 0) { @@ -82,11 +123,7 @@ void is_nitro_acquisition_capture_main_loop(CaptureData* capture_data) { capture_error_print(true, capture_data, "Disconnected: Read error"); return; } - ret = LidReopenCaptureCheck(capture_data, curr_capture_type, &lid_state); - if(ret < 0) { - capture_error_print(true, capture_data, "Lid Reopen: Failed"); - return; - } + is_acquisition_off = true; continue; } @@ -97,13 +134,13 @@ void is_nitro_acquisition_capture_main_loop(CaptureData* capture_data) { return; } curr_capture_type = capture_data->status.capture_type; - ret = StartAcquisitionCapture(handlers, curr_capture_type, &lid_state, usb_device_desc); + ret = StartAcquisitionCapture(handlers, curr_capture_type, &is_acquisition_off, usb_device_desc); if(ret < 0) { capture_error_print(true, capture_data, "Capture Restart: Failed"); return; } } } - if(!(lid_state & 1)) + if(!is_acquisition_off) EndAcquisition(handlers, true, 0, curr_capture_type, usb_device_desc); } diff --git a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_emulator.cpp b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_emulator.cpp index 9a43f81..fb9da53 100644 --- a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_emulator.cpp +++ b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_acquisition_emulator.cpp @@ -28,6 +28,7 @@ // For this reason, the code was split into two device-specific files. #define FRAME_BUFFER_SIZE 32 +#define SLEEP_CHECKS_TIME 20 static int drain_frames(is_nitro_device_handlers* handlers, int num_frames, int start_frames, CaptureScreensType capture_type, const is_nitro_usb_device* usb_device_desc) { ISNitroEmulatorVideoInputData* video_in_buffer = new ISNitroEmulatorVideoInputData; @@ -274,7 +275,7 @@ void is_nitro_acquisition_emulator_main_loop(CaptureData* capture_data) { } else { capture_data->status.cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM; - default_sleep(20); + default_sleep(SLEEP_CHECKS_TIME); } capture_data->status.curr_delay = last_frame_counter % FRAME_BUFFER_SIZE; ret = reset_acquisition_frames(handlers, curr_frame_counter, last_frame_counter, single_frame_time, clock_last_reset, curr_capture_type, capture_data->status.capture_type, 1, usb_device_desc); diff --git a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.cpp b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.cpp index 1b3b247..fff5723 100644 --- a/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.cpp +++ b/source/CaptureDeviceSpecific/ISNitro/usb_is_nitro_communications.cpp @@ -58,6 +58,8 @@ enum is_nitro_emulator_command { IS_NITRO_EMU_CMD_READ_NEC_MEM = 0x17, IS_NITRO_EMU_CMD_WRITE_NEC_MEM = 0x24, IS_NITRO_EMU_CMD_SET_READ_NEC_MEM = 0x25, + IS_NITRO_EMU_CMD_FULL_HARDWARE_RESET = 0x81, + IS_NITRO_EMU_CMD_CPU_RESET = 0x8A, IS_NITRO_EMU_CMD_AD = 0xAD, }; @@ -68,8 +70,12 @@ enum is_nitro_capture_command { IS_NITRO_CAP_CMD_SET_FWD_MODE = 0x13, IS_NITRO_CAP_CMD_SET_FWD_COLOURS = 0x14, IS_NITRO_CAP_CMD_SET_FWD_FRAMES = 0x15, + IS_NITRO_CAP_CMD_GET_DEBUG_STATE = 0x18, + IS_NITRO_CAP_CMD_SET_RESTART_FULL = 0x18, IS_NITRO_CAP_CMD_GET_LID_STATE = 0x19, IS_NITRO_CAP_CMD_SET_FWD_RESTART = 0x1C, + IS_NITRO_CAP_CMD_SET_RESET_CPU_ON = 0x21, + IS_NITRO_CAP_CMD_SET_RESET_CPU_OFF = 0x22, }; enum is_nitro_emulator_forward_bits { @@ -432,13 +438,13 @@ int GetFrameCounter(is_nitro_device_handlers* handlers, uint16_t* out, const is_ int UpdateFrameForwardConfig(is_nitro_device_handlers* handlers, is_nitro_forward_config_values_colors colors, is_nitro_forward_config_values_screens screens, is_nitro_forward_config_values_rate rate, const is_nitro_usb_device* device_desc) { if(!device_desc->is_capture) return WriteNecMemU16(handlers, 0x0800000A, ((colors & 1) << 4) | ((screens & 3) << 2) | ((rate & 3) << 0), device_desc); - int ret = SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_COLOURS, colors & 1, device_desc); + int ret = SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_RATE, rate & 3, device_desc); if(ret < 0) return ret; - ret = SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_RATE, rate & 3, device_desc); + ret = SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_MODE, screens & 3, device_desc); if(ret < 0) return ret; - return SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_MODE, screens & 3, device_desc); + return SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_COLOURS, colors & 1, device_desc); } int UpdateFrameForwardEnable(is_nitro_device_handlers* handlers, bool enable, bool restart, const is_nitro_usb_device* device_desc) { @@ -455,17 +461,62 @@ int UpdateFrameForwardEnable(is_nitro_device_handlers* handlers, bool enable, bo return SendWriteCommandU32(handlers, IS_NITRO_CAP_CMD_SET_FWD_RESTART, value, device_desc); } -int ReadLidState(is_nitro_device_handlers* handlers, uint32_t* out, const is_nitro_usb_device* device_desc) { - if(device_desc->is_capture) - return SendReadCommandU32(handlers, IS_NITRO_CAP_CMD_GET_LID_STATE, out, device_desc); - uint16_t flags = 0; - int ret = ReadNecMemU16(handlers, 0x08000000, &flags, device_desc); +int ReadLidState(is_nitro_device_handlers* handlers, bool* out, const is_nitro_usb_device* device_desc) { + uint32_t flags = 0; + if(device_desc->is_capture) { + int ret = SendReadCommandU32(handlers, IS_NITRO_CAP_CMD_GET_LID_STATE, &flags, device_desc); + *out = (flags & 1) ? true : false; + return ret; + } + int ret = ReadNecMemU32(handlers, 0x08000000, &flags, device_desc); if(ret < 0) return ret; - *out = (flags & 2) >> 1; + *out = (flags & 2) ? true : false; return ret; } +int ReadDebugButtonState(is_nitro_device_handlers* handlers, bool* out, const is_nitro_usb_device* device_desc) { + uint32_t flags = 0; + if(device_desc->is_capture) { + int ret = SendReadCommandU32(handlers, IS_NITRO_CAP_CMD_GET_DEBUG_STATE, &flags, device_desc); + *out = (flags & 1) ? true : false; + return ret; + } + int ret = ReadNecMemU32(handlers, 0x08000000, &flags, device_desc); + if(ret < 0) + return ret; + *out = (flags & 1) ? true : false; + return ret; +} + +int ReadPowerButtonState(is_nitro_device_handlers* handlers, bool* out, const is_nitro_usb_device* device_desc) { + return ReadDebugButtonState(handlers, out, device_desc); +} + +static int ResetCPUEmulatorGeneral(is_nitro_device_handlers* handlers, bool on, const is_nitro_usb_device* device_desc) { + uint8_t data[] = {IS_NITRO_EMU_CMD_CPU_RESET, 0, (uint8_t)(on ? 1 : 0), 0}; + return SendWriteCommand(handlers, IS_NITRO_EMU_CMD_CPU_RESET, data, sizeof(data), device_desc); +} + +int ResetCPUStart(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc) { + if(device_desc->is_capture) + return SendWriteCommand(handlers, IS_NITRO_CAP_CMD_SET_RESET_CPU_ON, NULL, 0, device_desc); + return ResetCPUEmulatorGeneral(handlers, true, device_desc); +} + +int ResetCPUEnd(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc) { + if(device_desc->is_capture) + return SendWriteCommand(handlers, IS_NITRO_CAP_CMD_SET_RESET_CPU_OFF, NULL, 0, device_desc); + return ResetCPUEmulatorGeneral(handlers, false, device_desc); +} + +int ResetFullHardware(is_nitro_device_handlers* handlers, const is_nitro_usb_device* device_desc) { + if(device_desc->is_capture) + return SendWriteCommand(handlers, IS_NITRO_CAP_CMD_SET_RESTART_FULL, NULL, 0, device_desc); + uint8_t data[] = {IS_NITRO_EMU_CMD_FULL_HARDWARE_RESET, 0xF2}; + return SendWriteCommand(handlers, IS_NITRO_EMU_CMD_FULL_HARDWARE_RESET, data, sizeof(data), device_desc); +} + int ReadFrame(is_nitro_device_handlers* handlers, uint8_t* buf, int length, const is_nitro_usb_device* device_desc) { // Maybe making this async would be better for lower end hardware... int num_bytes = 0; diff --git a/source/Menus/ISNitroMenu.cpp b/source/Menus/ISNitroMenu.cpp index bea14e3..f87705b 100644 --- a/source/Menus/ISNitroMenu.cpp +++ b/source/Menus/ISNitroMenu.cpp @@ -1,4 +1,5 @@ #include "ISNitroMenu.hpp" +#include "usb_is_nitro_acquisition.hpp" #define NUM_TOTAL_MENU_OPTIONS (sizeof(pollable_options)/sizeof(pollable_options[0])) @@ -6,6 +7,8 @@ struct ISNitroMenuOptionInfo { const std::string base_name; const std::string false_name; const bool is_selectable; + const bool is_capture_valid; + const bool is_emulator_valid; const bool is_inc; const std::string dec_str; const std::string inc_str; @@ -15,17 +18,26 @@ struct ISNitroMenuOptionInfo { static const ISNitroMenuOptionInfo is_nitro_delay_option = { .base_name = "Delay", .false_name = "", .is_selectable = false, +.is_capture_valid = false, .is_emulator_valid = true, .is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = ISN_MENU_NO_ACTION, .out_action = ISN_MENU_DELAY}; static const ISNitroMenuOptionInfo is_nitro_type_option = { .base_name = "Capture", .false_name = "", .is_selectable = true, +.is_capture_valid = true, .is_emulator_valid = true, .is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = ISN_MENU_TYPE_INC, .out_action = ISN_MENU_TYPE_DEC}; +static const ISNitroMenuOptionInfo is_nitro_reset_option = { +.base_name = "Reset Hardware", .false_name = "", .is_selectable = true, +.is_capture_valid = true, .is_emulator_valid = false, +.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = ISN_MENU_NO_ACTION, +.out_action = ISN_MENU_RESET}; + static const ISNitroMenuOptionInfo* pollable_options[] = { &is_nitro_delay_option, &is_nitro_type_option, +&is_nitro_reset_option, }; ISNitroMenu::ISNitroMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){ @@ -54,11 +66,22 @@ void ISNitroMenu::class_setup() { this->show_title = true; } -void ISNitroMenu::insert_data() { +void ISNitroMenu::insert_data(CaptureDevice* device) { + bool is_capture = false; + #ifdef USE_IS_NITRO_USB + is_capture = is_nitro_is_capture(device); + #endif this->num_enabled_options = 0; for(int i = 0; i < NUM_TOTAL_MENU_OPTIONS; i++) { - this->options_indexes[this->num_enabled_options] = i; - this->num_enabled_options++; + bool valid = true; + if(is_capture) + valid = valid && pollable_options[i]->is_capture_valid; + else + valid = valid && pollable_options[i]->is_emulator_valid; + if(valid) { + this->options_indexes[this->num_enabled_options] = i; + this->num_enabled_options++; + } } this->prepare_options(); } diff --git a/source/WindowScreen_Menu.cpp b/source/WindowScreen_Menu.cpp index 1c851eb..0384c1e 100755 --- a/source/WindowScreen_Menu.cpp +++ b/source/WindowScreen_Menu.cpp @@ -185,6 +185,10 @@ void WindowScreen::is_nitro_capture_type_change(bool positive) { this->capture_status->capture_type = static_cast(new_value % CAPTURE_SCREENS_ENUM_END); } +void WindowScreen::is_nitro_capture_reset_hw() { + this->capture_status->reset_hardware = true; +} + void WindowScreen::padding_change() { if(this->m_info.is_fullscreen) return; @@ -918,7 +922,7 @@ void WindowScreen::setup_is_nitro_menu(bool reset_data) { this->curr_menu = ISN_MENU_TYPE; if(reset_data) this->is_nitro_menu->reset_data(); - this->is_nitro_menu->insert_data(); + this->is_nitro_menu->insert_data(&this->capture_status->device); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } } @@ -1815,6 +1819,9 @@ void WindowScreen::poll(bool do_everything) { case ISN_MENU_TYPE_INC: this->is_nitro_capture_type_change(true); break; + case ISN_MENU_RESET: + this->is_nitro_capture_reset_hw(); + break; default: break; }