mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2026-09-08 16:45:17 -05:00
Add N3DS XL Loopy 3D Mode
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:
@@ -21,9 +21,44 @@ struct FTD3XXReceivedDataBuffer {
|
||||
ULONG read_buffer;
|
||||
};
|
||||
|
||||
static bool wait_all_fast_capture_call_async_transfers(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data) {
|
||||
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
|
||||
for(int inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS; ++inner_curr_in) {
|
||||
FT_STATUS ftStatus = FT_GetOverlappedResult(handle, &received_buffer[inner_curr_in].overlap, &received_buffer[inner_curr_in].read_buffer, true);
|
||||
if(FT_FAILED(ftStatus)) {
|
||||
capture_error_print(true, capture_data, "Disconnected: USB error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fast_capture_call_init_async_transfers(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data, int fifo_channel, int &inner_curr_in, bool could_use_3d, bool stored_3d_status) {
|
||||
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
|
||||
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);
|
||||
if(ftStatus != FT_IO_PENDING) {
|
||||
capture_error_print(true, capture_data, "Disconnected: Read failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inner_curr_in = FTD3_CONCURRENT_BUFFERS - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data, int fifo_channel) {
|
||||
int inner_curr_in = 0;
|
||||
FT_STATUS ftStatus;
|
||||
|
||||
bool could_use_3d = get_3d_enabled(&capture_data->status, true);
|
||||
bool stored_3d_status = true;
|
||||
bool result_3d_setup = ftd3_capture_3d_setup(capture_data, true, stored_3d_status);
|
||||
if(!result_3d_setup)
|
||||
return;
|
||||
|
||||
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
|
||||
for (inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS; ++inner_curr_in) {
|
||||
ftStatus = FT_InitializeOverlapped(handle, &received_buffer[inner_curr_in].overlap);
|
||||
@@ -33,24 +68,29 @@ static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(capture_data), &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;
|
||||
}
|
||||
}
|
||||
|
||||
inner_curr_in = FTD3_CONCURRENT_BUFFERS - 1;
|
||||
if(!fast_capture_call_init_async_transfers(received_buffer, capture_data, fifo_channel, inner_curr_in, could_use_3d, stored_3d_status))
|
||||
return;
|
||||
|
||||
auto clock_start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while (capture_data->status.connected && capture_data->status.running) {
|
||||
if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) {
|
||||
if(!wait_all_fast_capture_call_async_transfers(received_buffer, capture_data))
|
||||
return;
|
||||
|
||||
result_3d_setup = ftd3_capture_3d_setup(capture_data, false, stored_3d_status);
|
||||
if(!result_3d_setup)
|
||||
return;
|
||||
|
||||
if(!fast_capture_call_init_async_transfers(received_buffer, capture_data, fifo_channel, inner_curr_in, could_use_3d, stored_3d_status))
|
||||
return;
|
||||
|
||||
clock_start = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
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(capture_data), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap);
|
||||
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);
|
||||
if(ftStatus != FT_IO_PENDING) {
|
||||
capture_error_print(true, capture_data, "Disconnected: Read failed");
|
||||
return;
|
||||
@@ -71,15 +111,25 @@ static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture
|
||||
static bool safe_capture_call(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data, int fifo_channel) {
|
||||
auto clock_start = std::chrono::high_resolution_clock::now();
|
||||
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
|
||||
bool could_use_3d = get_3d_enabled(&capture_data->status, true);
|
||||
bool stored_3d_status = true;
|
||||
bool result_3d_setup = ftd3_capture_3d_setup(capture_data, true, stored_3d_status);
|
||||
if(!result_3d_setup)
|
||||
return true;
|
||||
|
||||
while(capture_data->status.connected && capture_data->status.running) {
|
||||
if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) {
|
||||
result_3d_setup = ftd3_capture_3d_setup(capture_data, false, stored_3d_status);
|
||||
if(!result_3d_setup)
|
||||
return true;
|
||||
}
|
||||
|
||||
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(0);
|
||||
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
|
||||
#ifdef _WIN32
|
||||
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(capture_data), &received_buffer->read_buffer, NULL);
|
||||
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer->read_buffer, NULL);
|
||||
#else
|
||||
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(capture_data), &received_buffer->read_buffer, 1000);
|
||||
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer->read_buffer, 1000);
|
||||
#endif
|
||||
if(FT_FAILED(ftStatus)) {
|
||||
capture_error_print(true, capture_data, "Disconnected: Read failed");
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
struct FTD3LibusbCaptureReceivedData {
|
||||
bool in_use;
|
||||
bool* pause_output;
|
||||
uint32_t index;
|
||||
int internal_index;
|
||||
CaptureData* capture_data;
|
||||
@@ -105,6 +106,9 @@ static void ftd3_libusb_read_frame_cb(void* user_data, int transfer_length, int
|
||||
}
|
||||
*ftd3_libusb_capture_recv_data->last_index = ftd3_libusb_capture_recv_data->index;
|
||||
|
||||
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);
|
||||
end_ftd3_libusb_read_frame_cb(ftd3_libusb_capture_recv_data, false);
|
||||
}
|
||||
@@ -193,10 +197,34 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa
|
||||
int index = 0;
|
||||
CaptureData* capture_data = ftd3_libusb_capture_recv_data[0].capture_data;
|
||||
|
||||
bool could_use_3d = get_3d_enabled(&capture_data->status, true);
|
||||
bool stored_3d_status = true;
|
||||
bool result_3d_setup = ftd3_capture_3d_setup(capture_data, true, stored_3d_status);
|
||||
if(!result_3d_setup)
|
||||
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);
|
||||
|
||||
while(capture_data->status.connected && capture_data->status.running) {
|
||||
if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) {
|
||||
*ftd3_libusb_capture_recv_data->pause_output = true;
|
||||
wait_all_ftd3_libusb_buffers_free(ftd3_libusb_capture_recv_data);
|
||||
if(get_ftd3_libusb_status(ftd3_libusb_capture_recv_data) < 0) {
|
||||
capture_error_print(true, capture_data, "Disconnected: Read failed");
|
||||
return;
|
||||
}
|
||||
|
||||
result_3d_setup = ftd3_capture_3d_setup(capture_data, false, stored_3d_status);
|
||||
if(!result_3d_setup)
|
||||
return;
|
||||
|
||||
*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_capture_recv_data[0].clock_start = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
if(get_ftd3_libusb_status(ftd3_libusb_capture_recv_data) < 0) {
|
||||
capture_error_print(true, capture_data, "Disconnected: Read failed");
|
||||
return;
|
||||
@@ -214,12 +242,14 @@ void ftd3_libusb_capture_main_loop(CaptureData* capture_data, int pipe) {
|
||||
|
||||
uint32_t last_index = -1;
|
||||
int status = 0;
|
||||
bool pause_output = false;
|
||||
SharedConsumerMutex is_buffer_free_shared_mutex(FTD3_CONCURRENT_BUFFERS);
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> clock_start = std::chrono::high_resolution_clock::now();
|
||||
FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data = new FTD3LibusbCaptureReceivedData[FTD3_CONCURRENT_BUFFERS];
|
||||
for(int i = 0; i < FTD3_CONCURRENT_BUFFERS; i++) {
|
||||
ftd3_libusb_capture_recv_data[i].in_use = false;
|
||||
ftd3_libusb_capture_recv_data[i].index = i;
|
||||
ftd3_libusb_capture_recv_data[i].pause_output = &pause_output;
|
||||
ftd3_libusb_capture_recv_data[i].internal_index = i;
|
||||
ftd3_libusb_capture_recv_data[i].capture_data = capture_data;
|
||||
ftd3_libusb_capture_recv_data[i].last_index = &last_index;
|
||||
|
||||
@@ -54,14 +54,14 @@ uint64_t ftd3_get_video_in_size(CaptureData* capture_data) {
|
||||
return sizeof(RGB83DSVideoInputData_3D);
|
||||
}
|
||||
|
||||
static uint64_t ftd3_get_capture_size(CaptureStatus* capture_status) {
|
||||
if(!get_3d_enabled(capture_status))
|
||||
uint64_t ftd3_get_capture_size(bool is_3d_enabled) {
|
||||
if(!is_3d_enabled)
|
||||
return sizeof(FTD3_3DSCaptureReceived) & (~(EXTRA_DATA_BUFFER_FTD3XX_SIZE - 1));
|
||||
return sizeof(FTD3_3DSCaptureReceived_3D) & (~(EXTRA_DATA_BUFFER_FTD3XX_SIZE - 1));
|
||||
}
|
||||
|
||||
uint64_t ftd3_get_capture_size(CaptureData* capture_data) {
|
||||
return ftd3_get_capture_size(&capture_data->status);
|
||||
return ftd3_get_capture_size(get_3d_enabled(&capture_data->status));
|
||||
}
|
||||
|
||||
static void preemptive_close_connection(CaptureData* capture_data) {
|
||||
@@ -180,8 +180,6 @@ bool connect_ftd3(bool print_failed, CaptureData* capture_data, CaptureDevice* d
|
||||
capture_error_print(print_failed, capture_data, "Second Create failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
ftd3_device_device_handlers* handlers = (ftd3_device_device_handlers*)capture_data->handle;
|
||||
|
||||
if(!reset_3ds_state(print_failed, capture_data))
|
||||
return false;
|
||||
@@ -201,19 +199,47 @@ bool connect_ftd3(bool print_failed, CaptureData* capture_data, CaptureDevice* d
|
||||
if(!read_3ds_config_3d(print_failed, capture_data, device))
|
||||
return false;
|
||||
|
||||
CaptureStatus tmp_status;
|
||||
tmp_status.device = *device;
|
||||
tmp_status.connected = true;
|
||||
tmp_status.requested_3d = capture_data->status.requested_3d;
|
||||
if(!get_3d_enabled(&tmp_status)) {
|
||||
if(!set_3ds_state(print_failed, capture_data, 0x42))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ftd3_capture_3d_setup(CaptureData* capture_data, bool first_pass, bool& stored_3d_status) {
|
||||
CaptureStatus tmp_status;
|
||||
tmp_status.device = capture_data->status.device;
|
||||
tmp_status.connected = capture_data->status.connected;
|
||||
tmp_status.requested_3d = capture_data->status.requested_3d;
|
||||
|
||||
if(first_pass)
|
||||
stored_3d_status = true;
|
||||
|
||||
if((!first_pass) && ((stored_3d_status == tmp_status.requested_3d) || (!get_3d_enabled(&tmp_status, true)))) {
|
||||
stored_3d_status = tmp_status.requested_3d;
|
||||
return true;
|
||||
}
|
||||
|
||||
ftd3_device_device_handlers* handlers = (ftd3_device_device_handlers*)capture_data->handle;
|
||||
bool print_failed = true;
|
||||
|
||||
if(!first_pass) {
|
||||
if(ftd3_is_error_compat(handlers, ftd3_abort_pipe_compat(handlers, BULK_IN))) {
|
||||
capture_error_print(print_failed, capture_data, "Abort failed");
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool _3d_enabled_result = get_3d_enabled(&tmp_status);
|
||||
bool update_state = stored_3d_status != _3d_enabled_result;
|
||||
if(update_state) {
|
||||
int state_to_set = 0x42;
|
||||
if(_3d_enabled_result)
|
||||
state_to_set = 0x43;
|
||||
if(!set_3ds_state(print_failed, capture_data, state_to_set))
|
||||
return false;
|
||||
if(!set_3ds_state(print_failed, capture_data, 0x40))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ftd3_is_error_compat(handlers, ftd3_set_stream_pipe_compat(handlers, BULK_IN, ftd3_get_capture_size(&tmp_status)))) {
|
||||
if(ftd3_is_error_compat(handlers, ftd3_set_stream_pipe_compat(handlers, BULK_IN, ftd3_get_capture_size(_3d_enabled_result)))) {
|
||||
capture_error_print(print_failed, capture_data, "Stream failed");
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
@@ -226,16 +252,18 @@ bool connect_ftd3(bool print_failed, CaptureData* capture_data, CaptureDevice* d
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ftd3_is_error_compat(handlers, ftd3_set_stream_pipe_compat(handlers, BULK_IN, ftd3_get_capture_size(&tmp_status)))) {
|
||||
if(ftd3_is_error_compat(handlers, ftd3_set_stream_pipe_compat(handlers, BULK_IN, ftd3_get_capture_size(_3d_enabled_result)))) {
|
||||
capture_error_print(print_failed, capture_data, "Stream failed");
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
stored_3d_status = tmp_status.requested_3d;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ftd3_capture_main_loop(CaptureData* capture_data) {
|
||||
bool could_have_3d = get_3d_enabled(&capture_data->status, true);
|
||||
ftd3_main_loop_compat(capture_data, BULK_IN);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user