From 72110aba942e1de56b0103672a7cb793192d4812 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Wed, 26 Mar 2025 00:43:29 +0100 Subject: [PATCH] Add information to the data passed about 3D to account for 2D only games --- .../3dscapture_ftd3_shared.hpp | 1 + .../3dscapture_ftd3_shared_general.hpp | 2 +- .../usb_ds_3ds_capture.hpp | 1 + include/capture_structs.hpp | 9 +++-- include/conversions.hpp | 4 +- include/devicecapture.hpp | 4 +- source/CaptureDataBuffers.cpp | 15 ++++---- .../3dscapture_ftd3_driver_acquisition.cpp | 16 +++++--- .../3dscapture_ftd3_libusb_acquisition.cpp | 14 ++++--- .../3dscapture_ftd3_shared.cpp | 38 ++++++++++++------- .../usb_ds_3ds_capture.cpp | 4 ++ source/cc3dsfs.cpp | 10 ++--- source/conversions.cpp | 26 +++++++++---- source/devicecapture.cpp | 10 ++--- 14 files changed, 94 insertions(+), 60 deletions(-) diff --git a/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.hpp b/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.hpp index 22ca41a..92f1ce3 100644 --- a/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.hpp +++ b/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.hpp @@ -13,5 +13,6 @@ bool connect_ftd3(bool print_failed, CaptureData* capture_data, CaptureDevice* d void ftd3_capture_main_loop(CaptureData* capture_data); void ftd3_capture_cleanup(CaptureData* capture_data); uint64_t ftd3_get_video_in_size(CaptureData* capture_data); +uint64_t ftd3_get_video_in_size(CaptureData* capture_data, bool override_3d); #endif diff --git a/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared_general.hpp b/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared_general.hpp index d782ad6..e874751 100644 --- a/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared_general.hpp +++ b/include/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared_general.hpp @@ -9,7 +9,7 @@ uint64_t ftd3_get_capture_size(bool is_3d_enabled); uint64_t ftd3_get_capture_size(CaptureData* capture_data); std::string ftd3_get_serial(std::string serial_string, int &curr_serial_extra_id); void ftd3_insert_device(std::vector &devices_list, std::string serial_string, int &curr_serial_extra_id, uint32_t usb_speed, bool is_driver); -void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point &base_time); +void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point &base_time, bool is_3d); bool ftd3_capture_3d_setup(CaptureData* capture_data, bool first_pass, bool& stored_3d_status); #endif diff --git a/include/CaptureDeviceSpecific/usb_ds_3ds_capture.hpp b/include/CaptureDeviceSpecific/usb_ds_3ds_capture.hpp index 04155f1..68b1ded 100644 --- a/include/CaptureDeviceSpecific/usb_ds_3ds_capture.hpp +++ b/include/CaptureDeviceSpecific/usb_ds_3ds_capture.hpp @@ -15,6 +15,7 @@ bool connect_usb(bool print_failed, CaptureData* capture_data, CaptureDevice* de void usb_capture_main_loop(CaptureData* capture_data); void usb_capture_cleanup(CaptureData* capture_data); uint64_t usb_get_video_in_size(CaptureData* capture_data); +uint64_t usb_get_video_in_size(CaptureData* capture_data, bool override_3d); void usb_ds_3ds_init(); void usb_ds_3ds_close(); diff --git a/include/capture_structs.hpp b/include/capture_structs.hpp index bef6e64..5325091 100755 --- a/include/capture_structs.hpp +++ b/include/capture_structs.hpp @@ -231,6 +231,7 @@ struct CaptureDataSingleBuffer { CaptureReceived capture_buf; double time_in_buf; uint32_t inner_index; + bool is_3d; }; class CaptureDataBuffers { @@ -238,10 +239,10 @@ public: CaptureDataBuffers(); CaptureDataSingleBuffer* GetReaderBuffer(CaptureReaderType reader_type); void ReleaseReaderBuffer(CaptureReaderType reader_type); - void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index); - void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index); - void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index); - void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index); + void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index, bool is_3d = false); + void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index, bool is_3d = false); + void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index, bool is_3d = false); + void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index, bool is_3d = false); CaptureDataSingleBuffer* GetWriterBuffer(int index = 0); void ReleaseWriterBuffer(int index = 0, bool update_last_curr_in = true); private: diff --git a/include/conversions.hpp b/include/conversions.hpp index 88bb531..07d4369 100755 --- a/include/conversions.hpp +++ b/include/conversions.hpp @@ -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 convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status); +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, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool is_data_3d); #endif diff --git a/include/devicecapture.hpp b/include/devicecapture.hpp index 88510dc..e4e81ae 100755 --- a/include/devicecapture.hpp +++ b/include/devicecapture.hpp @@ -21,8 +21,8 @@ bool connect(bool print_failed, CaptureData* capture_data, FrontendData* fronten 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, uint64_t read); -uint64_t get_video_in_size(CaptureData* capture_data); +uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read, bool is_3d); +uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d); 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); diff --git a/source/CaptureDataBuffers.cpp b/source/CaptureDataBuffers.cpp index d8550c1..42303fb 100644 --- a/source/CaptureDataBuffers.cpp +++ b/source/CaptureDataBuffers.cpp @@ -95,7 +95,7 @@ void CaptureDataBuffers::ReleaseWriterBuffer(int index, bool update_last_curr_in access_mutex.unlock(); } -void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index) { +void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index, bool is_3d) { if(offset >= read) return; if(!is_writer_index_valid(index)) @@ -116,17 +116,18 @@ void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, d target->read = read - offset; target->time_in_buf = time_in_buf; target->capture_type = capture_type; + target->is_3d = is_3d; this->ReleaseWriterBuffer(index); } -void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index) { - return this->WriteToBuffer(buffer, read, time_in_buf, device, capture_type, 0, index); +void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index, bool is_3d) { + return this->WriteToBuffer(buffer, read, time_in_buf, device, capture_type, 0, index, is_3d); } -void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index) { - return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, offset, index); +void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index, bool is_3d) { + return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, offset, index, is_3d); } -void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index) { - return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, 0, index); +void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index, bool is_3d) { + return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, 0, index, is_3d); } diff --git a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_driver_acquisition.cpp b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_driver_acquisition.cpp index d9afe69..802b22f 100644 --- a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_driver_acquisition.cpp +++ b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_driver_acquisition.cpp @@ -19,6 +19,7 @@ struct FTD3XXReceivedDataBuffer { OVERLAPPED overlap; ULONG read_buffer; + bool is_3d; }; static bool wait_all_fast_capture_call_async_transfers(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data) { @@ -38,7 +39,8 @@ static bool fast_capture_call_init_async_transfers(FTD3XXReceivedDataBuffer* rec for(inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS - 1; ++inner_curr_in) { CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(inner_curr_in); uint8_t* buffer = (uint8_t*)&data_buf->capture_buf; - FT_STATUS ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap); + received_buffer[inner_curr_in].is_3d = could_use_3d && stored_3d_status; + FT_STATUS ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(received_buffer[inner_curr_in].is_3d), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap); if(ftStatus != FT_IO_PENDING) { capture_error_print(true, capture_data, "Disconnected: Read failed"); return false; @@ -90,7 +92,8 @@ static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(inner_curr_in); uint8_t* buffer = (uint8_t*)&data_buf->capture_buf; - ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap); + received_buffer[inner_curr_in].is_3d = could_use_3d && stored_3d_status; + ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(received_buffer[inner_curr_in].is_3d), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap); if(ftStatus != FT_IO_PENDING) { capture_error_print(true, capture_data, "Disconnected: Read failed"); return; @@ -104,7 +107,7 @@ static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture return; } - data_output_update(inner_curr_in, received_buffer[inner_curr_in].read_buffer, capture_data, clock_start); + data_output_update(inner_curr_in, received_buffer[inner_curr_in].read_buffer, capture_data, clock_start, received_buffer[inner_curr_in].is_3d); } } @@ -126,17 +129,18 @@ static bool safe_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(0); uint8_t* buffer = (uint8_t*)&data_buf->capture_buf; + received_buffer->is_3d = could_use_3d && stored_3d_status; #ifdef _WIN32 - FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer->read_buffer, NULL); + FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(received_buffer->is_3d), &received_buffer->read_buffer, NULL); #else - FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer->read_buffer, 1000); + FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(received_buffer->is_3d), &received_buffer->read_buffer, 1000); #endif if(FT_FAILED(ftStatus)) { capture_error_print(true, capture_data, "Disconnected: Read failed"); return true; } - data_output_update(0, received_buffer->read_buffer, capture_data, clock_start); + data_output_update(0, received_buffer->read_buffer, capture_data, clock_start, received_buffer->is_3d); } return false; diff --git a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_acquisition.cpp b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_acquisition.cpp index b258018..b60ac95 100644 --- a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_acquisition.cpp +++ b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_libusb_acquisition.cpp @@ -27,6 +27,7 @@ struct FTD3LibusbCaptureReceivedData { int internal_index; CaptureData* capture_data; uint32_t* last_index; + bool is_3d; std::chrono::time_point *clock_start; SharedConsumerMutex *is_buffer_free_shared_mutex; int* status; @@ -72,7 +73,7 @@ static void reset_ftd3_libusb_status(FTD3LibusbCaptureReceivedData* ftd3_libusb_ error_ftd3_libusb_status(ftd3_libusb_capture_recv_data, 0); } -static void ftd3_libusb_read_frame_request(CaptureData* capture_data, FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data, uint32_t index, int pipe) { +static void ftd3_libusb_read_frame_request(CaptureData* capture_data, FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data, uint32_t index, int pipe, bool is_3d) { if(ftd3_libusb_capture_recv_data == NULL) return; if((*ftd3_libusb_capture_recv_data->status) < 0) @@ -81,7 +82,8 @@ static void ftd3_libusb_read_frame_request(CaptureData* capture_data, FTD3Libusb ftd3_libusb_capture_recv_data->cb_data.function = ftd3_libusb_read_frame_cb; CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(ftd3_libusb_capture_recv_data->internal_index); uint8_t* buffer = (uint8_t*)&data_buf->capture_buf; - ftd3_libusb_async_in_start((ftd3_device_device_handlers*)capture_data->handle, pipe, MAX_TIME_WAIT * 1000, buffer, ftd3_get_capture_size(capture_data), &ftd3_libusb_capture_recv_data->cb_data); + ftd3_libusb_capture_recv_data->is_3d = is_3d; + ftd3_libusb_async_in_start((ftd3_device_device_handlers*)capture_data->handle, pipe, MAX_TIME_WAIT * 1000, buffer, ftd3_get_capture_size(is_3d), &ftd3_libusb_capture_recv_data->cb_data); } static void end_ftd3_libusb_read_frame_cb(FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data, bool early_release) { @@ -109,7 +111,7 @@ static void ftd3_libusb_read_frame_cb(void* user_data, int transfer_length, int if(*ftd3_libusb_capture_recv_data->pause_output) return end_ftd3_libusb_read_frame_cb(ftd3_libusb_capture_recv_data, true); - data_output_update(ftd3_libusb_capture_recv_data->internal_index, transfer_length, ftd3_libusb_capture_recv_data->capture_data, *ftd3_libusb_capture_recv_data->clock_start); + data_output_update(ftd3_libusb_capture_recv_data->internal_index, transfer_length, ftd3_libusb_capture_recv_data->capture_data, *ftd3_libusb_capture_recv_data->clock_start, ftd3_libusb_capture_recv_data->is_3d); end_ftd3_libusb_read_frame_cb(ftd3_libusb_capture_recv_data, false); } @@ -204,7 +206,7 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa return; for(int i = 0; i < FTD3_CONCURRENT_BUFFERS; i++) - ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe); + ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe, could_use_3d && stored_3d_status); while(capture_data->status.connected && capture_data->status.running) { if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) { @@ -221,7 +223,7 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa *ftd3_libusb_capture_recv_data->pause_output = false; for(int i = 0; i < FTD3_CONCURRENT_BUFFERS; i++) - ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe); + ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe, could_use_3d && stored_3d_status); *ftd3_libusb_capture_recv_data[0].clock_start = std::chrono::high_resolution_clock::now(); } @@ -230,7 +232,7 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa return; } FTD3LibusbCaptureReceivedData* free_buffer = ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data); - ftd3_libusb_read_frame_request(capture_data, free_buffer, index++, pipe); + ftd3_libusb_read_frame_request(capture_data, free_buffer, index++, pipe, could_use_3d && stored_3d_status); } } diff --git a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.cpp b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.cpp index a3f2958..28b9960 100644 --- a/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.cpp +++ b/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_shared.cpp @@ -35,23 +35,18 @@ void list_devices_ftd3(std::vector &devices_list, std::vector &base_time) { - const auto curr_time = std::chrono::high_resolution_clock::now(); - const std::chrono::duration diff = curr_time - base_time; - base_time = curr_time; - capture_data->data_buffers.WriteToBuffer(NULL, read_data, diff.count(), &capture_data->status.device, inner_index); - - if(capture_data->status.cooldown_curr_in) - capture_data->status.cooldown_curr_in = capture_data->status.cooldown_curr_in - 1; - // Signal that there is data available - capture_data->status.video_wait.unlock(); - capture_data->status.audio_wait.unlock(); +static uint64_t ftd3_get_video_in_size(bool is_3d_enabled) { + if(!is_3d_enabled) + return sizeof(RGB83DSVideoInputData); + return sizeof(RGB83DSVideoInputData_3D); } uint64_t ftd3_get_video_in_size(CaptureData* capture_data) { - if(!get_3d_enabled(&capture_data->status)) - return sizeof(RGB83DSVideoInputData); - return sizeof(RGB83DSVideoInputData_3D); + return ftd3_get_video_in_size(get_3d_enabled(&capture_data->status)); +} + +uint64_t ftd3_get_video_in_size(CaptureData* capture_data, bool override_3d) { + return ftd3_get_video_in_size(override_3d); } uint64_t ftd3_get_capture_size(bool is_3d_enabled) { @@ -64,6 +59,21 @@ uint64_t ftd3_get_capture_size(CaptureData* capture_data) { return ftd3_get_capture_size(get_3d_enabled(&capture_data->status)); } +void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point &base_time, bool is_3d) { + if(is_3d && (read_data < ftd3_get_video_in_size(is_3d)) && (read_data >= ftd3_get_video_in_size(false))) + is_3d = false; + const auto curr_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration diff = curr_time - base_time; + base_time = curr_time; + capture_data->data_buffers.WriteToBuffer(NULL, read_data, diff.count(), &capture_data->status.device, inner_index, is_3d); + + if(capture_data->status.cooldown_curr_in) + capture_data->status.cooldown_curr_in = capture_data->status.cooldown_curr_in - 1; + // Signal that there is data available + capture_data->status.video_wait.unlock(); + capture_data->status.audio_wait.unlock(); +} + static void preemptive_close_connection(CaptureData* capture_data) { ftd3_device_device_handlers* handlers = (ftd3_device_device_handlers*)capture_data->handle; ftd3_abort_pipe_compat(handlers, BULK_IN); diff --git a/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp b/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp index 97f78fb..06238b7 100644 --- a/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp +++ b/source/CaptureDeviceSpecific/usb_ds_3ds_capture.cpp @@ -395,6 +395,10 @@ uint64_t usb_get_video_in_size(CaptureData* capture_data) { return _usb_get_video_in_size(get_usb_device_desc(capture_data), get_3d_enabled(&capture_data->status)); } +uint64_t usb_get_video_in_size(CaptureData* capture_data, bool override_3d) { + return _usb_get_video_in_size(get_usb_device_desc(capture_data), override_3d); +} + void usb_capture_main_loop(CaptureData* capture_data) { if(!usb_is_initialized()) return; diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index 6cb14f1..2633cea 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -419,10 +419,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)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) { - uint64_t n_samples = get_audio_n_samples(capture_data, data_buffer->read); + if((data_buffer->read > get_video_in_size(capture_data, data_buffer->is_3d)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) { + uint64_t n_samples = get_audio_n_samples(capture_data, data_buffer->read, data_buffer->is_3d); double out_time = data_buffer->time_in_buf; - bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, endianness, data_buffer, &capture_data->status); + bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, endianness, data_buffer, &capture_data->status, data_buffer->is_3d); if(!conversion_success) audio_data->signal_conversion_error(); audio.samples.emplace(out_buf[audio_buf_counter], n_samples, out_time); @@ -602,11 +602,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)) { + if(data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d)) { 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); + bool conversion_success = convertVideoToOutput(out_buf, endianness, data_buffer, &capture_data->status, frontend_data.display_data.interleaved_3d, data_buffer->is_3d); if(!conversion_success) UpdateOutText(out_text_data, "", "Video conversion failed...", TEXT_KIND_NORMAL); } diff --git a/source/conversions.cpp b/source/conversions.cpp index 16e07af..9aaccba 100755 --- a/source/conversions.cpp +++ b/source/conversions.cpp @@ -59,7 +59,7 @@ static inline void convertVideoToOutputChunk_3D(RGB83DSVideoInputData_3D *p_in, memcpy(&p_out->screen_data[start_out], &p_in->screen_data[start_in], iters * 3); } -static void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d, bool interleaved_3d) { +static void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d, bool interleaved_3d, bool requested_3d) { if(!enabled_3d) { convertVideoToOutputChunk(&p_in->ftd3_received.video_in, p_out, IN_VIDEO_NO_BOTTOM_SIZE_3DS, 0, BOT_SIZE_3DS); @@ -67,6 +67,15 @@ static void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_ convertVideoToOutputChunk(&p_in->ftd3_received.video_in, p_out, IN_VIDEO_WIDTH_3DS, (((i * 2) + 0) * IN_VIDEO_WIDTH_3DS) + IN_VIDEO_NO_BOTTOM_SIZE_3DS, i * IN_VIDEO_WIDTH_3DS); convertVideoToOutputChunk(&p_in->ftd3_received.video_in, p_out, IN_VIDEO_WIDTH_3DS, (((i * 2) + 1) * IN_VIDEO_WIDTH_3DS) + IN_VIDEO_NO_BOTTOM_SIZE_3DS, BOT_SIZE_3DS + IN_VIDEO_NO_BOTTOM_SIZE_3DS + (i * IN_VIDEO_WIDTH_3DS)); } + if(requested_3d && interleaved_3d) { + for(int i = TOP_WIDTH_3DS - 1; i >= 0; i--) { + memcpy(&p_out->screen_data[BOT_SIZE_3DS + (((2 * i) + 1) * HEIGHT_3DS)], &p_out->screen_data[BOT_SIZE_3DS + (i * HEIGHT_3DS)], HEIGHT_3DS * 3); + memcpy(&p_out->screen_data[BOT_SIZE_3DS + ((2 * i) * HEIGHT_3DS)], &p_out->screen_data[BOT_SIZE_3DS + (i * HEIGHT_3DS)], HEIGHT_3DS * 3); + } + } + else if(requested_3d) { + memcpy(&p_out->screen_data[BOT_SIZE_3DS + TOP_SIZE_3DS], &p_out->screen_data[BOT_SIZE_3DS], TOP_SIZE_3DS * 3); + } } else { size_t last_line_index = ((IN_VIDEO_SIZE_3DS_3D - IN_VIDEO_NO_BOTTOM_SIZE_3DS_3D) / (IN_VIDEO_WIDTH_3DS_3D * 3)) - 1; @@ -206,7 +215,7 @@ static void usb_3DSconvertVideoToOutput(USB3DSCaptureReceived *p_in, VideoOutput memcpy(p_out->screen_data, p_in->video_in.screen_data, IN_VIDEO_HEIGHT_3DS * IN_VIDEO_WIDTH_3DS * 3); } -static void usb_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, CaptureDevice* capture_device, bool enabled_3d, const bool is_big_endian, bool interleaved_3d) { +static void usb_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, CaptureDevice* capture_device, bool enabled_3d, const bool is_big_endian, bool interleaved_3d, bool requested_3d) { if(capture_device->is_3ds) { if(!enabled_3d) usb_3DSconvertVideoToOutput(&p_in->usb_received_3ds, p_out); @@ -288,13 +297,14 @@ 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 convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d, bool is_data_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_3d_requested = get_3d_enabled(status); #ifdef USE_FTD3 if(chosen_device->cc_type == CAPTURE_CONN_FTD3) { - ftd3_convertVideoToOutput(p_in, p_out, get_3d_enabled(status), interleaved_3d); + ftd3_convertVideoToOutput(p_in, p_out, is_data_3d, interleaved_3d, is_3d_requested); converted = true; } #endif @@ -306,7 +316,7 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt #endif #ifdef USE_DS_3DS_USB if(chosen_device->cc_type == CAPTURE_CONN_USB) { - usb_convertVideoToOutput(p_in, p_out, chosen_device, get_3d_enabled(status), is_big_endian, interleaved_3d); + usb_convertVideoToOutput(p_in, p_out, chosen_device, is_data_3d, is_big_endian, interleaved_3d, is_3d_requested); converted = true; } #endif @@ -325,14 +335,14 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt return converted; } -bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status) { +bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool is_data_3d) { if(!status->device.has_audio) return true; CaptureReceived* p_in = (CaptureReceived*)(((uint8_t*)&data_buffer->capture_buf) + data_buffer->unused_offset); uint8_t* base_ptr = NULL; #ifdef USE_FTD3 if(status->device.cc_type == CAPTURE_CONN_FTD3) { - if(!get_3d_enabled(status)) + if(!is_data_3d) base_ptr = (uint8_t*)p_in->ftd3_received.audio_data; else base_ptr = (uint8_t*)p_in->ftd3_received_3d.audio_data; @@ -344,7 +354,7 @@ bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool i #endif #ifdef USE_DS_3DS_USB if(status->device.cc_type == CAPTURE_CONN_USB) { - if(!get_3d_enabled(status)) + if(!is_data_3d) base_ptr = (uint8_t*)p_in->usb_received_3ds.audio_data; else base_ptr = (uint8_t*)p_in->usb_received_3ds_3d.audio_data; diff --git a/source/devicecapture.cpp b/source/devicecapture.cpp index 1533a8d..6f2f631 100755 --- a/source/devicecapture.cpp +++ b/source/devicecapture.cpp @@ -222,10 +222,10 @@ void captureCall(CaptureData* capture_data) { } } -uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read) { +uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read, bool is_3d) { if(!capture_data->status.device.has_audio) return 0; - uint64_t n_samples = (read - get_video_in_size(capture_data)) / 2; + uint64_t n_samples = (read - get_video_in_size(capture_data, is_3d)) / 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 @@ -234,14 +234,14 @@ uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read) { return n_samples; } -uint64_t get_video_in_size(CaptureData* capture_data) { +uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d) { #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_FTD3 if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD3) - return ftd3_get_video_in_size(capture_data); + return ftd3_get_video_in_size(capture_data, is_3d); #endif #ifdef USE_FTD2 if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD2) @@ -249,7 +249,7 @@ uint64_t get_video_in_size(CaptureData* capture_data) { #endif #ifdef USE_DS_3DS_USB if(capture_data->status.device.cc_type == CAPTURE_CONN_USB) - return usb_get_video_in_size(capture_data); + return usb_get_video_in_size(capture_data, is_3d); #endif #ifdef USE_IS_DEVICES_USB if(capture_data->status.device.cc_type == CAPTURE_CONN_IS_NITRO)