Add support for multi-audio packet

This commit is contained in:
Lorenzooone 2026-01-11 19:13:42 +01:00
parent 74debf9cf3
commit 0e3f6fbc16
3 changed files with 32 additions and 86 deletions

View File

@ -250,34 +250,6 @@ static size_t get_partner_ctr_size_command_header(PartnerCTRCaptureCommand read_
}
}
static USB3DSOptimizeColumnInfo convert_to_column_info(uint16_t value) {
// The macos compiler requires this... :/
USB3DSOptimizeColumnInfo column_info;
column_info.has_extra_header_data_2d_only = (value >> 15) & 1;
column_info.buffer_num = (value >> 14) & 1;
column_info.unk = (value >> 10) & 0xF;
column_info.column_index = value & 0x3FF;
return column_info;
}
static bool get_expect_extra_header_in_buffer(uint16_t value) {
return convert_to_column_info(value).has_extra_header_data_2d_only;
}
static bool get_is_data_2d_only(uint16_t value) {
return convert_to_column_info(value).has_extra_header_data_2d_only;
}
static bool get_is_pos_column_synch_in_buffer(uint8_t* buffer, size_t pos_to_check, uint16_t column_index) {
if(read_le16(buffer + pos_to_check) != SYNCH_VALUE_PARTNER_CTR)
return false;
return convert_to_column_info(read_le16(buffer + pos_to_check + 2)).column_index == column_index;
}
static bool get_is_pos_column_synch_in_buffer(USB3DSOptimizeHeaderSoundData* in_ptr, uint16_t column_index) {
return get_is_pos_column_synch_in_buffer((uint8_t*)&in_ptr->header_info, 0, column_index);
}
static bool get_is_pos_synch_in_buffer(uint8_t* buffer, size_t pos_to_check) {
PartnerCTRCaptureCommand base_command = read_partner_ctr_base_command(buffer + pos_to_check);
return base_command.magic == SYNCH_VALUE_PARTNER_CTR;
@ -288,37 +260,6 @@ static bool get_is_pos_first_synch_in_buffer(uint8_t* buffer, size_t pos_to_chec
return (base_command.magic == SYNCH_VALUE_PARTNER_CTR) && (base_command.command == PARTNER_CTR_CAPTURE_COMMAND_INPUT);
}
static bool get_is_buffer_2d_fully_synced(CaptureReceived* buffer) {
USB8883DSOptimizeCaptureReceived* real_buffer = &buffer->cypress_optimize_received_888;
USB8883DSOptimizeCaptureReceivedExtraHeader* real_buffer_special = &buffer->cypress_optimize_received_888_extra_header;
bool is_special = get_expect_extra_header_in_buffer(read_le16((uint8_t*)&real_buffer->columns_data[0].header_sound.header_info.column_info));
for(int i = 0; i < TOP_WIDTH_3DS; i++)
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i].header_sound, i))
return false;
if(is_special && (!get_is_pos_column_synch_in_buffer(&real_buffer_special->columns_data[TOP_WIDTH_3DS].header_sound, TOP_WIDTH_3DS)))
return false;
return true;
}
static bool get_is_buffer_3d_fully_synced(CaptureReceived* buffer) {
USB8883DSOptimizeCaptureReceived_3D* real_buffer = &buffer->cypress_optimize_received_888_3d;
for(int i = 0; i < TOP_WIDTH_3DS; i++) {
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i][0].header_sound, i * 2))
return false;
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i][1].header_sound, (i * 2) + 1))
return false;
}
if(!get_is_pos_column_synch_in_buffer(&real_buffer->bottom_only_column.header_sound, TOP_WIDTH_3DS * 2))
return false;
return true;
}
static bool get_is_buffer_fully_synched(CaptureReceived* buffer, bool is_3d) {
if(is_3d)
return get_is_buffer_3d_fully_synced(buffer);
return get_is_buffer_2d_fully_synced(buffer);
}
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer, int start_pos) {
for(int i = start_pos; i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
if(get_is_pos_first_synch_in_buffer(buffer, i * 2))
@ -358,10 +299,6 @@ static void cypress_output_to_thread(CaptureData* capture_data, uint8_t *buffer_
// Output to the other threads...
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(internal_index);
copy_slice_data_to_buffer((uint8_t*)&data_buf->capture_buf, buffer_arr, start_slice_index, start_slice_pos, read_size);
if(!get_is_buffer_fully_synched(&data_buf->capture_buf, is_3d)) {
capture_data->data_buffers.ReleaseWriterBuffer(internal_index, false);
return;
}
const auto curr_time = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double> diff = curr_time - (*clock_start);
*clock_start = curr_time;
@ -432,20 +369,23 @@ static size_t get_pos_next_command_partner_ctr(uint8_t* data, size_t slice_index
static size_t find_pos_partner_ctr_x_screen(uint8_t* data, size_t slice_index, size_t start_pos, size_t curr_pos, size_t available_bytes) {
if((curr_pos + sizeof(PartnerCTRCaptureCommand)) > available_bytes)
return ERROR_CTR_SCREEN_SEARCH_NOT_ENOUGH_DATA;
PartnerCTRCaptureCommand read_command = get_command_partner_ctr(data, slice_index, start_pos, curr_pos);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return ERROR_CTR_SCREEN_SEARCH_NOT_SYNCHRONIZED;
if((read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_BOT_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_SECOND_TOP_SCREEN))
return curr_pos;
if(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_AUDIO)
while(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_AUDIO) {
curr_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, curr_pos);
if((curr_pos + sizeof(PartnerCTRCaptureCommand)) > available_bytes)
return ERROR_CTR_SCREEN_SEARCH_NOT_ENOUGH_DATA;
read_command = get_command_partner_ctr(data, slice_index, start_pos, curr_pos);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return ERROR_CTR_SCREEN_SEARCH_NOT_SYNCHRONIZED;
if((curr_pos + sizeof(PartnerCTRCaptureCommand)) > available_bytes)
return ERROR_CTR_SCREEN_SEARCH_NOT_ENOUGH_DATA;
read_command = get_command_partner_ctr(data, slice_index, start_pos, curr_pos);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return ERROR_CTR_SCREEN_SEARCH_NOT_SYNCHRONIZED;
}
if((read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_BOT_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_SECOND_TOP_SCREEN))
return curr_pos;
@ -475,13 +415,13 @@ static bool is_valid_frame_partner_ctr(uint8_t* data, size_t slice_index, size_t
out_end_pos = 0;
first_screen_pos = find_pos_partner_ctr_x_screen(data, slice_index, start_pos, 0, available_bytes);
out_end_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, first_screen_pos);
if(first_screen_pos == ERROR_CTR_SCREEN_SEARCH_NOT_ENOUGH_DATA)
return false;
if(first_screen_pos == ERROR_CTR_SCREEN_SEARCH_NOT_SYNCHRONIZED) {
synchronized = false;
return false;
}
out_end_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, first_screen_pos);
PartnerCTRCaptureCommand read_command = get_command_partner_ctr(data, slice_index, start_pos, first_screen_pos);
if(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN)
@ -492,13 +432,13 @@ static bool is_valid_frame_partner_ctr(uint8_t* data, size_t slice_index, size_t
has_top_second = true;
second_screen_pos = find_pos_partner_ctr_x_screen(data, slice_index, start_pos, out_end_pos, available_bytes);
out_end_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, second_screen_pos);
if(second_screen_pos == ERROR_CTR_SCREEN_SEARCH_NOT_ENOUGH_DATA)
return false;
if(second_screen_pos == ERROR_CTR_SCREEN_SEARCH_NOT_SYNCHRONIZED) {
synchronized = false;
return false;
}
out_end_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, second_screen_pos);
read_command = get_command_partner_ctr(data, slice_index, start_pos, second_screen_pos);
if(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN)
@ -520,13 +460,13 @@ static bool is_valid_frame_partner_ctr(uint8_t* data, size_t slice_index, size_t
}
third_screen_pos = find_pos_partner_ctr_x_screen(data, slice_index, start_pos, out_end_pos, available_bytes);
out_end_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, third_screen_pos);
if(third_screen_pos == ERROR_CTR_SCREEN_SEARCH_NOT_ENOUGH_DATA)
return false;
if(third_screen_pos == ERROR_CTR_SCREEN_SEARCH_NOT_SYNCHRONIZED) {
synchronized = false;
return false;
}
out_end_pos = get_pos_next_command_partner_ctr(data, slice_index, start_pos, third_screen_pos);
read_command = get_command_partner_ctr(data, slice_index, start_pos, third_screen_pos);
if(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN)

View File

@ -114,7 +114,7 @@ static int recv_partner_ctr_packet(cy_device_device_handlers* handlers, const cy
static int write_to_address_partner_ctr(cy_device_device_handlers* handlers, const cypart_device_usb_device* device, uint32_t address, const uint8_t* data, size_t data_size, uint8_t data_size_byte) {
int transferred = 0;
const size_t out_data_size = 6 + data_size;
uint8_t buffer_out[out_data_size];
uint8_t* buffer_out = new uint8_t[out_data_size];
buffer_out[0] = 0x43;
buffer_out[1] = data_size_byte;
@ -122,6 +122,7 @@ static int write_to_address_partner_ctr(cy_device_device_handlers* handlers, con
memcpy(buffer_out + 6, data, data_size);
int ret = send_partner_ctr_packet(handlers, device, buffer_out, out_data_size, transferred);
delete []buffer_out;
if(ret < 0)
return ret;
if(transferred < ((int)out_data_size))

View File

@ -824,15 +824,16 @@ static uint8_t* find_partner_ctr_x_screen(uint8_t* data) {
PartnerCTRCaptureCommand read_command = read_partner_ctr_base_command(data);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return NULL;
if((read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_BOT_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_SECOND_TOP_SCREEN))
return data;
if(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_AUDIO)
while(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_AUDIO) {
data = get_ptr_next_command_partner_ctr(data);
read_command = read_partner_ctr_base_command(data);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return NULL;
read_command = read_partner_ctr_base_command(data);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return NULL;
}
if((read_command.command == PARTNER_CTR_CAPTURE_COMMAND_TOP_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_BOT_SCREEN) || (read_command.command == PARTNER_CTR_CAPTURE_COMMAND_SECOND_TOP_SCREEN))
return data;
@ -1158,17 +1159,21 @@ static void copyAudioOptimize3DS3DForced2DBE(std::int16_t *p_out, uint64_t &n_sa
}
static void usb_partner_ctr_copyBufferToAudio(uint8_t* buffer_ptr, std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian) {
uint8_t* audio_buffer_ptr = NULL;
PartnerCTRCaptureCommand read_command = read_partner_ctr_base_command(buffer_ptr);
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return;
if(read_command.command != PARTNER_CTR_CAPTURE_COMMAND_AUDIO)
return;
buffer_ptr += get_partner_ctr_size_command_header(read_command);
while(read_command.command == PARTNER_CTR_CAPTURE_COMMAND_AUDIO) {
if(read_command.magic != PARTNER_CTR_CAPTURE_BASE_COMMAND)
return;
audio_buffer_ptr = buffer_ptr + get_partner_ctr_size_command_header(read_command);
memcpy_data_u16le_origin((uint16_t*)p_out + n_samples, buffer_ptr, (size_t)read_command.payload_size / 2, is_big_endian);
memcpy_data_u16le_origin((uint16_t*)p_out + n_samples, audio_buffer_ptr, (size_t)read_command.payload_size / 2, is_big_endian);
n_samples += read_command.payload_size / 2;
n_samples += read_command.payload_size / 2;
buffer_ptr = get_ptr_next_command_partner_ctr(buffer_ptr);
read_command = read_partner_ctr_base_command(buffer_ptr);
}
}
static void usb_partner_ctr_copyBufferAfterCommandToAudio(uint8_t* buffer_ptr, std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian) {