mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2026-04-26 00:13:40 -05:00
Implement Optimize New 3DS Firmware loading
Some checks are pending
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux32 flags:32 name:Linux GCC 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux64 flags:64 name:Linux GCC x64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm32 flags:arm32 name:Linux GCC ARM 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm64 flags:arm64 name:Linux GCC ARM 64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:macos name:macOS Apple Silicon os:macos-14]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win32 flags:-A Win32 name:Windows VS2022 Win32 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win64 flags:-A x64 name:Windows VS2022 x64 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:winarm64 flags:-A ARM64 name:Windows VS2022 ARM os:windows-2022]) (push) Waiting to run
CD / Create Pi Mono Setup (push) Blocked by required conditions
CD / Publishing (push) Blocked by required conditions
Some checks are pending
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux32 flags:32 name:Linux GCC 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux64 flags:64 name:Linux GCC x64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm32 flags:arm32 name:Linux GCC ARM 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm64 flags:arm64 name:Linux GCC ARM 64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:macos name:macOS Apple Silicon os:macos-14]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win32 flags:-A Win32 name:Windows VS2022 Win32 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win64 flags:-A x64 name:Windows VS2022 x64 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:winarm64 flags:-A ARM64 name:Windows VS2022 ARM os:windows-2022]) (push) Waiting to run
CD / Create Pi Mono Setup (push) Blocked by required conditions
CD / Publishing (push) Blocked by required conditions
This commit is contained in:
parent
7c4640b3dc
commit
6b040e4d36
|
|
@ -11,12 +11,13 @@ set(NEW_DS_LOOPY_SUPPORT 1)
|
|||
set(IS_DEVICES_SUPPORT 1)
|
||||
set(OLD_DS_3DS_LOOPY_SUPPORT 1)
|
||||
set(CYPRESS_NISETRO_SUPPORT 1)
|
||||
set(OPTIMIZE_NEW3DS_SUPPORT 1)
|
||||
|
||||
set(USE_FTD2XX_FOR_NEW_DS_LOOPY ${NEW_DS_LOOPY_SUPPORT})
|
||||
set(USE_LIBUSB_FOR_NEW_DS_LOOPY ${NEW_DS_LOOPY_SUPPORT})
|
||||
set(USE_FTD3XX_FOR_N3DSXL_LOOPY ${N3DSXL_LOOPY_SUPPORT})
|
||||
set(USE_LIBUSB_FOR_N3DSXL_LOOPY ${N3DSXL_LOOPY_SUPPORT})
|
||||
set(USE_CYPRESS_USB_SUPPORT ${CYPRESS_NISETRO_SUPPORT})
|
||||
set(USE_CYPRESS_USB_SUPPORT ${CYPRESS_NISETRO_SUPPORT} OR ${OPTIMIZE_NEW3DS_SUPPORT})
|
||||
set(USE_LIBUSB_SUPPORT ${IS_DEVICES_SUPPORT} OR ${OLD_DS_3DS_LOOPY_SUPPORT} OR ${USE_LIBUSB_FOR_NEW_DS_LOOPY} OR ${USE_LIBUSB_FOR_N3DSXL_LOOPY} OR ${USE_CYPRESS_USB_SUPPORT})
|
||||
if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Windows"))
|
||||
#Performance outside of Windows is very bad for the official drivers...
|
||||
|
|
@ -306,6 +307,7 @@ set(SOURCE_CPP_FTD2_FILES_BASE_PATH "${SOURCE_CPP_DEVICE_FILES_BASE_PATH}/DSCapt
|
|||
set(SOURCE_CPP_FTD3_FILES_BASE_PATH "${SOURCE_CPP_DEVICE_FILES_BASE_PATH}/3DSCapture_FTD3")
|
||||
set(SOURCE_CPP_CYPRESS_USB_FILES_BASE_PATH "${SOURCE_CPP_DEVICE_FILES_BASE_PATH}/CypressShared")
|
||||
set(SOURCE_CPP_CYPRESS_NISETRO_DEVICES_FILES_BASE_PATH "${SOURCE_CPP_DEVICE_FILES_BASE_PATH}/Nisetro")
|
||||
set(SOURCE_CPP_CYPRESS_NEW_OPTIMIZE_3DS_FILES_BASE_PATH "${SOURCE_CPP_DEVICE_FILES_BASE_PATH}/Optimize_New_3DS")
|
||||
if(N3DSXL_LOOPY_SUPPORT)
|
||||
list(APPEND SOURCE_CPP_EXTRA_FILES ${SOURCE_CPP_FTD3_FILES_BASE_PATH}/3dscapture_ftd3_shared.cpp ${SOURCE_CPP_FTD3_FILES_BASE_PATH}/3dscapture_ftd3_compatibility.cpp)
|
||||
if(MSVC)
|
||||
|
|
@ -368,6 +370,14 @@ if(CYPRESS_NISETRO_SUPPORT)
|
|||
list(APPEND EXTRA_CXX_FLAGS "-DUSE_CYNI_USB")
|
||||
endif()
|
||||
endif()
|
||||
if(OPTIMIZE_NEW3DS_SUPPORT)
|
||||
list(APPEND SOURCE_CPP_EXTRA_FILES ${SOURCE_CPP_CYPRESS_NEW_OPTIMIZE_3DS_FILES_BASE_PATH}/cypress_optimize_new_3ds_communications.cpp ${SOURCE_CPP_CYPRESS_NEW_OPTIMIZE_3DS_FILES_BASE_PATH}/cypress_optimize_new_3ds_acquisition.cpp ${TOOLS_DATA_DIR}/optimize_new_3ds_fw.cpp ${TOOLS_DATA_DIR}/optimize_new_3ds_565_fpga_pl.cpp ${TOOLS_DATA_DIR}/optimize_new_3ds_888_fpga_pl.cpp)
|
||||
if(MSVC)
|
||||
list(APPEND EXTRA_CXX_FLAGS "/DUSE_CYPRESS_NEW_OPTIMIZE")
|
||||
else()
|
||||
list(APPEND EXTRA_CXX_FLAGS "-DUSE_CYPRESS_NEW_OPTIMIZE")
|
||||
endif()
|
||||
endif()
|
||||
if(NEW_DS_LOOPY_SUPPORT)
|
||||
list(APPEND SOURCE_CPP_EXTRA_FILES ${SOURCE_CPP_FTD2_FILES_BASE_PATH}/dscapture_ftd2_shared.cpp ${SOURCE_CPP_FTD2_FILES_BASE_PATH}/dscapture_ftd2_compatibility.cpp ${TOOLS_DATA_DIR}/ftd2_ds2_fw_1.cpp ${TOOLS_DATA_DIR}/ftd2_ds2_fw_2.cpp)
|
||||
if(MSVC)
|
||||
|
|
@ -527,7 +537,7 @@ endif()
|
|||
if(USE_FTD2XX_FOR_NEW_DS_LOOPY)
|
||||
target_link_libraries(${OUTPUT_NAME} PRIVATE ${ftd2xx_BINARY_DIR}/${FTD2XX_SUBFOLDER}/${FTD2XX_LIB})
|
||||
endif()
|
||||
target_include_directories(${OUTPUT_NAME} PRIVATE ${EXTRA_INCLUDE_DIRECTORIES} ${TOOLS_DATA_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include/Menus ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/ISDevices ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/Nisetro ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/CypressShared ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/3DSCapture_FTD3 ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/DSCapture_FTD2)
|
||||
target_include_directories(${OUTPUT_NAME} PRIVATE ${EXTRA_INCLUDE_DIRECTORIES} ${TOOLS_DATA_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include/Menus ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/ISDevices ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/Nisetro ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/Optimize_New_3DS ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/CypressShared ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/3DSCapture_FTD3 ${CMAKE_SOURCE_DIR}/include/CaptureDeviceSpecific/DSCapture_FTD2)
|
||||
target_compile_features(${OUTPUT_NAME} PRIVATE cxx_std_20)
|
||||
target_compile_options(${OUTPUT_NAME} PRIVATE ${EXTRA_CXX_FLAGS})
|
||||
|
||||
|
|
@ -573,6 +583,27 @@ add_custom_command(
|
|||
DEPENDS ${CMAKE_SOURCE_DIR}/bin/nisetro_ds_fw.bin ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${TOOLS_DATA_DIR}/optimize_new_3ds_fw.cpp
|
||||
COMMENT "Convert fw binary to C - Optimize New 3DS"
|
||||
COMMAND ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION} ${CMAKE_SOURCE_DIR}/bin/optimize_new_3ds_fw.bin ${TOOLS_DATA_DIR} optimize_new_3ds_fw optimize_new_3ds_fw
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/bin/optimize_new_3ds_fw.bin ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${TOOLS_DATA_DIR}/optimize_new_3ds_565_fpga_pl.cpp
|
||||
COMMENT "Convert FPGA 565 PL binary to C - Optimize New 3DS"
|
||||
COMMAND ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION} ${CMAKE_SOURCE_DIR}/bin/optimize_new_3ds_565_fpga_pl.bin ${TOOLS_DATA_DIR} optimize_new_3ds_565_fpga_pl optimize_new_3ds_565_fpga_pl
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/bin/optimize_new_3ds_565_fpga_pl.bin ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${TOOLS_DATA_DIR}/optimize_new_3ds_888_fpga_pl.cpp
|
||||
COMMENT "Convert FPGA 888 PL binary to C - Optimize New 3DS"
|
||||
COMMAND ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION} ${CMAKE_SOURCE_DIR}/bin/optimize_new_3ds_888_fpga_pl.bin ${TOOLS_DATA_DIR} optimize_new_3ds_888_fpga_pl optimize_new_3ds_888_fpga_pl
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/bin/optimize_new_3ds_888_fpga_pl.bin ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION}
|
||||
)
|
||||
|
||||
set(SHADERS_LIST "")
|
||||
list(APPEND SHADERS_LIST ${CMAKE_SOURCE_DIR}/shaders/bit_crusher_fragment_shader.2_to_x_1_7.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_crusher_fragment_shader.2_to_x_1_6.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_crusher_fragment_shader_7.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_fragment_shader.2_to_x_0_6.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_fragment_shader_7.frag ${CMAKE_SOURCE_DIR}/shaders/frame_blending_bit_crusher_fragment_shader.2_to_x_1_7.frag ${CMAKE_SOURCE_DIR}/shaders/frame_blending_fragment_shader.frag ${CMAKE_SOURCE_DIR}/shaders/no_effect_fragment_shader.frag ${CMAKE_SOURCE_DIR}/shaders/color_emulation_fragment_shader.frag)
|
||||
|
||||
|
|
@ -647,6 +678,7 @@ else()
|
|||
install(FILES ${USB_RULES_DIR}/50-ftd2xx.rules DESTINATION .)
|
||||
install(FILES ${USB_RULES_DIR}/51-ftd2xx.rules DESTINATION .)
|
||||
install(FILES ${USB_RULES_DIR}/51-nisetro.rules DESTINATION .)
|
||||
install(FILES ${USB_RULES_DIR}/51-optimize.rules DESTINATION .)
|
||||
install(FILES ${SETUP_SCRIPTS_DIR}/install_usb_rules${SCRIPT_EXTENSION} DESTINATION .)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
BIN
bin/optimize_new_3ds_565_fpga_pl.bin
Normal file
BIN
bin/optimize_new_3ds_565_fpga_pl.bin
Normal file
Binary file not shown.
BIN
bin/optimize_new_3ds_888_fpga_pl.bin
Normal file
BIN
bin/optimize_new_3ds_888_fpga_pl.bin
Normal file
Binary file not shown.
BIN
bin/optimize_new_3ds_fw.bin
Normal file
BIN
bin/optimize_new_3ds_fw.bin
Normal file
Binary file not shown.
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef __CYPRESS_NISETRO_DRIVER_COMMS_HPP
|
||||
#define __CYPRESS_NISETRO_DRIVER_COMMS_HPP
|
||||
#ifndef __CYPRESS_SHARED_DRIVER_COMMS_HPP
|
||||
#define __CYPRESS_SHARED_DRIVER_COMMS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "capture_structs.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "cypress_shared_communications.hpp"
|
||||
|
||||
enum CypressWindowsDriversEnum { CYPRESS_WINDOWS_DEFAULT_USB_DRIVER };
|
||||
enum CypressWindowsDriversEnum { CYPRESS_WINDOWS_DEFAULT_USB_DRIVER, CYPRESS_WINDOWS_OPTIMIZE_NEW_USB_DRIVER };
|
||||
|
||||
void cypress_driver_list_devices(std::vector<CaptureDevice>& devices_list, bool* not_supported_elems, int* curr_serial_extra_id_cypress, std::vector<const cy_device_usb_device*> &device_descriptions, CypressWindowsDriversEnum driver);
|
||||
void cypress_driver_find_used_serial(const cy_device_usb_device* usb_device_desc, bool* found, size_t num_free_fw_ids, int &curr_serial_extra_id, CypressWindowsDriversEnum driver);
|
||||
cy_device_device_handlers* cypress_driver_find_by_serial_number(const cy_device_usb_device* usb_device_desc, std::string wanted_serial_number, int &curr_serial_extra_id, CaptureDevice* new_device, CypressWindowsDriversEnum driver);
|
||||
cy_device_device_handlers* cypress_driver_serial_reconnection(CaptureDevice* device);
|
||||
void cypress_nisetro_driver_end_connection(cy_device_device_handlers* handlers);
|
||||
void cypress_driver_end_connection(cy_device_device_handlers* handlers);
|
||||
int cypress_driver_ctrl_transfer_in(cy_device_device_handlers* handlers, uint8_t* buffer, size_t inner_size, uint16_t value, uint16_t index, uint16_t request_code, int* num_read);
|
||||
int cypress_driver_ctrl_transfer_out(cy_device_device_handlers* handlers, uint8_t* buffer, size_t inner_size, uint16_t value, uint16_t index, uint16_t request_code, int* num_read);
|
||||
int cypress_driver_bulk_in(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, uint8_t* buf, int length, int* transferred);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __CYPRESS_NISETRO_DEVICE_LIBUSB_HPP
|
||||
#define __CYPRESS_NISETRO_DEVICE_LIBUSB_HPP
|
||||
#ifndef __CYPRESS_SHARED_DEVICE_LIBUSB_HPP
|
||||
#define __CYPRESS_SHARED_DEVICE_LIBUSB_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "capture_structs.hpp"
|
||||
|
|
|
|||
|
|
@ -4,25 +4,6 @@
|
|||
#include "cypress_shared_communications.hpp"
|
||||
#include "cypress_nisetro_communications.hpp"
|
||||
|
||||
#define NUM_CAPTURE_RECEIVED_DATA_BUFFERS NUM_CONCURRENT_DATA_BUFFER_WRITERS
|
||||
|
||||
struct CypressDeviceCaptureReceivedData {
|
||||
volatile bool in_use;
|
||||
uint32_t index;
|
||||
SharedConsumerMutex* is_buffer_free_shared_mutex;
|
||||
size_t* scheduled_special_read;
|
||||
uint32_t* active_special_read_index;
|
||||
bool* is_active_special_read;
|
||||
bool* recalibration_request;
|
||||
int* status;
|
||||
uint32_t* last_index;
|
||||
int* errors_since_last_output;
|
||||
int* consecutive_output_to_thread;
|
||||
CaptureData* capture_data;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock>* clock_start;
|
||||
cy_async_callback_data cb_data;
|
||||
};
|
||||
|
||||
std::string cypress_nisetro_get_serial(const void* usb_device_desc, std::string serial, uint16_t bcd_device, int& curr_serial_extra_id);
|
||||
CaptureDevice cypress_nisetro_create_device(const void* usb_device_desc, std::string serial, std::string path);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __CYPRESS_OPTIMIZE_NEW_3DS_ACQUISITION_HPP
|
||||
#define __CYPRESS_OPTIMIZE_NEW_3DS_ACQUISITION_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "utils.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
#include "capture_structs.hpp"
|
||||
#include "display_structs.hpp"
|
||||
#include "devicecapture.hpp"
|
||||
|
||||
void list_devices_cyopn_device(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list);
|
||||
bool cyopn_device_connect_usb(bool print_failed, CaptureData* capture_data, CaptureDevice* device);
|
||||
uint64_t cyopn_device_get_video_in_size(CaptureStatus* status, bool is_3d, InputVideoDataType video_data_type);
|
||||
uint64_t cyopn_device_get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type);
|
||||
void cyopn_device_acquisition_main_loop(CaptureData* capture_data);
|
||||
void usb_cyopn_device_acquisition_cleanup(CaptureData* capture_data);
|
||||
void usb_cyopn_device_init();
|
||||
void usb_cyopn_device_close();
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __CYPRESS_OPTIMIZE_NEW_3DS_ACQUISITION_GENERAL_HPP
|
||||
#define __CYPRESS_OPTIMIZE_NEW_3DS_ACQUISITION_GENERAL_HPP
|
||||
|
||||
#include "cypress_shared_communications.hpp"
|
||||
#include "cypress_optimize_new_3ds_communications.hpp"
|
||||
|
||||
std::string cypress_optimize_new_3ds_get_serial(const void* usb_device_desc, std::string serial, uint16_t bcd_device, int& curr_serial_extra_id);
|
||||
CaptureDevice cypress_optimize_new_3ds_create_device(const void* usb_device_desc, std::string serial, std::string path);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __CYPRESS_OPTIMIZE_NEW_3DS_DEVICE_COMMUNICATIONS_HPP
|
||||
#define __CYPRESS_OPTIMIZE_NEW_3DS_DEVICE_COMMUNICATIONS_HPP
|
||||
|
||||
#include <libusb.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include "utils.hpp"
|
||||
#include "capture_structs.hpp"
|
||||
#include "cypress_shared_communications.hpp"
|
||||
|
||||
enum cypress_optimize_new_device_type {
|
||||
CYPRESS_OPTIMIZE_NEW_3DS_BLANK_DEVICE,
|
||||
};
|
||||
|
||||
struct cyopn_device_usb_device {
|
||||
std::string name;
|
||||
std::string long_name;
|
||||
cypress_optimize_new_device_type device_type;
|
||||
uint8_t* firmware_to_load;
|
||||
size_t firmware_size;
|
||||
cypress_optimize_new_device_type next_device;
|
||||
bool has_bcd_device_serial;
|
||||
cy_device_usb_device usb_device_info;
|
||||
};
|
||||
|
||||
|
||||
int GetNumCyOpNDeviceDesc(void);
|
||||
const cyopn_device_usb_device* GetCyOpNDeviceDesc(int index);
|
||||
const cyopn_device_usb_device* GetNextDeviceDesc(const cyopn_device_usb_device* device);
|
||||
const cy_device_usb_device* get_cy_usb_info(const cyopn_device_usb_device* usb_device_desc);
|
||||
bool has_to_load_firmware(const cyopn_device_usb_device* device);
|
||||
bool load_firmware(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint8_t patch_id);
|
||||
int capture_start(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device);
|
||||
int StartCaptureDma(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device);
|
||||
int capture_end(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device);
|
||||
int ReadFrame(cy_device_device_handlers* handlers, uint8_t* buf, int length, const cyopn_device_usb_device* device_desc);
|
||||
int ReadFrameAsync(cy_device_device_handlers* handlers, uint8_t* buf, int length, const cyopn_device_usb_device* device_desc, cy_async_callback_data* cb_data);
|
||||
|
||||
#endif
|
||||
|
|
@ -308,6 +308,7 @@ struct CaptureDataSingleBuffer {
|
|||
double time_in_buf;
|
||||
uint32_t inner_index;
|
||||
bool is_3d;
|
||||
InputVideoDataType buffer_video_data_type;
|
||||
};
|
||||
|
||||
class CaptureDataBuffers {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
#include "capture_structs.hpp"
|
||||
#include "display_structs.hpp"
|
||||
|
||||
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d, bool is_data_3d);
|
||||
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool is_data_3d);
|
||||
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d);
|
||||
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void captureCall(CaptureData* capture_data);
|
|||
void capture_error_print(bool print_failed, CaptureData* capture_data, std::string error_string);
|
||||
void capture_error_print(bool print_failed, CaptureData* capture_data, std::string graphical_string, std::string detailed_string);
|
||||
uint64_t get_audio_n_samples(CaptureData* capture_data, CaptureDataSingleBuffer* data_buffer);
|
||||
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d);
|
||||
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type);
|
||||
std::string get_name_of_device(CaptureStatus* capture_status, bool use_long = false);
|
||||
int get_usb_speed_of_device(CaptureStatus* capture_status);
|
||||
bool get_device_can_do_3d(CaptureStatus* capture_status);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, d
|
|||
target->time_in_buf = time_in_buf;
|
||||
target->capture_type = capture_type;
|
||||
target->is_3d = is_3d;
|
||||
target->buffer_video_data_type = device->video_data_type;
|
||||
this->ReleaseWriterBuffer(index);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,11 +138,14 @@ struct PACKED CYPRESS_SET_TRANSFER_SIZE_INFO {
|
|||
#pragma pack(pop)
|
||||
|
||||
static GUID cypress_driver_guid = {.Data1 = 0xae18aa60, .Data2 = 0x7f6a, .Data3 = 0x11d4, .Data4 = {0x97, 0xdd, 0x0, 0x1, 0x2, 0x29, 0xb9, 0x59}};
|
||||
static GUID cypress_optimize_new_driver_guid = {.Data1 = 0xae18aa60, .Data2 = 0x7f6a, .Data3 = 0x11d4, .Data4 = {0x97, 0xdd, 0x0, 0x1, 0x2, 0x29, 0xb9, 0x59}};
|
||||
|
||||
static GUID* get_driver_guid(CypressWindowsDriversEnum driver) {
|
||||
switch(driver) {
|
||||
case CYPRESS_WINDOWS_DEFAULT_USB_DRIVER:
|
||||
return &cypress_driver_guid;
|
||||
case CYPRESS_WINDOWS_OPTIMIZE_NEW_USB_DRIVER:
|
||||
return &cypress_optimize_new_driver_guid;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -365,7 +368,7 @@ static bool cypress_driver_get_device_pid_vid_manufacturer_serial_number(std::st
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool cypress_nisetro_driver_setup_connection(cy_device_device_handlers* handlers, std::string path, bool do_pipe_clear_reset) {
|
||||
static bool cypress_driver_setup_connection(cy_device_device_handlers* handlers, std::string path, bool do_pipe_clear_reset) {
|
||||
handlers->usb_handle = NULL;
|
||||
handlers->mutex = NULL;
|
||||
handlers->write_handle = INVALID_HANDLE_VALUE;
|
||||
|
|
@ -397,7 +400,7 @@ static bool cypress_nisetro_driver_setup_connection(cy_device_device_handlers* h
|
|||
return true;
|
||||
}
|
||||
|
||||
static void cypress_nisetro_driver_close_handle(void** handle, void* default_value = INVALID_HANDLE_VALUE) {
|
||||
static void cypress_driver_close_handle(void** handle, void* default_value = INVALID_HANDLE_VALUE) {
|
||||
#ifdef _WIN32
|
||||
if ((*handle) == default_value)
|
||||
return;
|
||||
|
|
@ -419,7 +422,7 @@ cy_device_device_handlers* cypress_driver_serial_reconnection(CaptureDevice* dev
|
|||
if(device->path != "") {
|
||||
cy_device_device_handlers handlers;
|
||||
const cy_device_usb_device* usb_device_info = (const cy_device_usb_device*)device->descriptor;
|
||||
if(cypress_nisetro_driver_setup_connection(&handlers, device->path, usb_device_info->do_pipe_clear_reset)) {
|
||||
if(cypress_driver_setup_connection(&handlers, device->path, usb_device_info->do_pipe_clear_reset)) {
|
||||
final_handlers = new cy_device_device_handlers;
|
||||
final_handlers->usb_handle = NULL;
|
||||
final_handlers->mutex = handlers.mutex;
|
||||
|
|
@ -428,7 +431,7 @@ cy_device_device_handlers* cypress_driver_serial_reconnection(CaptureDevice* dev
|
|||
final_handlers->path = device->path;
|
||||
}
|
||||
else
|
||||
cypress_nisetro_driver_end_connection(&handlers);
|
||||
cypress_driver_end_connection(&handlers);
|
||||
}
|
||||
#endif
|
||||
return final_handlers;
|
||||
|
|
@ -464,8 +467,8 @@ void cypress_driver_list_devices(std::vector<CaptureDevice> &devices_list, bool*
|
|||
const cy_device_usb_device* usb_device_desc = device_descriptions[j];
|
||||
if(not_supported_elems[j] && (usb_device_desc->vid == vid) && (usb_device_desc->pid == pid)) {
|
||||
cy_device_device_handlers handlers;
|
||||
bool result_conn_check = cypress_nisetro_driver_setup_connection(&handlers, path, usb_device_desc->do_pipe_clear_reset);
|
||||
cypress_nisetro_driver_end_connection(&handlers);
|
||||
bool result_conn_check = cypress_driver_setup_connection(&handlers, path, usb_device_desc->do_pipe_clear_reset);
|
||||
cypress_driver_end_connection(&handlers);
|
||||
if(result_conn_check)
|
||||
cypress_insert_device(devices_list, usb_device_desc, serial, bcd_device, curr_serial_extra_id_cypress[j], path);
|
||||
break;
|
||||
|
|
@ -508,7 +511,7 @@ cy_device_device_handlers* cypress_driver_find_by_serial_number(const cy_device_
|
|||
std::string read_serial = cypress_get_serial(usb_device_desc, serial, bcd_device, curr_serial_extra_id);
|
||||
if((usb_device_desc->vid == vid) && (usb_device_desc->pid == pid) && (wanted_serial_number == read_serial)) {
|
||||
cy_device_device_handlers handlers;
|
||||
if(cypress_nisetro_driver_setup_connection(&handlers, path, usb_device_desc->do_pipe_clear_reset)) {
|
||||
if(cypress_driver_setup_connection(&handlers, path, usb_device_desc->do_pipe_clear_reset)) {
|
||||
final_handlers = new cy_device_device_handlers;
|
||||
final_handlers->usb_handle = NULL;
|
||||
final_handlers->mutex = handlers.mutex;
|
||||
|
|
@ -519,7 +522,7 @@ cy_device_device_handlers* cypress_driver_find_by_serial_number(const cy_device_
|
|||
*new_device = cypress_create_device(usb_device_desc, wanted_serial_number, path);
|
||||
}
|
||||
else
|
||||
cypress_nisetro_driver_end_connection(&handlers);
|
||||
cypress_driver_end_connection(&handlers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -552,11 +555,11 @@ int cypress_driver_ctrl_transfer_out(cy_device_device_handlers* handlers, uint8_
|
|||
#endif
|
||||
}
|
||||
|
||||
void cypress_nisetro_driver_end_connection(cy_device_device_handlers* handlers) {
|
||||
void cypress_driver_end_connection(cy_device_device_handlers* handlers) {
|
||||
#ifdef _WIN32
|
||||
cypress_nisetro_driver_close_handle(&handlers->write_handle);
|
||||
cypress_driver_close_handle(&handlers->write_handle);
|
||||
handlers->read_handle = handlers->write_handle;
|
||||
cypress_nisetro_driver_close_handle(&handlers->mutex, NULL);
|
||||
cypress_driver_close_handle(&handlers->mutex, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <chrono>
|
||||
#include <cstring>
|
||||
|
||||
#define NUM_CAPTURE_RECEIVED_DATA_BUFFERS NUM_CONCURRENT_DATA_BUFFER_WRITERS
|
||||
|
||||
// The driver only seems to support up to 4 concurrent reads. Not more...
|
||||
#ifdef NUM_CAPTURE_RECEIVED_DATA_BUFFERS
|
||||
#if NUM_CAPTURE_RECEIVED_DATA_BUFFERS > 4
|
||||
|
|
@ -20,16 +22,32 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define SERIAL_NUMBER_SIZE (0x100 + 1)
|
||||
#define MAX_TIME_WAIT 1.0
|
||||
#define MAX_ERRORS_ALLOWED 100
|
||||
#define NUM_CONSECUTIVE_NEEDED_OUTPUT 6
|
||||
|
||||
#define NISETRO_CYPRESS_USB_WINDOWS_DRIVER CYPRESS_WINDOWS_DEFAULT_USB_DRIVER
|
||||
|
||||
struct CypressNisetroDeviceCaptureReceivedData {
|
||||
volatile bool in_use;
|
||||
uint32_t index;
|
||||
SharedConsumerMutex* is_buffer_free_shared_mutex;
|
||||
size_t* scheduled_special_read;
|
||||
uint32_t* active_special_read_index;
|
||||
bool* is_active_special_read;
|
||||
bool* recalibration_request;
|
||||
int* status;
|
||||
uint32_t* last_index;
|
||||
int* errors_since_last_output;
|
||||
int* consecutive_output_to_thread;
|
||||
CaptureData* capture_data;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock>* clock_start;
|
||||
cy_async_callback_data cb_data;
|
||||
};
|
||||
|
||||
static void cypress_device_read_frame_cb(void* user_data, int transfer_length, int transfer_status);
|
||||
static int get_cypress_device_status(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data);
|
||||
static void error_cypress_device_status(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, int error_val);
|
||||
static int get_cypress_device_status(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data);
|
||||
static void error_cypress_device_status(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, int error_val);
|
||||
|
||||
static cy_device_device_handlers* usb_find_by_serial_number(const cyni_device_usb_device* usb_device_desc, std::string wanted_serial_number, CaptureDevice* new_device) {
|
||||
cy_device_device_handlers* final_handlers = NULL;
|
||||
|
|
@ -96,7 +114,7 @@ static void cypress_nisetro_connection_end(cy_device_device_handlers* handlers,
|
|||
if (handlers->usb_handle)
|
||||
cypress_libusb_end_connection(handlers, get_cy_usb_info(device_desc), interface_claimed);
|
||||
else
|
||||
cypress_nisetro_driver_end_connection(handlers);
|
||||
cypress_driver_end_connection(handlers);
|
||||
delete handlers;
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +249,7 @@ static int cypress_device_read_frame_and_output(CaptureData* capture_data, int i
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int cypress_device_read_frame_request(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, uint32_t index) {
|
||||
static int cypress_device_read_frame_request(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, uint32_t index) {
|
||||
if(cypress_device_capture_recv_data == NULL)
|
||||
return LIBUSB_SUCCESS;
|
||||
if((*cypress_device_capture_recv_data->status) < 0) {
|
||||
|
|
@ -253,7 +271,7 @@ static int cypress_device_read_frame_request(CaptureData* capture_data, CypressD
|
|||
return ReadFrameAsync((cy_device_device_handlers*)capture_data->handle, buffer, read_size, usb_device_info, &cypress_device_capture_recv_data->cb_data);
|
||||
}
|
||||
|
||||
static void end_cypress_device_read_frame_cb(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool early_release) {
|
||||
static void end_cypress_device_read_frame_cb(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool early_release) {
|
||||
if(early_release)
|
||||
cypress_device_capture_recv_data->capture_data->data_buffers.ReleaseWriterBuffer(cypress_device_capture_recv_data->cb_data.internal_index, false);
|
||||
cypress_device_capture_recv_data->in_use = false;
|
||||
|
|
@ -261,7 +279,7 @@ static void end_cypress_device_read_frame_cb(CypressDeviceCaptureReceivedData* c
|
|||
}
|
||||
|
||||
static void cypress_device_read_frame_cb(void* user_data, int transfer_length, int transfer_status) {
|
||||
CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data = (CypressDeviceCaptureReceivedData*)user_data;
|
||||
CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data = (CypressNisetroDeviceCaptureReceivedData*)user_data;
|
||||
if((*cypress_device_capture_recv_data->status) < 0)
|
||||
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
||||
if(transfer_status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
|
|
@ -298,7 +316,7 @@ static void cypress_device_read_frame_cb(void* user_data, int transfer_length, i
|
|||
end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, false);
|
||||
}
|
||||
|
||||
static int cypress_device_get_num_free_buffers(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static int cypress_device_get_num_free_buffers(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
int num_free = 0;
|
||||
for(int i = 0; i < NUM_NISETRO_CYPRESS_BUFFERS; i++)
|
||||
if(!cypress_device_capture_recv_data[i].in_use)
|
||||
|
|
@ -306,7 +324,7 @@ static int cypress_device_get_num_free_buffers(CypressDeviceCaptureReceivedData*
|
|||
return num_free;
|
||||
}
|
||||
|
||||
static void close_all_reads_error(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool &async_read_closed) {
|
||||
static void close_all_reads_error(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool &async_read_closed) {
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
const cyni_device_usb_device* usb_device_desc = (const cyni_device_usb_device*)capture_data->status.device.descriptor;
|
||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0) {
|
||||
|
|
@ -328,14 +346,14 @@ static bool has_too_much_time_passed(const std::chrono::time_point<std::chrono::
|
|||
return diff.count() > MAX_TIME_WAIT;
|
||||
}
|
||||
|
||||
static void error_too_much_time_passed(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool &async_read_closed, const std::chrono::time_point<std::chrono::high_resolution_clock> &start_time) {
|
||||
static void error_too_much_time_passed(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool &async_read_closed, const std::chrono::time_point<std::chrono::high_resolution_clock> &start_time) {
|
||||
if(has_too_much_time_passed(start_time)) {
|
||||
error_cypress_device_status(cypress_device_capture_recv_data, -1);
|
||||
close_all_reads_error(capture_data, cypress_device_capture_recv_data, async_read_closed);
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_all_cypress_device_buffers_free(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static void wait_all_cypress_device_buffers_free(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
if(cypress_device_capture_recv_data == NULL)
|
||||
return;
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
|
|
@ -349,7 +367,7 @@ static void wait_all_cypress_device_buffers_free(CaptureData* capture_data, Cypr
|
|||
}
|
||||
}
|
||||
|
||||
static void wait_one_cypress_device_buffer_free(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static void wait_one_cypress_device_buffer_free(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
bool done = false;
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
|
|
@ -369,7 +387,7 @@ static void wait_one_cypress_device_buffer_free(CaptureData* capture_data, Cypre
|
|||
}
|
||||
}
|
||||
|
||||
static void wait_specific_cypress_device_buffer_free(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static void wait_specific_cypress_device_buffer_free(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
bool done = false;
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
|
|
@ -387,11 +405,11 @@ static void wait_specific_cypress_device_buffer_free(CaptureData* capture_data,
|
|||
}
|
||||
}
|
||||
|
||||
static bool cypress_device_are_buffers_all_free(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static bool cypress_device_are_buffers_all_free(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
return cypress_device_get_num_free_buffers(cypress_device_capture_recv_data) == NUM_NISETRO_CYPRESS_BUFFERS;
|
||||
}
|
||||
|
||||
static CypressDeviceCaptureReceivedData* cypress_device_get_free_buffer(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static CypressNisetroDeviceCaptureReceivedData* cypress_device_get_free_buffer(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
wait_one_cypress_device_buffer_free(capture_data, cypress_device_capture_recv_data);
|
||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)
|
||||
return NULL;
|
||||
|
|
@ -404,11 +422,11 @@ static CypressDeviceCaptureReceivedData* cypress_device_get_free_buffer(CaptureD
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int get_cypress_device_status(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static int get_cypress_device_status(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
return *cypress_device_capture_recv_data[0].status;
|
||||
}
|
||||
|
||||
static void error_cypress_device_status(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, int error_val) {
|
||||
static void error_cypress_device_status(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, int error_val) {
|
||||
if((error_val == 0) || (get_cypress_device_status(cypress_device_capture_recv_data) == 0))
|
||||
*cypress_device_capture_recv_data[0].status = error_val;
|
||||
}
|
||||
|
|
@ -416,14 +434,14 @@ static void error_cypress_device_status(CypressDeviceCaptureReceivedData* cypres
|
|||
static void exported_error_cypress_device_status(void* data, int error_val) {
|
||||
if(data == NULL)
|
||||
return;
|
||||
return error_cypress_device_status((CypressDeviceCaptureReceivedData*)data, error_val);
|
||||
return error_cypress_device_status((CypressNisetroDeviceCaptureReceivedData*)data, error_val);
|
||||
}
|
||||
|
||||
static void reset_cypress_device_status(CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static void reset_cypress_device_status(CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
error_cypress_device_status(cypress_device_capture_recv_data, 0);
|
||||
}
|
||||
|
||||
static void recalibration_reads(cy_device_device_handlers* handlers, const cyni_device_usb_device* usb_device_desc, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, CypressDeviceCaptureReceivedData* chosen_buffer, uint32_t &index) {
|
||||
static void recalibration_reads(cy_device_device_handlers* handlers, const cyni_device_usb_device* usb_device_desc, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data, CypressNisetroDeviceCaptureReceivedData* chosen_buffer, uint32_t &index) {
|
||||
// Enforce properly synchronized reads.
|
||||
// Reduces complexity and latency, at the cost of some extra
|
||||
// time between lid reopening and visible video output.
|
||||
|
|
@ -439,7 +457,7 @@ static void recalibration_reads(cy_device_device_handlers* handlers, const cyni_
|
|||
chosen_buffer->in_use = true;
|
||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)
|
||||
return;
|
||||
CypressDeviceCaptureReceivedData* next_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||
CypressNisetroDeviceCaptureReceivedData* next_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||
default_sleep();
|
||||
*chosen_buffer->recalibration_request = false;
|
||||
chosen_buffer->in_use = true;
|
||||
|
|
@ -461,7 +479,7 @@ static void recalibration_reads(cy_device_device_handlers* handlers, const cyni_
|
|||
chosen_buffer->in_use = true;
|
||||
}
|
||||
|
||||
static bool cyni_device_acquisition_loop(CaptureData* capture_data, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
static bool cyni_device_acquisition_loop(CaptureData* capture_data, CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
const cyni_device_usb_device* usb_device_desc = (const cyni_device_usb_device*)capture_data->status.device.descriptor;
|
||||
uint32_t index = 0;
|
||||
|
|
@ -473,7 +491,7 @@ static bool cyni_device_acquisition_loop(CaptureData* capture_data, CypressDevic
|
|||
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), cyni_device_get_video_in_size(usb_device_desc->device_type));
|
||||
auto clock_last_reset = std::chrono::high_resolution_clock::now();
|
||||
for(int i = 0; i < NUM_NISETRO_CYPRESS_BUFFERS; i++) {
|
||||
CypressDeviceCaptureReceivedData* chosen_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||
CypressNisetroDeviceCaptureReceivedData* chosen_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||
ret = cypress_device_read_frame_request(capture_data, chosen_buffer, index++);
|
||||
if(ret < 0) {
|
||||
chosen_buffer->in_use = false;
|
||||
|
|
@ -499,7 +517,7 @@ static bool cyni_device_acquisition_loop(CaptureData* capture_data, CypressDevic
|
|||
reset_cypress_device_status(cypress_device_capture_recv_data);
|
||||
default_sleep(100);
|
||||
}
|
||||
CypressDeviceCaptureReceivedData* chosen_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||
CypressNisetroDeviceCaptureReceivedData* chosen_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||
if(chosen_buffer == NULL)
|
||||
error_cypress_device_status(cypress_device_capture_recv_data, LIBUSB_ERROR_TIMEOUT);
|
||||
if(chosen_buffer && (*chosen_buffer->recalibration_request)) {
|
||||
|
|
@ -540,7 +558,7 @@ void cyni_device_acquisition_main_loop(CaptureData* capture_data) {
|
|||
SharedConsumerMutex is_transfer_done_shared_mutex(NUM_NISETRO_CYPRESS_BUFFERS);
|
||||
SharedConsumerMutex is_transfer_data_ready_shared_mutex(NUM_NISETRO_CYPRESS_BUFFERS);
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> clock_start = std::chrono::high_resolution_clock::now();
|
||||
CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data = new CypressDeviceCaptureReceivedData[NUM_NISETRO_CYPRESS_BUFFERS];
|
||||
CypressNisetroDeviceCaptureReceivedData* cypress_device_capture_recv_data = new CypressNisetroDeviceCaptureReceivedData[NUM_NISETRO_CYPRESS_BUFFERS];
|
||||
for(int i = 0; i < NUM_NISETRO_CYPRESS_BUFFERS; i++) {
|
||||
cypress_device_capture_recv_data[i].in_use = false;
|
||||
cypress_device_capture_recv_data[i].index = i;
|
||||
|
|
|
|||
|
|
@ -106,6 +106,11 @@ bool has_to_load_firmware(const cyni_device_usb_device* device) {
|
|||
return !((device->firmware_to_load == NULL) || (device->firmware_size == 0));
|
||||
}
|
||||
|
||||
static bool free_firmware_and_return(uint8_t* fw_data, bool retval) {
|
||||
delete []fw_data;
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool load_firmware(cy_device_device_handlers* handlers, const cyni_device_usb_device* device, uint8_t patch_id) {
|
||||
if(!has_to_load_firmware(device))
|
||||
return true;
|
||||
|
|
@ -120,10 +125,8 @@ bool load_firmware(cy_device_device_handlers* handlers, const cyni_device_usb_de
|
|||
uint8_t buffer[0x8000];
|
||||
buffer[0] = 1;
|
||||
int ret = cypress_ctrl_out_transfer(handlers, get_cy_usb_info(device), buffer, 1, 0xA0, 0xE600, 0, &transferred);
|
||||
if(ret < 0) {
|
||||
delete []fw_data;
|
||||
return false;
|
||||
}
|
||||
if(ret < 0)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
bool done = false;
|
||||
int fw_pos = read_le16(fw_data);
|
||||
while(!done) {
|
||||
|
|
@ -132,20 +135,15 @@ bool load_firmware(cy_device_device_handlers* handlers, const cyni_device_usb_de
|
|||
done = (inside_len & 0x8000) != 0;
|
||||
inside_len &= 0x7FFF;
|
||||
fw_pos += 4;
|
||||
if((inside_len + fw_pos) > device->firmware_size) {
|
||||
delete []fw_data;
|
||||
return false;
|
||||
}
|
||||
if((inside_len + fw_pos) > device->firmware_size)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
memcpy(buffer, fw_data + fw_pos, inside_len);
|
||||
fw_pos += inside_len;
|
||||
ret = cypress_ctrl_out_transfer(handlers, get_cy_usb_info(device), buffer, inside_len, 0xA0, offset, 0, &transferred);
|
||||
if(ret < 0) {
|
||||
delete []fw_data;
|
||||
return false;
|
||||
}
|
||||
if(ret < 0)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
}
|
||||
delete []fw_data;
|
||||
return true;
|
||||
return free_firmware_and_return(fw_data, true);
|
||||
}
|
||||
|
||||
int capture_start(cy_device_device_handlers* handlers, const cyni_device_usb_device* device) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,225 @@
|
|||
#include "devicecapture.hpp"
|
||||
#include "cypress_shared_driver_comms.hpp"
|
||||
#include "cypress_shared_libusb_comms.hpp"
|
||||
#include "cypress_shared_communications.hpp"
|
||||
#include "cypress_optimize_new_3ds_communications.hpp"
|
||||
#include "cypress_optimize_new_3ds_acquisition.hpp"
|
||||
#include "cypress_optimize_new_3ds_acquisition_general.hpp"
|
||||
#include "usb_generic.hpp"
|
||||
|
||||
#include <libusb.h>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
|
||||
// This code was developed by exclusively looking at Wireshark USB packet
|
||||
// captures to learn the USB device's protocol.
|
||||
// As such, it was developed in a clean room environment, to provide
|
||||
// compatibility of the USB device with more (and more modern) hardware.
|
||||
// Such an action is allowed under EU law.
|
||||
// No reverse engineering of the original software was done to create this.
|
||||
|
||||
#define NUM_CAPTURE_RECEIVED_DATA_BUFFERS NUM_CONCURRENT_DATA_BUFFER_WRITERS
|
||||
|
||||
// The driver only seems to support up to 4 concurrent reads. Not more...
|
||||
#ifdef NUM_CAPTURE_RECEIVED_DATA_BUFFERS
|
||||
#if NUM_CAPTURE_RECEIVED_DATA_BUFFERS > 4
|
||||
#define NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS 4
|
||||
#else
|
||||
#define NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS NUM_CAPTURE_RECEIVED_DATA_BUFFERS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX_TIME_WAIT 1.0
|
||||
|
||||
#define OPTIMIZE_NEW_3DS_CYPRESS_USB_WINDOWS_DRIVER CYPRESS_WINDOWS_OPTIMIZE_NEW_USB_DRIVER
|
||||
|
||||
struct CypressOptimizeNew3DSDeviceCaptureReceivedData {
|
||||
volatile bool in_use;
|
||||
uint32_t index;
|
||||
SharedConsumerMutex* is_buffer_free_shared_mutex;
|
||||
int* status;
|
||||
uint32_t* last_index;
|
||||
CaptureData* capture_data;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock>* clock_start;
|
||||
cy_async_callback_data cb_data;
|
||||
};
|
||||
|
||||
static void cypress_device_read_frame_cb(void* user_data, int transfer_length, int transfer_status);
|
||||
static int get_cypress_device_status(CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data);
|
||||
static void error_cypress_device_status(CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, int error_val);
|
||||
|
||||
static cy_device_device_handlers* usb_find_by_serial_number(const cyopn_device_usb_device* usb_device_desc, std::string wanted_serial_number, CaptureDevice* new_device) {
|
||||
cy_device_device_handlers* final_handlers = NULL;
|
||||
int curr_serial_extra_id = 0;
|
||||
final_handlers = cypress_libusb_serial_reconnection(get_cy_usb_info(usb_device_desc), wanted_serial_number, curr_serial_extra_id, new_device);
|
||||
|
||||
if(final_handlers == NULL)
|
||||
final_handlers = cypress_driver_find_by_serial_number(get_cy_usb_info(usb_device_desc), wanted_serial_number, curr_serial_extra_id, new_device, OPTIMIZE_NEW_3DS_CYPRESS_USB_WINDOWS_DRIVER);
|
||||
return final_handlers;
|
||||
}
|
||||
|
||||
static int usb_find_free_fw_id(const cyopn_device_usb_device* usb_device_desc) {
|
||||
int curr_serial_extra_id = 0;
|
||||
const int num_free_fw_ids = 0x100;
|
||||
bool found[num_free_fw_ids];
|
||||
for(int i = 0; i < num_free_fw_ids; i++)
|
||||
found[i] = false;
|
||||
cypress_libusb_find_used_serial(get_cy_usb_info(usb_device_desc), found, num_free_fw_ids, curr_serial_extra_id);
|
||||
cypress_driver_find_used_serial(get_cy_usb_info(usb_device_desc), found, num_free_fw_ids, curr_serial_extra_id, OPTIMIZE_NEW_3DS_CYPRESS_USB_WINDOWS_DRIVER);
|
||||
|
||||
for(int i = 0; i < num_free_fw_ids; i++)
|
||||
if(!found[i])
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cy_device_device_handlers* usb_reconnect(const cyopn_device_usb_device* usb_device_desc, CaptureDevice* device) {
|
||||
cy_device_device_handlers* final_handlers = NULL;
|
||||
int curr_serial_extra_id = 0;
|
||||
final_handlers = cypress_libusb_serial_reconnection(get_cy_usb_info(usb_device_desc), device->serial_number, curr_serial_extra_id, NULL);
|
||||
|
||||
if (final_handlers == NULL)
|
||||
final_handlers = cypress_driver_serial_reconnection(device);
|
||||
return final_handlers;
|
||||
}
|
||||
|
||||
static std::string _cypress_optimize_new_3ds_get_serial(const cyopn_device_usb_device* usb_device_desc, std::string serial, uint16_t bcd_device, int& curr_serial_extra_id) {
|
||||
if((!usb_device_desc->has_bcd_device_serial) && (serial != ""))
|
||||
return serial;
|
||||
if(usb_device_desc->has_bcd_device_serial)
|
||||
return std::to_string(bcd_device & 0xFF);
|
||||
return std::to_string((curr_serial_extra_id++) + 1);
|
||||
}
|
||||
|
||||
std::string cypress_optimize_new_3ds_get_serial(const void* usb_device_desc, std::string serial, uint16_t bcd_device, int& curr_serial_extra_id) {
|
||||
if(usb_device_desc == NULL)
|
||||
return "";
|
||||
return _cypress_optimize_new_3ds_get_serial((const cyopn_device_usb_device*)usb_device_desc, serial, bcd_device, curr_serial_extra_id);
|
||||
}
|
||||
|
||||
static CaptureDevice _cypress_optimize_new_3ds_create_device(const cyopn_device_usb_device* usb_device_desc, std::string serial, std::string path) {
|
||||
return CaptureDevice(serial, usb_device_desc->name, usb_device_desc->long_name, CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE, (void*)usb_device_desc, false, false, false, WIDTH_DS, HEIGHT_DS + HEIGHT_DS, 0, 0, 0, 0, 0, HEIGHT_DS, VIDEO_DATA_RGB, path);
|
||||
}
|
||||
|
||||
CaptureDevice cypress_optimize_new_3ds_create_device(const void* usb_device_desc, std::string serial, std::string path) {
|
||||
if(usb_device_desc == NULL)
|
||||
return CaptureDevice();
|
||||
return _cypress_optimize_new_3ds_create_device((const cyopn_device_usb_device*)usb_device_desc, serial, path);
|
||||
}
|
||||
|
||||
static void cypress_optimize_new_3ds_connection_end(cy_device_device_handlers* handlers, const cyopn_device_usb_device *device_desc, bool interface_claimed = true) {
|
||||
if (handlers == NULL)
|
||||
return;
|
||||
if (handlers->usb_handle)
|
||||
cypress_libusb_end_connection(handlers, get_cy_usb_info(device_desc), interface_claimed);
|
||||
else
|
||||
cypress_driver_end_connection(handlers);
|
||||
delete handlers;
|
||||
}
|
||||
|
||||
void list_devices_cyopn_device(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list) {
|
||||
const size_t num_cyopn_device_desc = GetNumCyOpNDeviceDesc();
|
||||
int* curr_serial_extra_id_cyopn_device = new int[num_cyopn_device_desc];
|
||||
bool* no_access_elems = new bool[num_cyopn_device_desc];
|
||||
bool* not_supported_elems = new bool[num_cyopn_device_desc];
|
||||
std::vector<const cy_device_usb_device*> usb_devices_to_check;
|
||||
for (int i = 0; i < num_cyopn_device_desc; i++) {
|
||||
no_access_elems[i] = false;
|
||||
not_supported_elems[i] = false;
|
||||
curr_serial_extra_id_cyopn_device[i] = 0;
|
||||
const cyopn_device_usb_device* curr_device_desc = GetCyOpNDeviceDesc(i);
|
||||
usb_devices_to_check.push_back(get_cy_usb_info(curr_device_desc));
|
||||
}
|
||||
cypress_libusb_list_devices(devices_list, no_access_elems, not_supported_elems, curr_serial_extra_id_cyopn_device, usb_devices_to_check);
|
||||
|
||||
bool any_not_supported = false;
|
||||
for(int i = 0; i < num_cyopn_device_desc; i++)
|
||||
any_not_supported |= not_supported_elems[i];
|
||||
for(int i = 0; i < num_cyopn_device_desc; i++)
|
||||
if(no_access_elems[i])
|
||||
no_access_list.emplace_back(usb_devices_to_check[i]->vid, usb_devices_to_check[i]->pid);
|
||||
if(any_not_supported)
|
||||
cypress_driver_list_devices(devices_list, not_supported_elems, curr_serial_extra_id_cyopn_device, usb_devices_to_check, OPTIMIZE_NEW_3DS_CYPRESS_USB_WINDOWS_DRIVER);
|
||||
|
||||
delete[] curr_serial_extra_id_cyopn_device;
|
||||
delete[] no_access_elems;
|
||||
delete[] not_supported_elems;
|
||||
}
|
||||
|
||||
bool cyopn_device_connect_usb(bool print_failed, CaptureData* capture_data, CaptureDevice* device) {
|
||||
const cyopn_device_usb_device* usb_device_info = (const cyopn_device_usb_device*)device->descriptor;
|
||||
cy_device_device_handlers* handlers = usb_reconnect(usb_device_info, device);
|
||||
if(handlers == NULL) {
|
||||
capture_error_print(true, capture_data, "Device not found");
|
||||
return false;
|
||||
}
|
||||
if(has_to_load_firmware(usb_device_info)) {
|
||||
const cyopn_device_usb_device* next_usb_device_info = GetNextDeviceDesc(usb_device_info);
|
||||
int free_fw_id = usb_find_free_fw_id(next_usb_device_info);
|
||||
int ret = load_firmware(handlers, usb_device_info, free_fw_id);
|
||||
if(!ret) {
|
||||
capture_error_print(true, capture_data, "Firmware load error");
|
||||
return false;
|
||||
}
|
||||
cypress_optimize_new_3ds_connection_end(handlers, usb_device_info);
|
||||
std::string new_serial_number = std::to_string(free_fw_id);
|
||||
CaptureDevice new_device;
|
||||
for(int i = 0; i < 20; i++) {
|
||||
default_sleep(500);
|
||||
handlers = usb_find_by_serial_number(next_usb_device_info, new_serial_number, &new_device);
|
||||
if(handlers != NULL)
|
||||
break;
|
||||
}
|
||||
if(handlers == NULL) {
|
||||
capture_error_print(true, capture_data, "Device reconnection error");
|
||||
return false;
|
||||
}
|
||||
*device = new_device;
|
||||
}
|
||||
capture_data->handle = (void*)handlers;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t cyopn_device_get_video_in_size(bool is_3d, InputVideoDataType video_data_type) {
|
||||
bool is_rgb888 = video_data_type == VIDEO_DATA_RGB;
|
||||
if(is_rgb888) {
|
||||
if(is_3d)
|
||||
return sizeof(USB888New3DSOptimizeCaptureReceived_3D);
|
||||
return sizeof(USB888New3DSOptimizeCaptureReceived);
|
||||
}
|
||||
if(is_3d)
|
||||
return sizeof(USB565New3DSOptimizeCaptureReceived_3D);
|
||||
return sizeof(USB565New3DSOptimizeCaptureReceived);
|
||||
}
|
||||
|
||||
|
||||
uint64_t cyopn_device_get_video_in_size(CaptureStatus* status, bool is_3d, InputVideoDataType video_data_type) {
|
||||
return cyopn_device_get_video_in_size(is_3d, video_data_type);
|
||||
}
|
||||
|
||||
|
||||
uint64_t cyopn_device_get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type) {
|
||||
return cyopn_device_get_video_in_size(&capture_data->status, is_3d, video_data_type);
|
||||
}
|
||||
|
||||
void cyopn_device_acquisition_main_loop(CaptureData* capture_data) {
|
||||
if(!usb_is_initialized())
|
||||
return;
|
||||
}
|
||||
|
||||
void usb_cyopn_device_acquisition_cleanup(CaptureData* capture_data) {
|
||||
if(!usb_is_initialized())
|
||||
return;
|
||||
|
||||
cypress_optimize_new_3ds_connection_end((cy_device_device_handlers*)capture_data->handle, (const cyopn_device_usb_device*)capture_data->status.device.descriptor);
|
||||
capture_data->handle = NULL;
|
||||
}
|
||||
void usb_cyopn_device_init() {
|
||||
return usb_init();
|
||||
}
|
||||
|
||||
void usb_cyopn_device_close() {
|
||||
usb_close();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
#include "frontend.hpp"
|
||||
#include "cypress_optimize_new_3ds_communications.hpp"
|
||||
#include "cypress_shared_communications.hpp"
|
||||
#include "cypress_optimize_new_3ds_acquisition_general.hpp"
|
||||
#include "usb_generic.hpp"
|
||||
|
||||
#include "optimize_new_3ds_fw.h"
|
||||
#include "optimize_new_3ds_565_fpga_pl.h"
|
||||
#include "optimize_new_3ds_888_fpga_pl.h"
|
||||
|
||||
#include <libusb.h>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
// This code was developed by exclusively looking at Wireshark USB packet
|
||||
// captures to learn the USB device's protocol.
|
||||
// As such, it was developed in a clean room environment, to provide
|
||||
// compatibility of the USB device with more (and more modern) hardware.
|
||||
// Such an action is allowed under EU law.
|
||||
// No reverse engineering of the original software was done to create this.
|
||||
|
||||
#define CYPRESS_BASE_USB_PACKET_LIMIT 64
|
||||
#define CYPRESS_OPTIMIZE_NEW_3DS_USB_PACKET_LIMIT 512
|
||||
|
||||
static const cyopn_device_usb_device cypress_optimize_new_3ds_generic_device = {
|
||||
.name = "EZ-USB Optimize New 3DS", .long_name = "EZ-USB Optimize New 3DS",
|
||||
.device_type = CYPRESS_OPTIMIZE_NEW_3DS_BLANK_DEVICE,
|
||||
.firmware_to_load = optimize_new_3ds_fw, .firmware_size = optimize_new_3ds_fw_len,
|
||||
.next_device = CYPRESS_OPTIMIZE_NEW_3DS_BLANK_DEVICE,
|
||||
.has_bcd_device_serial = false,
|
||||
.usb_device_info = {
|
||||
.vid = 0x0752, .pid = 0x8613,
|
||||
.default_config = 1, .default_interface = 0,
|
||||
.bulk_timeout = 500,
|
||||
.ep_ctrl_bulk_in = 0, .ep_ctrl_bulk_out = 0,
|
||||
.ep_bulk_in = 0,
|
||||
.max_usb_packet_size = CYPRESS_BASE_USB_PACKET_LIMIT,
|
||||
.do_pipe_clear_reset = false,
|
||||
.alt_interface = 1,
|
||||
.full_data = &cypress_optimize_new_3ds_generic_device,
|
||||
.get_serial_fn = cypress_optimize_new_3ds_get_serial,
|
||||
.create_device_fn = cypress_optimize_new_3ds_create_device
|
||||
}
|
||||
};
|
||||
|
||||
static const cyopn_device_usb_device* all_usb_cyopn_device_devices_desc[] = {
|
||||
&cypress_optimize_new_3ds_generic_device,
|
||||
};
|
||||
|
||||
const cy_device_usb_device* get_cy_usb_info(const cyopn_device_usb_device* usb_device_desc) {
|
||||
return &usb_device_desc->usb_device_info;
|
||||
}
|
||||
|
||||
int GetNumCyOpNDeviceDesc() {
|
||||
return sizeof(all_usb_cyopn_device_devices_desc) / sizeof(all_usb_cyopn_device_devices_desc[0]);
|
||||
}
|
||||
|
||||
const cyopn_device_usb_device* GetCyOpNDeviceDesc(int index) {
|
||||
if((index < 0) || (index >= GetNumCyOpNDeviceDesc()))
|
||||
index = 0;
|
||||
return all_usb_cyopn_device_devices_desc[index];
|
||||
}
|
||||
|
||||
const cyopn_device_usb_device* GetNextDeviceDesc(const cyopn_device_usb_device* device) {
|
||||
for(int i = 0; i < GetNumCyOpNDeviceDesc(); i++) {
|
||||
const cyopn_device_usb_device* examined_device = GetCyOpNDeviceDesc(i);
|
||||
if(examined_device->device_type == device->next_device)
|
||||
return examined_device;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool has_to_load_firmware(const cyopn_device_usb_device* device) {
|
||||
return !((device->firmware_to_load == NULL) || (device->firmware_size == 0));
|
||||
}
|
||||
|
||||
static bool free_firmware_and_return(uint8_t* fw_data, bool retval) {
|
||||
delete []fw_data;
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool load_firmware(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint8_t patch_id) {
|
||||
if(!has_to_load_firmware(device))
|
||||
return true;
|
||||
int transferred = 0;
|
||||
uint8_t* fw_data = new uint8_t[device->firmware_size];
|
||||
memcpy(fw_data, device->firmware_to_load, device->firmware_size);
|
||||
int num_patches = read_le16(fw_data, 1);
|
||||
for(int i = 0; i < num_patches; i++) {
|
||||
int pos_patch = read_le16(fw_data, 2 + i);
|
||||
write_le16(fw_data + pos_patch, patch_id | 0xFF00);
|
||||
}
|
||||
uint8_t buffer[0x8000];
|
||||
buffer[0] = 1;
|
||||
int ret = cypress_ctrl_out_transfer(handlers, get_cy_usb_info(device), buffer, 1, 0xA0, 0xE600, 0, &transferred);
|
||||
if(ret < 0)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
bool done = false;
|
||||
int fw_pos = read_le16(fw_data);
|
||||
while(!done) {
|
||||
int offset = read_le16(fw_data + fw_pos);
|
||||
int index = read_le16(fw_data + fw_pos, 1);
|
||||
int inside_len = read_le16(fw_data + fw_pos, 2);
|
||||
done = (inside_len & 0x8000) != 0;
|
||||
inside_len &= 0x7FFF;
|
||||
fw_pos += 6;
|
||||
if((inside_len + fw_pos) > device->firmware_size)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
memcpy(buffer, fw_data + fw_pos, inside_len);
|
||||
fw_pos += inside_len;
|
||||
ret = cypress_ctrl_out_transfer(handlers, get_cy_usb_info(device), buffer, inside_len, 0xA0, offset, index, &transferred);
|
||||
if(ret < 0)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
}
|
||||
buffer[0] = 0;
|
||||
ret = cypress_ctrl_out_transfer(handlers, get_cy_usb_info(device), buffer, 1, 0xA0, 0xE600, 0, &transferred);
|
||||
if(ret < 0)
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
return free_firmware_and_return(fw_data, true);
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
// Adapted from sample code provided by Loopy
|
||||
|
||||
#define PRODUCT_SIZE 32
|
||||
#define REAL_SERIAL_NUMBER_SIZE 32
|
||||
#define SERIAL_NUMBER_SIZE (REAL_SERIAL_NUMBER_SIZE+1)
|
||||
|
||||
|
|
@ -131,6 +132,16 @@ static std::string get_serial(libusb_device_handle *handle, libusb_device_descri
|
|||
return serial_str;
|
||||
}
|
||||
|
||||
static bool check_product_usable(libusb_device_handle *handle, libusb_device_descriptor *usb_descriptor) {
|
||||
uint8_t data[PRODUCT_SIZE + 1];
|
||||
std::string product_str = "";
|
||||
if(libusb_get_string_descriptor_ascii(handle, usb_descriptor->iProduct, data, PRODUCT_SIZE-1) >= 0) {
|
||||
data[PRODUCT_SIZE] = '\0';
|
||||
product_str = std::string((const char*)data);
|
||||
}
|
||||
return product_str != "N3DSCC";
|
||||
}
|
||||
|
||||
static int do_usb_config_device(libusb_device_handle *handle, const usb_device* usb_device_desc) {
|
||||
libusb_check_and_detach_kernel_driver(handle, usb_device_desc->capture_interface);
|
||||
int result = libusb_check_and_set_configuration(handle, usb_device_desc->default_config);
|
||||
|
|
@ -160,6 +171,10 @@ static int insert_device(std::vector<CaptureDevice> &devices_list, const usb_dev
|
|||
libusb_close(handle);
|
||||
return result;
|
||||
}
|
||||
if(!check_product_usable(handle, usb_descriptor)) {
|
||||
libusb_close(handle);
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
}
|
||||
std::string serial_str = get_serial(handle, usb_descriptor, curr_serial_extra_id);
|
||||
if(usb_device_desc->is_3ds)
|
||||
devices_list.emplace_back(serial_str, "3DS", CAPTURE_CONN_USB, (void*)usb_device_desc, true, capture_get_has_3d(handle, usb_device_desc), true, HEIGHT_3DS, TOP_WIDTH_3DS + BOT_WIDTH_3DS, O3DS_SAMPLES_IN, 90, 0, 0, TOP_WIDTH_3DS, 0, VIDEO_DATA_RGB);
|
||||
|
|
@ -189,6 +204,10 @@ static libusb_device_handle* usb_find_by_serial_number(const usb_device* usb_dev
|
|||
result = libusb_open(usb_devices[i], &handle);
|
||||
if(result || (handle == NULL))
|
||||
continue;
|
||||
if(!check_product_usable(handle, &usb_descriptor)) {
|
||||
libusb_close(handle);
|
||||
continue;
|
||||
}
|
||||
std::string device_serial_number = get_serial(handle, &usb_descriptor, curr_serial_extra_id);
|
||||
if(serial_number == device_serial_number) {
|
||||
final_handle = handle;
|
||||
|
|
|
|||
|
|
@ -420,10 +420,10 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) {
|
|||
CaptureDataSingleBuffer* data_buffer = capture_data->data_buffers.GetReaderBuffer(CAPTURE_READER_AUDIO);
|
||||
if(data_buffer != NULL) {
|
||||
loaded_samples = audio.samples.size();
|
||||
if((data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) {
|
||||
if((data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->buffer_video_data_type)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) {
|
||||
uint64_t n_samples = get_audio_n_samples(capture_data, data_buffer);
|
||||
double out_time = data_buffer->time_in_buf;
|
||||
bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, last_buffer_index, endianness, data_buffer, &capture_data->status, data_buffer->is_3d);
|
||||
bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, last_buffer_index, endianness, data_buffer, &capture_data->status);
|
||||
if(!conversion_success)
|
||||
audio_data->signal_conversion_error();
|
||||
audio.samples.emplace(out_buf[audio_buf_counter], n_samples, out_time);
|
||||
|
|
@ -604,11 +604,11 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data,
|
|||
CaptureDataSingleBuffer* data_buffer = capture_data->data_buffers.GetReaderBuffer(CAPTURE_READER_VIDEO);
|
||||
if(data_buffer != NULL) {
|
||||
last_frame_time = data_buffer->time_in_buf;
|
||||
if(data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d)) {
|
||||
if(data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->buffer_video_data_type)) {
|
||||
if(capture_data->status.cooldown_curr_in || (!capture_data->status.connected))
|
||||
blank_out = true;
|
||||
else {
|
||||
bool conversion_success = convertVideoToOutput(out_buf, endianness, data_buffer, &capture_data->status, frontend_data.display_data.interleaved_3d, data_buffer->is_3d);
|
||||
bool conversion_success = convertVideoToOutput(out_buf, endianness, data_buffer, &capture_data->status, frontend_data.display_data.interleaved_3d);
|
||||
if(!conversion_success)
|
||||
UpdateOutText(out_text_data, "", "Video conversion failed...", TEXT_KIND_NORMAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -804,10 +804,12 @@ static void usb_is_device_convertVideoToOutput(CaptureReceived *p_in, VideoOutpu
|
|||
}
|
||||
}
|
||||
|
||||
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d, bool is_data_3d) {
|
||||
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d) {
|
||||
CaptureReceived* p_in = (CaptureReceived*)(((uint8_t*)&data_buffer->capture_buf) + data_buffer->unused_offset);
|
||||
bool converted = false;
|
||||
CaptureDevice* chosen_device = &status->device;
|
||||
bool is_data_3d = data_buffer->is_3d;
|
||||
InputVideoDataType video_data_type = data_buffer->buffer_video_data_type;
|
||||
bool is_3d_requested = get_3d_enabled(status);
|
||||
#ifdef USE_FTD3
|
||||
if(chosen_device->cc_type == CAPTURE_CONN_FTD3) {
|
||||
|
|
@ -841,8 +843,8 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt
|
|||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
if(status->device.cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE) {
|
||||
bool is_rgb888 = true;
|
||||
usb_new_3ds_optimize_convertVideoToOutput(p_in, p_out, is_data_3d, is_big_endian, interleaved_3d, requested_3d, is_rgb888);
|
||||
bool is_rgb888 = video_data_type == VIDEO_DATA_RGB;
|
||||
usb_new_3ds_optimize_convertVideoToOutput(p_in, p_out, is_data_3d, is_big_endian, interleaved_3d, is_3d_requested, is_rgb888);
|
||||
converted = true;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -922,9 +924,11 @@ static void copyAudioNewOptimize3DSBE(std::int16_t *p_out, uint64_t &n_samples,
|
|||
n_samples = ((last_buffer_index + 1 + OPTIMIZE_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE) * 2;
|
||||
}
|
||||
|
||||
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool is_data_3d) {
|
||||
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status) {
|
||||
if(!status->device.has_audio)
|
||||
return true;
|
||||
bool is_data_3d = data_buffer->is_3d;
|
||||
InputVideoDataType video_data_type = data_buffer->buffer_video_data_type;
|
||||
CaptureReceived* p_in = (CaptureReceived*)(((uint8_t*)&data_buffer->capture_buf) + data_buffer->unused_offset);
|
||||
uint8_t* base_ptr = NULL;
|
||||
#ifdef USE_FTD3
|
||||
|
|
@ -967,7 +971,7 @@ bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &la
|
|||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
if(status->device.cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE) {
|
||||
bool is_rgb888 = true;
|
||||
bool is_rgb888 = video_data_type == VIDEO_DATA_RGB;
|
||||
if(is_big_endian)
|
||||
copyAudioNewOptimize3DSBE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888, is_data_3d);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "usb_ds_3ds_capture.hpp"
|
||||
#include "usb_is_device_acquisition.hpp"
|
||||
#include "cypress_nisetro_acquisition.hpp"
|
||||
#include "cypress_optimize_new_3ds_acquisition.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
|
@ -87,6 +88,9 @@ bool connect(bool print_failed, CaptureData* capture_data, FrontendData* fronten
|
|||
#ifdef USE_CYNI_USB
|
||||
list_devices_cyni_device(devices_list, no_access_list);
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
list_devices_cyopn_device(devices_list, no_access_list);
|
||||
#endif
|
||||
#ifdef USE_FTD3
|
||||
list_devices_ftd3(devices_list, no_access_list);
|
||||
#endif
|
||||
|
|
@ -128,6 +132,10 @@ bool connect(bool print_failed, CaptureData* capture_data, FrontendData* fronten
|
|||
if((devices_list[chosen_device].cc_type == CAPTURE_CONN_CYPRESS_NISETRO) && (!cyni_device_connect_usb(print_failed, capture_data, &devices_list[chosen_device])))
|
||||
return false;
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
if((devices_list[chosen_device].cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE) && (!cyopn_device_connect_usb(print_failed, capture_data, &devices_list[chosen_device])))
|
||||
return false;
|
||||
#endif
|
||||
#ifdef USE_FTD3
|
||||
if((devices_list[chosen_device].cc_type == CAPTURE_CONN_FTD3) && (!connect_ftd3(print_failed, capture_data, &devices_list[chosen_device])))
|
||||
return false;
|
||||
|
|
@ -168,6 +176,10 @@ void captureCall(CaptureData* capture_data) {
|
|||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NISETRO)
|
||||
cyni_device_acquisition_main_loop(capture_data);
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE)
|
||||
cyopn_device_acquisition_main_loop(capture_data);
|
||||
#endif
|
||||
#ifdef USE_FTD3
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD3)
|
||||
ftd3_capture_main_loop(capture_data);
|
||||
|
|
@ -198,6 +210,10 @@ void captureCall(CaptureData* capture_data) {
|
|||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NISETRO)
|
||||
usb_cyni_device_acquisition_cleanup(capture_data);
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE)
|
||||
usb_cyopn_device_acquisition_cleanup(capture_data);
|
||||
#endif
|
||||
#ifdef USE_FTD3
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD3)
|
||||
ftd3_capture_cleanup(capture_data);
|
||||
|
|
@ -229,7 +245,7 @@ uint64_t get_audio_n_samples(CaptureData* capture_data, CaptureDataSingleBuffer*
|
|||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE)
|
||||
return -1;
|
||||
#endif
|
||||
uint64_t n_samples = (data_buffer->read - get_video_in_size(capture_data, data_buffer->is_3d)) / 2;
|
||||
uint64_t n_samples = (data_buffer->read - get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->buffer_video_data_type)) / 2;
|
||||
if(n_samples > capture_data->status.device.max_samples_in)
|
||||
n_samples = capture_data->status.device.max_samples_in;
|
||||
// Avoid entering a glitched state due to a partial packet or something
|
||||
|
|
@ -238,11 +254,15 @@ uint64_t get_audio_n_samples(CaptureData* capture_data, CaptureDataSingleBuffer*
|
|||
return n_samples;
|
||||
}
|
||||
|
||||
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d) {
|
||||
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type) {
|
||||
#ifdef USE_CYNI_USB
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NISETRO)
|
||||
return cyni_device_get_video_in_size(capture_data);
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE)
|
||||
return cyopn_device_get_video_in_size(capture_data, is_3d, video_data_type);
|
||||
#endif
|
||||
#ifdef USE_FTD3
|
||||
if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD3)
|
||||
return ftd3_get_video_in_size(capture_data, is_3d);
|
||||
|
|
@ -344,6 +364,9 @@ void capture_init() {
|
|||
#ifdef USE_CYNI_USB
|
||||
usb_cyni_device_init();
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
usb_cyopn_device_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void capture_close() {
|
||||
|
|
@ -359,4 +382,7 @@ void capture_close() {
|
|||
#ifdef USE_CYNI_USB
|
||||
usb_cyni_device_close();
|
||||
#endif
|
||||
#ifdef USE_CYPRESS_NEW_OPTIMIZE
|
||||
usb_cyopn_device_close();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
1
usb_rules/51-optimize.rules
Normal file
1
usb_rules/51-optimize.rules
Normal file
|
|
@ -0,0 +1 @@
|
|||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0752", ATTRS{idProduct}=="8613", MODE="0666"
|
||||
Loading…
Reference in New Issue
Block a user