Fix possible loop in Optimize 3DS CCs and issues with initial frame for Partner CTR Capture

This commit is contained in:
Lorenzooone 2026-01-15 03:04:45 +01:00
parent 9aa4fe3613
commit a83ba0f79f
2 changed files with 19 additions and 9 deletions

View File

@ -33,6 +33,8 @@
#define NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS (3 * NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS)
#define OPTIMIZE_3DS_TOTAL_BUFFERS_SIZE (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE)
#define MAX_TIME_WAIT 1.0
#define CAPTURE_START_AGAIN_NO_KEY_TIME 260.0
@ -457,8 +459,8 @@ static bool get_is_buffer_fully_synched(CaptureReceived* buffer, bool is_3d, boo
return get_is_buffer_rgb888_fully_synced(buffer);
}
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer) {
for(int i = 0; i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer, size_t start_pos) {
for(size_t i = (start_pos / 2); i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
if(get_is_pos_first_synch_in_buffer(buffer, i * 2))
return i * 2;
}
@ -481,11 +483,11 @@ static void unlock_buffers_from_x(CypressOptimize3DSDeviceCaptureReceivedData* c
}
static void copy_slice_data_to_buffer(uint8_t* dst, uint8_t *src, size_t start_slice_index, size_t start_slice_pos, size_t copy_size) {
size_t start_byte = (start_slice_index * SINGLE_RING_BUFFER_SLICE_SIZE) + start_slice_pos;
if((start_byte + copy_size) <= (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE))
size_t start_byte = ((start_slice_index * SINGLE_RING_BUFFER_SLICE_SIZE) + start_slice_pos) % OPTIMIZE_3DS_TOTAL_BUFFERS_SIZE;
if((start_byte + copy_size) <= OPTIMIZE_3DS_TOTAL_BUFFERS_SIZE)
memcpy(dst, src + start_byte, copy_size);
else {
size_t upper_read_size = (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE) - start_byte;
size_t upper_read_size = OPTIMIZE_3DS_TOTAL_BUFFERS_SIZE - start_byte;
size_t start_read_size = copy_size - upper_read_size;
memcpy(dst, src + start_byte, upper_read_size);
memcpy(dst + upper_read_size, src, start_read_size);
@ -512,6 +514,8 @@ static void cypress_output_to_thread(CaptureData* capture_data, uint8_t *buffer_
static bool cypress_device_read_frame_not_synchronized(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, int &error) {
volatile int first_slice_to_check = *cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index;
volatile int original_first_slice_to_check = first_slice_to_check;
volatile int first_slice_pos_to_check = (int)*cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos;
bool found = false;
// Determine which buffer is the first which needs to still be checked
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++) {
@ -533,7 +537,11 @@ static bool cypress_device_read_frame_not_synchronized(CypressOptimize3DSDeviceC
// If they are there, enque the buffer and switch mode.
// Checks all available buffers which have data (but in order).
if(cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[check_index]) {
size_t result = get_pos_first_synch_in_buffer(&cypress_device_capture_recv_data->ring_slice_buffer_arr[check_index * SINGLE_RING_BUFFER_SLICE_SIZE]);
size_t start_result = 0;
// Increase by two to prevent looping...
if(check_index == original_first_slice_to_check)
start_result = first_slice_pos_to_check + 2;
size_t result = get_pos_first_synch_in_buffer(&cypress_device_capture_recv_data->ring_slice_buffer_arr[check_index * SINGLE_RING_BUFFER_SLICE_SIZE], start_result);
if(result >= SINGLE_RING_BUFFER_SLICE_SIZE) {
unlock_buffer_slice_index(cypress_device_capture_recv_data, check_index, true);
}
@ -931,7 +939,7 @@ void cyop_device_acquisition_main_loop(CaptureData* capture_data) {
bool could_use_3d = get_3d_enabled(&capture_data->status, true);
bool stored_is_3d = could_use_3d && get_3d_enabled(&capture_data->status);
uint8_t *ring_slice_buffer = new uint8_t[NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE];
uint8_t *ring_slice_buffer = new uint8_t[OPTIMIZE_3DS_TOTAL_BUFFERS_SIZE];
bool *is_ring_buffer_slice_data_ready = new bool[NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS];
bool *is_ring_buffer_slice_data_in_use = new bool[NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS];
int *buffer_ring_slice_to_array = new int[NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS];

View File

@ -266,7 +266,7 @@ static bool get_is_pos_first_synch_in_buffer(uint8_t* buffer, size_t pos_to_chec
}
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer, size_t start_pos) {
for(size_t i = start_pos; i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
for(size_t i = (start_pos / 2); i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
if(get_is_pos_first_synch_in_buffer(buffer, i * 2))
return i * 2;
}
@ -318,6 +318,7 @@ static void cypress_output_to_thread(CaptureData* capture_data, uint8_t *buffer_
static bool cypress_device_read_frame_not_synchronized(CypressPartnerCTRDeviceCaptureReceivedData* cypress_device_capture_recv_data, int &error) {
volatile int first_slice_to_check = *cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index;
volatile int original_first_slice_to_check = first_slice_to_check;
volatile int first_slice_pos_to_check = (int)*cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos;
bool found = false;
// Determine which buffer is the first which needs to still be checked
@ -341,7 +342,8 @@ static bool cypress_device_read_frame_not_synchronized(CypressPartnerCTRDeviceCa
// Checks all available buffers which have data (but in order).
if(cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[check_index]) {
size_t start_result = 0;
if(check_index == first_slice_to_check)
// Increase by two to prevent looping...
if(check_index == original_first_slice_to_check)
start_result = first_slice_pos_to_check + 2;
size_t result = get_pos_first_synch_in_buffer(&cypress_device_capture_recv_data->ring_slice_buffer_arr[check_index * SINGLE_RING_BUFFER_SLICE_SIZE], start_result);
if(result >= SINGLE_RING_BUFFER_SLICE_SIZE) {