mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2025-06-18 16:45:39 -04:00
No output with start capture implementation for Optimize N3DS
This commit is contained in:
parent
7aabe62753
commit
cbd0d9d77a
@ -72,7 +72,7 @@ int cypress_ctrl_out_transfer(cy_device_device_handlers* handlers, const cy_devi
|
||||
int cypress_bulk_in_transfer(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, uint8_t* buf, int length, int* transferred);
|
||||
int cypress_bulk_in_async(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, uint8_t *buf, int length, cy_async_callback_data* cb_data);
|
||||
int cypress_ctrl_bulk_in_transfer(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, uint8_t* buf, int length, int* transferred);
|
||||
int cypress_ctrl_bulk_out_transfer(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, uint8_t* buf, int length, int* transferred);
|
||||
int cypress_ctrl_bulk_out_transfer(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, const uint8_t* buf, int length, int* transferred);
|
||||
void cypress_pipe_reset_bulk_in(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc);
|
||||
void cypress_pipe_reset_ctrl_bulk_in(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc);
|
||||
void cypress_pipe_reset_ctrl_bulk_out(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
enum cypress_optimize_new_device_type {
|
||||
CYPRESS_OPTIMIZE_NEW_3DS_BLANK_DEVICE,
|
||||
CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE,
|
||||
};
|
||||
|
||||
struct cyopn_device_usb_device {
|
||||
@ -19,6 +20,14 @@ struct cyopn_device_usb_device {
|
||||
cypress_optimize_new_device_type device_type;
|
||||
uint8_t* firmware_to_load;
|
||||
size_t firmware_size;
|
||||
uint8_t* fpga_pl_565;
|
||||
size_t fpga_pl_565_size;
|
||||
uint8_t* fpga_pl_565_3d;
|
||||
size_t fpga_pl_565_3d_size;
|
||||
uint8_t* fpga_pl_888;
|
||||
size_t fpga_pl_888_size;
|
||||
uint8_t* fpga_pl_888_3d;
|
||||
size_t fpga_pl_888_3d_size;
|
||||
cypress_optimize_new_device_type next_device;
|
||||
bool has_bcd_device_serial;
|
||||
cy_device_usb_device usb_device_info;
|
||||
@ -31,8 +40,8 @@ const cyopn_device_usb_device* GetNextDeviceDesc(const cyopn_device_usb_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_start(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, bool is_first_load, bool is_rgb888);
|
||||
int StartCaptureDma(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, bool is_rgb888);
|
||||
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);
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#define OPTIMIZE_NEW_3DS_ALTERNATIVE_PRODUCT_NAME "N3DSCC"
|
||||
|
||||
#define OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE 0x200
|
||||
|
||||
enum CaptureConnectionType { CAPTURE_CONN_FTD3, CAPTURE_CONN_USB, CAPTURE_CONN_FTD2, CAPTURE_CONN_IS_NITRO, CAPTURE_CONN_CYPRESS_NISETRO, CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE };
|
||||
enum InputVideoDataType { VIDEO_DATA_RGB, VIDEO_DATA_BGR, VIDEO_DATA_RGB16, VIDEO_DATA_BGR16 };
|
||||
enum CaptureScreensType { CAPTURE_SCREENS_BOTH, CAPTURE_SCREENS_TOP, CAPTURE_SCREENS_BOTTOM, CAPTURE_SCREENS_ENUM_END };
|
||||
@ -251,7 +253,7 @@ struct CaptureDevice {
|
||||
CaptureDevice(std::string serial_number, std::string name, CaptureConnectionType cc_type, const void* descriptor, bool is_3ds, bool has_3d, bool has_audio, int width, int height, uint64_t max_samples_in, int base_rotation, int top_screen_x, int top_screen_y, int bot_screen_x, int bot_screen_y, InputVideoDataType video_data_type) : serial_number(serial_number), name(name), cc_type(cc_type), descriptor(descriptor), is_3ds(is_3ds), has_3d(has_3d), has_audio(has_audio), width(width), height(height), max_samples_in(max_samples_in), base_rotation(base_rotation), top_screen_x(top_screen_x), top_screen_y(top_screen_y), bot_screen_x(bot_screen_x), bot_screen_y(bot_screen_y), video_data_type(video_data_type), long_name(name) {}
|
||||
CaptureDevice(std::string serial_number, std::string name, std::string long_name, CaptureConnectionType cc_type, const void* descriptor, bool is_3ds, bool has_3d, bool has_audio, int width, int height, uint64_t max_samples_in, int base_rotation, int top_screen_x, int top_screen_y, int bot_screen_x, int bot_screen_y, InputVideoDataType video_data_type, std::string path = "") : serial_number(serial_number), name(name), cc_type(cc_type), descriptor(descriptor), is_3ds(is_3ds), has_3d(has_3d), has_audio(has_audio), width(width), height(height), max_samples_in(max_samples_in), base_rotation(base_rotation), top_screen_x(top_screen_x), top_screen_y(top_screen_y), bot_screen_x(bot_screen_x), bot_screen_y(bot_screen_y), video_data_type(video_data_type), path(path), long_name(long_name) {}
|
||||
CaptureDevice(std::string serial_number, std::string name, std::string long_name, CaptureConnectionType cc_type, const void* descriptor, bool is_3ds, bool has_3d, bool has_audio, int width, int height, uint64_t max_samples_in, int base_rotation, int top_screen_x, int top_screen_y, int bot_screen_x, int bot_screen_y, InputVideoDataType video_data_type, int firmware_id, bool is_rgb_888, std::string path = "") : serial_number(serial_number), name(name), cc_type(cc_type), descriptor(descriptor), is_3ds(is_3ds), has_3d(has_3d), has_audio(has_audio), width(width), height(height), max_samples_in(max_samples_in), base_rotation(base_rotation), top_screen_x(top_screen_x), top_screen_y(top_screen_y), bot_screen_x(bot_screen_x), bot_screen_y(bot_screen_y), path(path), video_data_type(video_data_type), firmware_id(firmware_id), is_rgb_888(is_rgb_888), long_name(long_name) {}
|
||||
CaptureDevice(std::string serial_number, std::string name, std::string long_name, CaptureConnectionType cc_type, const void* descriptor, bool is_3ds, bool has_3d, bool has_audio, int width, int height, int width_3d, int height_3d, uint64_t max_samples_in, int base_rotation, int top_screen_x, int top_screen_y, int second_top_screen_x, int second_top_screen_y, int bot_screen_x, int bot_screen_y, bool is_second_top_screen_right, InputVideoDataType video_data_type, uint32_t usb_speed) : serial_number(serial_number), name(name), cc_type(cc_type), descriptor(descriptor), is_3ds(is_3ds), has_3d(has_3d), has_audio(has_audio), width(width), height(height), max_samples_in(max_samples_in), base_rotation(base_rotation), top_screen_x(top_screen_x), top_screen_y(top_screen_y), bot_screen_x(bot_screen_x), bot_screen_y(bot_screen_y), video_data_type(video_data_type), long_name(long_name), usb_speed(usb_speed), second_top_screen_x(second_top_screen_x), second_top_screen_y(second_top_screen_y), width_3d(width_3d), height_3d(height_3d), is_second_top_screen_right(is_second_top_screen_right) {}
|
||||
CaptureDevice(std::string serial_number, std::string name, std::string long_name, CaptureConnectionType cc_type, const void* descriptor, bool is_3ds, bool has_3d, bool has_audio, int width, int height, int width_3d, int height_3d, uint64_t max_samples_in, int base_rotation, int top_screen_x, int top_screen_y, int second_top_screen_x, int second_top_screen_y, int bot_screen_x, int bot_screen_y, bool is_second_top_screen_right, InputVideoDataType video_data_type, uint32_t usb_speed, std::string path = "") : serial_number(serial_number), name(name), cc_type(cc_type), descriptor(descriptor), is_3ds(is_3ds), has_3d(has_3d), has_audio(has_audio), width(width), height(height), max_samples_in(max_samples_in), base_rotation(base_rotation), top_screen_x(top_screen_x), top_screen_y(top_screen_y), bot_screen_x(bot_screen_x), bot_screen_y(bot_screen_y), video_data_type(video_data_type), long_name(long_name), usb_speed(usb_speed), second_top_screen_x(second_top_screen_x), second_top_screen_y(second_top_screen_y), width_3d(width_3d), height_3d(height_3d), is_second_top_screen_right(is_second_top_screen_right), path(path) {}
|
||||
CaptureDevice() : usb_speed(0) {}
|
||||
|
||||
std::string serial_number = "";
|
||||
|
@ -47,10 +47,14 @@ uint16_t read_le16(const uint8_t* data, size_t count = 0, size_t multiplier = si
|
||||
uint16_t read_be16(const uint8_t* data, size_t count = 0, size_t multiplier = sizeof(uint16_t));
|
||||
uint32_t read_le32(const uint8_t* data, size_t count = 0, size_t multiplier = sizeof(uint32_t));
|
||||
uint32_t read_be32(const uint8_t* data, size_t count = 0, size_t multiplier = sizeof(uint32_t));
|
||||
uint64_t read_le64(const uint8_t* data, size_t count = 0, size_t multiplier = sizeof(uint64_t));
|
||||
uint64_t read_be64(const uint8_t* data, size_t count = 0, size_t multiplier = sizeof(uint64_t));
|
||||
void write_le16(uint8_t* data, uint16_t value, size_t count = 0, size_t multiplier = sizeof(uint16_t));
|
||||
void write_be16(uint8_t* data, uint16_t value, size_t count = 0, size_t multiplier = sizeof(uint16_t));
|
||||
void write_le32(uint8_t* data, uint32_t value, size_t count = 0, size_t multiplier = sizeof(uint32_t));
|
||||
void write_be32(uint8_t* data, uint32_t value, size_t count = 0, size_t multiplier = sizeof(uint32_t));
|
||||
void write_le64(uint8_t* data, uint64_t value, size_t count = 0, size_t multiplier = sizeof(uint64_t));
|
||||
void write_be64(uint8_t* data, uint64_t value, size_t count = 0, size_t multiplier = sizeof(uint64_t));
|
||||
void write_string(uint8_t* data, std::string text);
|
||||
std::string read_string(uint8_t* data, size_t size);
|
||||
uint32_t rotate_bits_left(uint32_t value);
|
||||
|
@ -52,10 +52,10 @@ int cypress_ctrl_bulk_in_transfer(cy_device_device_handlers* handlers, const cy_
|
||||
return cypress_driver_ctrl_bulk_in(handlers, usb_device_desc, buf, length, transferred);
|
||||
}
|
||||
|
||||
int cypress_ctrl_bulk_out_transfer(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, uint8_t* buf, int length, int* transferred) {
|
||||
int cypress_ctrl_bulk_out_transfer(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc, const uint8_t* buf, int length, int* transferred) {
|
||||
if(handlers->usb_handle)
|
||||
return cypress_libusb_ctrl_bulk_out(handlers, usb_device_desc, buf, length, transferred);
|
||||
return cypress_driver_ctrl_bulk_out(handlers, usb_device_desc, buf, length, transferred);
|
||||
return cypress_libusb_ctrl_bulk_out(handlers, usb_device_desc, (uint8_t*)buf, length, transferred);
|
||||
return cypress_driver_ctrl_bulk_out(handlers, usb_device_desc, (uint8_t*)buf, length, transferred);
|
||||
}
|
||||
|
||||
void cypress_pipe_reset_bulk_in(cy_device_device_handlers* handlers, const cy_device_usb_device* usb_device_desc) {
|
||||
|
@ -98,7 +98,7 @@ std::string cypress_optimize_new_3ds_get_serial(const void* usb_device_desc, std
|
||||
}
|
||||
|
||||
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);
|
||||
return CaptureDevice(serial, usb_device_desc->name, usb_device_desc->long_name, CAPTURE_CONN_CYPRESS_NEW_OPTIMIZE, (void*)usb_device_desc, true, true, true, HEIGHT_3DS, TOP_WIDTH_3DS + BOT_WIDTH_3DS, HEIGHT_3DS, (TOP_WIDTH_3DS * 2) + BOT_WIDTH_3DS, OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE, 90, BOT_WIDTH_3DS, 0, BOT_WIDTH_3DS + TOP_WIDTH_3DS, 0, 0, 0, false, VIDEO_DATA_RGB16, 0x200, path);
|
||||
}
|
||||
|
||||
CaptureDevice cypress_optimize_new_3ds_create_device(const void* usb_device_desc, std::string serial, std::string path) {
|
||||
@ -203,9 +203,255 @@ uint64_t cyopn_device_get_video_in_size(CaptureData* capture_data, bool is_3d, I
|
||||
return cyopn_device_get_video_in_size(&capture_data->status, is_3d, video_data_type);
|
||||
}
|
||||
|
||||
static int cypress_device_read_frame_request(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, uint32_t index, bool is_3d, InputVideoDataType video_data_type) {
|
||||
if(cypress_device_capture_recv_data == NULL)
|
||||
return LIBUSB_SUCCESS;
|
||||
if((*cypress_device_capture_recv_data->status) < 0) {
|
||||
cypress_device_capture_recv_data->in_use = false;
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
const cyopn_device_usb_device* usb_device_info = (const cyopn_device_usb_device*)capture_data->status.device.descriptor;
|
||||
cypress_device_capture_recv_data->index = index;
|
||||
cypress_device_capture_recv_data->cb_data.function = cypress_device_read_frame_cb;
|
||||
size_t read_size = cyopn_device_get_video_in_size(is_3d, video_data_type);
|
||||
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(cypress_device_capture_recv_data->cb_data.internal_index);
|
||||
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
|
||||
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(CypressOptimizeNew3DSDeviceCaptureReceivedData* 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;
|
||||
cypress_device_capture_recv_data->is_buffer_free_shared_mutex->specific_unlock(cypress_device_capture_recv_data->cb_data.internal_index);
|
||||
}
|
||||
|
||||
static void cypress_device_read_frame_cb(void* user_data, int transfer_length, int transfer_status) {
|
||||
CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data = (CypressOptimizeNew3DSDeviceCaptureReceivedData*)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) {
|
||||
int error = LIBUSB_ERROR_OTHER;
|
||||
if(transfer_status == LIBUSB_TRANSFER_TIMED_OUT)
|
||||
error = LIBUSB_ERROR_TIMEOUT;
|
||||
*cypress_device_capture_recv_data->status = error;
|
||||
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
||||
}
|
||||
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
||||
}
|
||||
|
||||
static int cypress_device_get_num_free_buffers(CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
int num_free = 0;
|
||||
for(int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++)
|
||||
if(!cypress_device_capture_recv_data[i].in_use)
|
||||
num_free += 1;
|
||||
return num_free;
|
||||
}
|
||||
|
||||
static void close_all_reads_error(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool &async_read_closed) {
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
const cyopn_device_usb_device* usb_device_desc = (const cyopn_device_usb_device*)capture_data->status.device.descriptor;
|
||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0) {
|
||||
if(!async_read_closed) {
|
||||
if(handlers->usb_handle) {
|
||||
for (int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++)
|
||||
CypressCloseAsyncRead(handlers, get_cy_usb_info(usb_device_desc), &cypress_device_capture_recv_data[i].cb_data);
|
||||
}
|
||||
else
|
||||
CypressCloseAsyncRead(handlers, get_cy_usb_info(usb_device_desc), &cypress_device_capture_recv_data[0].cb_data);
|
||||
async_read_closed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool has_too_much_time_passed(const std::chrono::time_point<std::chrono::high_resolution_clock> &start_time) {
|
||||
const auto curr_time = std::chrono::high_resolution_clock::now();
|
||||
const std::chrono::duration<double> diff = curr_time - start_time;
|
||||
return diff.count() > MAX_TIME_WAIT;
|
||||
}
|
||||
|
||||
static void error_too_much_time_passed(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* 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, CypressOptimizeNew3DSDeviceCaptureReceivedData* 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;
|
||||
bool async_read_closed = false;
|
||||
close_all_reads_error(capture_data, cypress_device_capture_recv_data, async_read_closed);
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
for(int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++)
|
||||
while(cypress_device_capture_recv_data[i].in_use) {
|
||||
error_too_much_time_passed(capture_data, cypress_device_capture_recv_data, async_read_closed, start_time);
|
||||
cypress_device_capture_recv_data[i].is_buffer_free_shared_mutex->specific_timed_lock(i);
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_one_cypress_device_buffer_free(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* 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();
|
||||
while(!done) {
|
||||
for(int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++) {
|
||||
if(!cypress_device_capture_recv_data[i].in_use)
|
||||
done = true;
|
||||
}
|
||||
if(!done) {
|
||||
if(has_too_much_time_passed(start_time))
|
||||
return;
|
||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)
|
||||
return;
|
||||
int dummy = 0;
|
||||
cypress_device_capture_recv_data[0].is_buffer_free_shared_mutex->general_timed_lock(&dummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_specific_cypress_device_buffer_free(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* 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();
|
||||
while(!done) {
|
||||
if(!cypress_device_capture_recv_data->in_use)
|
||||
done = true;
|
||||
if(!done) {
|
||||
if(has_too_much_time_passed(start_time))
|
||||
return;
|
||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)
|
||||
return;
|
||||
int dummy = 0;
|
||||
cypress_device_capture_recv_data->is_buffer_free_shared_mutex->general_timed_lock(&dummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool cypress_device_are_buffers_all_free(CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
return cypress_device_get_num_free_buffers(cypress_device_capture_recv_data) == NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS;
|
||||
}
|
||||
|
||||
static CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_get_free_buffer(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* 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;
|
||||
for(int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++)
|
||||
if(!cypress_device_capture_recv_data[i].in_use) {
|
||||
cypress_device_capture_recv_data[i].is_buffer_free_shared_mutex->specific_try_lock(i);
|
||||
cypress_device_capture_recv_data[i].in_use = true;
|
||||
return &cypress_device_capture_recv_data[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int get_cypress_device_status(CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
return *cypress_device_capture_recv_data[0].status;
|
||||
}
|
||||
|
||||
static void error_cypress_device_status(CypressOptimizeNew3DSDeviceCaptureReceivedData* 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;
|
||||
}
|
||||
|
||||
static void exported_error_cypress_device_status(void* data, int error_val) {
|
||||
if(data == NULL)
|
||||
return;
|
||||
return error_cypress_device_status((CypressOptimizeNew3DSDeviceCaptureReceivedData*)data, error_val);
|
||||
}
|
||||
|
||||
static void reset_cypress_device_status(CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
error_cypress_device_status(cypress_device_capture_recv_data, 0);
|
||||
}
|
||||
|
||||
static bool cyopn_device_acquisition_loop(CaptureData* capture_data, CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
const cyopn_device_usb_device* usb_device_desc = (const cyopn_device_usb_device*)capture_data->status.device.descriptor;
|
||||
InputVideoDataType stored_video_data_type = capture_data->status.device.video_data_type;
|
||||
bool stored_is_3d = false;
|
||||
uint32_t index = 0;
|
||||
int ret = capture_start(handlers, usb_device_desc, true, stored_video_data_type == VIDEO_DATA_RGB);
|
||||
if (ret < 0) {
|
||||
capture_error_print(true, capture_data, "Capture Start: Failed");
|
||||
return false;
|
||||
}
|
||||
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), cyopn_device_get_video_in_size(stored_is_3d, stored_video_data_type));
|
||||
auto clock_last_reset = std::chrono::high_resolution_clock::now();
|
||||
for(int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++) {
|
||||
CypressOptimizeNew3DSDeviceCaptureReceivedData* 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++, stored_is_3d, stored_video_data_type);
|
||||
if(ret < 0) {
|
||||
chosen_buffer->in_use = false;
|
||||
error_cypress_device_status(cypress_device_capture_recv_data, ret);
|
||||
capture_error_print(true, capture_data, "Initial Reads: Failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
StartCaptureDma(handlers, usb_device_desc, stored_video_data_type == VIDEO_DATA_RGB);
|
||||
while (capture_data->status.connected && capture_data->status.running) {
|
||||
ret = get_cypress_device_status(cypress_device_capture_recv_data);
|
||||
if(ret < 0) {
|
||||
wait_all_cypress_device_buffers_free(capture_data, cypress_device_capture_recv_data);
|
||||
capture_error_print(true, capture_data, "Disconnected: Read error");
|
||||
return false;
|
||||
}
|
||||
CypressOptimizeNew3DSDeviceCaptureReceivedData* 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);
|
||||
ret = cypress_device_read_frame_request(capture_data, chosen_buffer, index++, stored_is_3d, stored_video_data_type);
|
||||
if(ret < 0) {
|
||||
chosen_buffer->in_use = false;
|
||||
error_cypress_device_status(cypress_device_capture_recv_data, ret);
|
||||
capture_error_print(true, capture_data, "Setup Read: Failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cyopn_device_acquisition_main_loop(CaptureData* capture_data) {
|
||||
if(!usb_is_initialized())
|
||||
return;
|
||||
bool is_done_thread;
|
||||
std::thread async_processing_thread;
|
||||
cy_device_device_handlers* handlers = (cy_device_device_handlers*)capture_data->handle;
|
||||
const cyopn_device_usb_device* usb_device_desc = (const cyopn_device_usb_device*)capture_data->status.device.descriptor;
|
||||
|
||||
uint32_t last_index = -1;
|
||||
int status = 0;
|
||||
std::vector<cy_async_callback_data*> cb_queue;
|
||||
SharedConsumerMutex is_buffer_free_shared_mutex(NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS);
|
||||
SharedConsumerMutex is_transfer_done_shared_mutex(NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS);
|
||||
SharedConsumerMutex is_transfer_data_ready_shared_mutex(NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS);
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> clock_start = std::chrono::high_resolution_clock::now();
|
||||
CypressOptimizeNew3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data = new CypressOptimizeNew3DSDeviceCaptureReceivedData[NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS];
|
||||
for(int i = 0; i < NUM_OPTIMIZE_NEW_3DS_CYPRESS_BUFFERS; i++) {
|
||||
cypress_device_capture_recv_data[i].in_use = false;
|
||||
cypress_device_capture_recv_data[i].index = i;
|
||||
cypress_device_capture_recv_data[i].capture_data = capture_data;
|
||||
cypress_device_capture_recv_data[i].last_index = &last_index;
|
||||
cypress_device_capture_recv_data[i].clock_start = &clock_start;
|
||||
cypress_device_capture_recv_data[i].is_buffer_free_shared_mutex = &is_buffer_free_shared_mutex;
|
||||
cypress_device_capture_recv_data[i].status = &status;
|
||||
cypress_device_capture_recv_data[i].cb_data.actual_user_data = &cypress_device_capture_recv_data[i];
|
||||
cypress_device_capture_recv_data[i].cb_data.transfer_data = NULL;
|
||||
cypress_device_capture_recv_data[i].cb_data.is_transfer_done_mutex = &is_transfer_done_shared_mutex;
|
||||
cypress_device_capture_recv_data[i].cb_data.internal_index = i;
|
||||
cypress_device_capture_recv_data[i].cb_data.is_transfer_data_ready_mutex = &is_transfer_data_ready_shared_mutex;
|
||||
cypress_device_capture_recv_data[i].cb_data.in_use_ptr = &cypress_device_capture_recv_data[i].in_use;
|
||||
cypress_device_capture_recv_data[i].cb_data.error_function = exported_error_cypress_device_status;
|
||||
cb_queue.push_back(&cypress_device_capture_recv_data[i].cb_data);
|
||||
}
|
||||
CypressSetupCypressDeviceAsyncThread(handlers, cb_queue, &async_processing_thread, &is_done_thread);
|
||||
bool proper_return = cyopn_device_acquisition_loop(capture_data, cypress_device_capture_recv_data);
|
||||
wait_all_cypress_device_buffers_free(capture_data, cypress_device_capture_recv_data);
|
||||
CypressEndCypressDeviceAsyncThread(handlers, cb_queue, &async_processing_thread, &is_done_thread);
|
||||
delete []cypress_device_capture_recv_data;
|
||||
|
||||
if(proper_return)
|
||||
capture_end(handlers, usb_device_desc);
|
||||
}
|
||||
|
||||
void usb_cyopn_device_acquisition_cleanup(CaptureData* capture_data) {
|
||||
|
@ -28,7 +28,11 @@ 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,
|
||||
.fpga_pl_565 = NULL, .fpga_pl_565_size = 0,
|
||||
.fpga_pl_565_3d = NULL, .fpga_pl_565_3d_size = 0,
|
||||
.fpga_pl_888 = NULL, .fpga_pl_888_size = 0,
|
||||
.fpga_pl_888_3d = NULL, .fpga_pl_888_3d_size = 0,
|
||||
.next_device = CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE,
|
||||
.has_bcd_device_serial = false,
|
||||
.usb_device_info = {
|
||||
.vid = 0x0752, .pid = 0x8613,
|
||||
@ -47,8 +51,36 @@ static const cyopn_device_usb_device cypress_optimize_new_3ds_generic_device = {
|
||||
}
|
||||
};
|
||||
|
||||
static const cyopn_device_usb_device cypress_optimize_new_3ds_instantiated_device = {
|
||||
.name = "Optimize New 3DS", .long_name = "Optimize New 3DS",
|
||||
.device_type = CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE,
|
||||
.firmware_to_load = NULL, .firmware_size = 0,
|
||||
.fpga_pl_565 = optimize_new_3ds_565_fpga_pl, .fpga_pl_565_size = optimize_new_3ds_565_fpga_pl_len,
|
||||
.fpga_pl_565_3d = NULL, .fpga_pl_565_3d_size = 0,
|
||||
.fpga_pl_888 = optimize_new_3ds_888_fpga_pl, .fpga_pl_888_size = optimize_new_3ds_888_fpga_pl_len,
|
||||
.fpga_pl_888_3d = NULL, .fpga_pl_888_3d_size = 0,
|
||||
.next_device = CYPRESS_OPTIMIZE_NEW_3DS_INSTANTIATED_DEVICE,
|
||||
.has_bcd_device_serial = true,
|
||||
.usb_device_info = {
|
||||
.vid = 0x16d0, .pid = 0x06a3,
|
||||
.default_config = 1, .default_interface = 0,
|
||||
.bulk_timeout = 500,
|
||||
.ep_ctrl_bulk_in = 1 | LIBUSB_ENDPOINT_IN, .ep_ctrl_bulk_out = 1 | LIBUSB_ENDPOINT_OUT,
|
||||
.ep_bulk_in = 2 | LIBUSB_ENDPOINT_IN,
|
||||
.max_usb_packet_size = CYPRESS_OPTIMIZE_NEW_3DS_USB_PACKET_LIMIT,
|
||||
.do_pipe_clear_reset = true,
|
||||
.alt_interface = 0,
|
||||
.full_data = &cypress_optimize_new_3ds_instantiated_device,
|
||||
.get_serial_fn = cypress_optimize_new_3ds_get_serial,
|
||||
.create_device_fn = cypress_optimize_new_3ds_create_device,
|
||||
.filter_for_product = true,
|
||||
.wanted_product_str = OPTIMIZE_NEW_3DS_ALTERNATIVE_PRODUCT_NAME
|
||||
}
|
||||
};
|
||||
|
||||
static const cyopn_device_usb_device* all_usb_cyopn_device_devices_desc[] = {
|
||||
&cypress_optimize_new_3ds_generic_device,
|
||||
&cypress_optimize_new_3ds_instantiated_device,
|
||||
};
|
||||
|
||||
const cy_device_usb_device* get_cy_usb_info(const cyopn_device_usb_device* usb_device_desc) {
|
||||
@ -122,3 +154,301 @@ bool load_firmware(cy_device_device_handlers* handlers, const cyopn_device_usb_d
|
||||
return free_firmware_and_return(fw_data, false);
|
||||
return free_firmware_and_return(fw_data, true);
|
||||
}
|
||||
|
||||
static int read_device_info(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device) {
|
||||
const uint8_t first_out_buffer[] = { 0x65 };
|
||||
const int read_block_size = 0x10;
|
||||
const int num_reads = 8;
|
||||
uint8_t in_buffer[read_block_size * num_reads];
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), first_out_buffer, sizeof(first_out_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
uint8_t second_out_buffer[] = { 0x38, 0x00, 0x10, 0x30 };
|
||||
for(int i = 0; i < num_reads; i++) {
|
||||
second_out_buffer[1] = i * read_block_size;
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), second_out_buffer, sizeof(second_out_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = cypress_ctrl_bulk_in_transfer(handlers, get_cy_usb_info(device), in_buffer + (i * read_block_size), read_block_size, &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(transferred < read_block_size)
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_second_device_id(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint64_t &second_device_id) {
|
||||
const uint8_t first_out_buffer[] = { 0x60, 0x02, 0x30, 0xFF, 0x60, 0xD0, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xCB, 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF };
|
||||
uint8_t in_buffer[sizeof(uint64_t)];
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), first_out_buffer, sizeof(first_out_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t second_out_buffer[] = { 0x60, 0x02, 0x30, 0xFF, 0x60, 0xF1, 0x60, 0x01, 0x20, 0xFF, 0x61, 0x08, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0x60, 0x01, 0x01, 0xFF, 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), second_out_buffer, sizeof(second_out_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = cypress_ctrl_bulk_in_transfer(handlers, get_cy_usb_info(device), in_buffer, sizeof(in_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(transferred < sizeof(in_buffer))
|
||||
return -1;
|
||||
second_device_id = read_le64(in_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_device_id(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint64_t &device_id, bool &is_full_0s) {
|
||||
const uint8_t out_buffer[] = { 0x70 };
|
||||
uint8_t in_buffer[0x10];
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), out_buffer, sizeof(out_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = cypress_ctrl_bulk_in_transfer(handlers, get_cy_usb_info(device), in_buffer, sizeof(in_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(transferred < sizeof(in_buffer))
|
||||
return -1;
|
||||
device_id = read_le64(in_buffer);
|
||||
is_full_0s = true;
|
||||
for(int i = 0; i < sizeof(in_buffer); i++)
|
||||
if(in_buffer[i] != 0) {
|
||||
is_full_0s = false;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_first_unk_value(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint32_t &value) {
|
||||
const uint8_t out_buffer[] = { 0x60, 0x02, 0x30, 0xFF, 0x60, 0xC9, 0x60, 0x01, 0x20, 0xFF, 0x61, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0x60, 0x01, 0x01, 0xFF };
|
||||
uint8_t in_buffer[sizeof(uint32_t)];
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), out_buffer, sizeof(out_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = cypress_ctrl_bulk_in_transfer(handlers, get_cy_usb_info(device), in_buffer, sizeof(in_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(transferred < sizeof(in_buffer))
|
||||
return -1;
|
||||
value = read_le32(in_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dual_first_unk_value_setup_read(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint32_t &value32, uint64_t &device_id, uint64_t &second_device_id) {
|
||||
const uint8_t first_buffer[] = { 0x64, 0x60, 0x01, 0xFF, 0xFF, 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF };
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), first_buffer, sizeof(first_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = read_first_unk_value(handlers, device, value32);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = read_first_unk_value(handlers, device, value32);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
bool is_full_0s = false;
|
||||
ret = read_device_id(handlers, device, device_id, is_full_0s);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
if(is_full_0s)
|
||||
ret = read_second_device_id(handlers, device, second_device_id);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fpga_pl_load(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint8_t* fpga_pl, size_t fpga_pl_size) {
|
||||
const uint8_t first_buffer[] = { 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xCB, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xC5, 0x66, 0x64, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xC5 };
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), first_buffer, sizeof(first_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t second_buffer[] = { 0x60, 0x01, 0x20, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), second_buffer, sizeof(second_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t third_buffer[] = { 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), third_buffer, sizeof(third_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t fourth_buffer[] = { 0x60, 0x01, 0x01, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), fourth_buffer, sizeof(fourth_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t fifth_buffer[] = { 0x60, 0x02, 0x30, 0xFF, 0x60, 0xC5 };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), fifth_buffer, sizeof(fifth_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t sixth_buffer[] = { 0x60, 0x01, 0x20, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), sixth_buffer, sizeof(sixth_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
const int fpga_pl_transfer_total_size = 64;
|
||||
const int fpga_pl_transfer_header_size = 2;
|
||||
const int fpga_pl_transfer_piece_size = fpga_pl_transfer_total_size - fpga_pl_transfer_header_size;
|
||||
const size_t num_iters = (fpga_pl_size + fpga_pl_transfer_piece_size - 1) / fpga_pl_transfer_piece_size;
|
||||
uint8_t pl_buffer[fpga_pl_transfer_total_size];
|
||||
pl_buffer[0] = 0x60;
|
||||
pl_buffer[1] = 0x1F;
|
||||
for(size_t i = 0; i < num_iters; i++) {
|
||||
size_t remaining_size = fpga_pl_size - (fpga_pl_transfer_piece_size * i);
|
||||
if(remaining_size > fpga_pl_transfer_piece_size)
|
||||
remaining_size = fpga_pl_transfer_piece_size;
|
||||
memcpy(pl_buffer + fpga_pl_transfer_header_size, fpga_pl + (fpga_pl_transfer_piece_size * i), remaining_size);
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), pl_buffer, sizeof(pl_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
const uint8_t seventh_buffer[] = { 0x60, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00 };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), seventh_buffer, sizeof(seventh_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t eight_buffer[] = { 0x60, 0x01, 0x01, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), eight_buffer, sizeof(eight_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t ninth_buffer[] = { 0x60, 0x02, 0x30, 0xFF, 0x60, 0xD6, 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xFF, 0x60, 0x01, 0x20, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), ninth_buffer, sizeof(ninth_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t tenth_buffer[] = { 0x60, 0x01, 0x80, 0x00 };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), tenth_buffer, sizeof(tenth_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t eleventh_buffer[] = { 0x60, 0x01, 0x01, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), eleventh_buffer, sizeof(eleventh_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int insert_device_id(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, uint64_t device_id) {
|
||||
const uint8_t first_buffer[] = { 0x60, 0x02, 0x30, 0xFF, 0x60, 0xCC, 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xFF, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xFF };
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), first_buffer, sizeof(first_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
uint8_t device_id_buffer[] = {0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xC3, 0x00, 0x00, 0x02, 0x30, 0xFF, 0x60, 0x65 };
|
||||
write_le64(device_id_buffer + 1, device_id);
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), device_id_buffer, sizeof(device_id_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int final_capture_start_transfer(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device) {
|
||||
const uint8_t first_buffer[] = { 0x5B, 0x59, 0x03 };
|
||||
int transferred = 0;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), first_buffer, sizeof(first_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int capture_start(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, bool is_first_load, bool is_rgb888) {
|
||||
int transferred = 0;
|
||||
int ret = 0;
|
||||
uint32_t value32 = 0;
|
||||
uint64_t device_id = 0;
|
||||
uint64_t second_device_id = 0;
|
||||
if(is_first_load) {
|
||||
for(int i = 0; i < 3; i++) {
|
||||
cypress_pipe_reset_ctrl_bulk_in(handlers, get_cy_usb_info(device));
|
||||
cypress_pipe_reset_ctrl_bulk_out(handlers, get_cy_usb_info(device));
|
||||
}
|
||||
ret = dual_first_unk_value_setup_read(handlers, device, value32, device_id, second_device_id);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = read_device_info(handlers, device);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
cypress_pipe_reset_ctrl_bulk_in(handlers, get_cy_usb_info(device));
|
||||
cypress_pipe_reset_ctrl_bulk_out(handlers, get_cy_usb_info(device));
|
||||
ret = dual_first_unk_value_setup_read(handlers, device, value32, device_id, second_device_id);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
uint8_t* pl_to_load = device->fpga_pl_565;
|
||||
size_t pl_len = device->fpga_pl_565_size;
|
||||
if(is_rgb888) {
|
||||
pl_to_load = device->fpga_pl_888;
|
||||
pl_len = device->fpga_pl_888_size;
|
||||
}
|
||||
ret = fpga_pl_load(handlers, device, pl_to_load, pl_len);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
// No clue about the algorithm to determine this...
|
||||
// Would need different examples to understand it.
|
||||
device_id = 0;
|
||||
ret = insert_device_id(handlers, device, device_id);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = final_capture_start_transfer(handlers, device);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
cypress_pipe_reset_bulk_in(handlers, get_cy_usb_info(device));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int StartCaptureDma(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device, bool is_rgb888) {
|
||||
uint8_t mono_buffer[0x1];
|
||||
int transferred = 0;
|
||||
mono_buffer[0] = 0x40;
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), mono_buffer, sizeof(mono_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t second_buffer[] = { 0x64, 0x60, 0x02, 0x00, 0xFF, 0x00, 0xFF, 0x60, 0x02, 0x30, 0xFF, 0x60, 0xC2, 0x60, 0x01, 0x20, 0xFF };
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), second_buffer, sizeof(second_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
const uint8_t third_buffer_565[] = { 0x61, 0x07, 0x00, 0x0F, 0x00, 0x3E, 0x00, 0xF8, 0x00, 0x38, 0x00, 0x51, 0x80, 0x5C, 0x01, 0x00 };
|
||||
const uint8_t third_buffer_888[] = { 0x61, 0x07, 0x00, 0xA6, 0x00, 0x28, 0x00, 0x62, 0x00, 0x3A, 0x00, 0x51, 0x80, 0x5C, 0x01, 0x00 };
|
||||
const uint8_t* third_buffer = third_buffer_565;
|
||||
if(is_rgb888)
|
||||
third_buffer = third_buffer_888;
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), third_buffer, sizeof(third_buffer_565), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
uint8_t in_buffer[7];
|
||||
ret = cypress_ctrl_bulk_in_transfer(handlers, get_cy_usb_info(device), in_buffer, sizeof(in_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
mono_buffer[0] = 0x65;
|
||||
ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), mono_buffer, sizeof(mono_buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int capture_end(cy_device_device_handlers* handlers, const cyopn_device_usb_device* device) {
|
||||
int transferred = 0;
|
||||
uint8_t buffer[] = { 0x41 };
|
||||
int ret = cypress_ctrl_bulk_out_transfer(handlers, get_cy_usb_info(device), buffer, sizeof(buffer), &transferred);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
cypress_pipe_reset_ctrl_bulk_in(handlers, get_cy_usb_info(device));
|
||||
cypress_pipe_reset_ctrl_bulk_out(handlers, get_cy_usb_info(device));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ReadFrame(cy_device_device_handlers* handlers, uint8_t* buf, int length, const cyopn_device_usb_device* device_desc) {
|
||||
// Maybe making this async would be better for lower end hardware...
|
||||
int num_bytes = 0;
|
||||
int ret = cypress_bulk_in_transfer(handlers, get_cy_usb_info(device_desc), buf, length, &num_bytes);
|
||||
if(num_bytes != length)
|
||||
return LIBUSB_ERROR_INTERRUPTED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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) {
|
||||
return cypress_bulk_in_async(handlers, get_cy_usb_info(device_desc), buf, length, cb_data);
|
||||
}
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define OPTIMIZE_AUDIO_BUFFER_MAX_SIZE 0x200
|
||||
|
||||
#define INTERLEAVED_RGB565_PIXEL_NUM 4
|
||||
#define INTERLEAVED_RGB565_PIXEL_SIZE 2
|
||||
#define INTERLEAVED_RGB565_DATA_SIZE sizeof(uint16_t)
|
||||
@ -863,21 +861,21 @@ static USBNew3DSOptimizeHeaderSoundData* getAudioHeaderPtrNewOptimize3DS(Capture
|
||||
}
|
||||
|
||||
static inline uint16_t read_sample_indexLE(USBNew3DSOptimizeSingleSoundData* sample) {
|
||||
return sample->sample_index % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE;
|
||||
return sample->sample_index % OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE;
|
||||
}
|
||||
|
||||
static inline uint16_t read_sample_indexBE(USBNew3DSOptimizeSingleSoundData* sample) {
|
||||
return _reverse_endianness(sample->sample_index) % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE;
|
||||
return _reverse_endianness(sample->sample_index) % OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE;
|
||||
}
|
||||
|
||||
static inline void copyAudioFromSoundDataNewOptimize3DSLE(std::int16_t *p_out, uint16_t start, USBNew3DSOptimizeSingleSoundData* sample) {
|
||||
int32_t position = (read_sample_indexLE(sample) + OPTIMIZE_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE;
|
||||
int32_t position = (read_sample_indexLE(sample) + OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE;
|
||||
p_out[position * 2] = sample->sample_l;
|
||||
p_out[(position * 2) + 1] = sample->sample_r;
|
||||
}
|
||||
|
||||
static inline void copyAudioFromSoundDataNewOptimize3DSBE(std::int16_t *p_out, uint16_t start, USBNew3DSOptimizeSingleSoundData* sample) {
|
||||
int32_t position = (read_sample_indexBE(sample) + OPTIMIZE_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE;
|
||||
int32_t position = (read_sample_indexBE(sample) + OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE;
|
||||
p_out[position * 2] = _reverse_endianness(sample->sample_l);
|
||||
p_out[(position * 2) + 1] = _reverse_endianness(sample->sample_r);
|
||||
}
|
||||
@ -900,7 +898,7 @@ static void copyAudioNewOptimize3DSLE(std::int16_t *p_out, uint64_t &n_samples,
|
||||
}
|
||||
USBNew3DSOptimizeHeaderSoundData* last_column_data = getAudioHeaderPtrNewOptimize3DS(buffer, is_rgb888, is_data_3d, TOP_WIDTH_3DS - 1);
|
||||
last_buffer_index = read_sample_indexLE(&last_column_data->samples[1]);
|
||||
n_samples = ((last_buffer_index + 1 + OPTIMIZE_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE) * 2;
|
||||
n_samples = ((last_buffer_index + 1 + OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE) * 2;
|
||||
}
|
||||
|
||||
static void copyAudioNewOptimize3DSBE(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, CaptureReceived* buffer, bool is_rgb888, bool is_data_3d) {
|
||||
@ -921,7 +919,7 @@ static void copyAudioNewOptimize3DSBE(std::int16_t *p_out, uint64_t &n_samples,
|
||||
}
|
||||
USBNew3DSOptimizeHeaderSoundData* last_column_data = getAudioHeaderPtrNewOptimize3DS(buffer, is_rgb888, is_data_3d, TOP_WIDTH_3DS - 1);
|
||||
last_buffer_index = read_sample_indexBE(&last_column_data->samples[1]);
|
||||
n_samples = ((last_buffer_index + 1 + OPTIMIZE_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_AUDIO_BUFFER_MAX_SIZE) * 2;
|
||||
n_samples = ((last_buffer_index + 1 + OPTIMIZE_NEW_3DS_AUDIO_BUFFER_MAX_SIZE - start) % OPTIMIZE_NEW_3DS_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) {
|
||||
|
@ -121,6 +121,16 @@ uint32_t read_be32(const uint8_t* data, size_t count, size_t multiplier) {
|
||||
return data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24);
|
||||
}
|
||||
|
||||
uint64_t read_le64(const uint8_t* data, size_t count, size_t multiplier) {
|
||||
data += count * multiplier;
|
||||
return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24) | (((uint64_t)data[4]) << 32) | (((uint64_t)data[5]) << 40) | (((uint64_t)data[6]) << 48) | (((uint64_t)data[7]) << 56);
|
||||
}
|
||||
|
||||
uint64_t read_be64(const uint8_t* data, size_t count, size_t multiplier) {
|
||||
data += count * multiplier;
|
||||
return data[7] | (data[6] << 8) | (data[5] << 16) | (data[4] << 24) | (((uint64_t)data[3]) << 32) | (((uint64_t)data[2]) << 40) | (((uint64_t)data[1]) << 48) | (((uint64_t)data[0]) << 56);
|
||||
}
|
||||
|
||||
void write_le16(uint8_t* data, uint16_t value, size_t count, size_t multiplier) {
|
||||
data += count * multiplier;
|
||||
data[0] = value & 0xFF;
|
||||
@ -149,6 +159,30 @@ void write_be32(uint8_t* data, uint32_t value, size_t count, size_t multiplier)
|
||||
data[3] = value & 0xFF;
|
||||
}
|
||||
|
||||
void write_le64(uint8_t* data, uint64_t value, size_t count, size_t multiplier) {
|
||||
data += count * multiplier;
|
||||
data[0] = value & 0xFF;
|
||||
data[1] = (value >> 8) & 0xFF;
|
||||
data[2] = (value >> 16) & 0xFF;
|
||||
data[3] = (value >> 24) & 0xFF;
|
||||
data[4] = (value >> 32) & 0xFF;
|
||||
data[5] = (value >> 40) & 0xFF;
|
||||
data[6] = (value >> 48) & 0xFF;
|
||||
data[7] = (value >> 56) & 0xFF;
|
||||
}
|
||||
|
||||
void write_be64(uint8_t* data, uint64_t value, size_t count, size_t multiplier) {
|
||||
data += count * multiplier;
|
||||
data[0] = (value >> 56) & 0xFF;
|
||||
data[1] = (value >> 48) & 0xFF;
|
||||
data[2] = (value >> 40) & 0xFF;
|
||||
data[3] = (value >> 32) & 0xFF;
|
||||
data[4] = (value >> 24) & 0xFF;
|
||||
data[5] = (value >> 16) & 0xFF;
|
||||
data[6] = (value >> 8) & 0xFF;
|
||||
data[7] = value & 0xFF;
|
||||
}
|
||||
|
||||
void write_string(uint8_t* data, std::string text) {
|
||||
for(int i = 0; i < text.size(); i++)
|
||||
data[i] = (uint8_t)text[i];
|
||||
|
Loading…
Reference in New Issue
Block a user