Implement buffer reading

The PID IV functions are currently buggy
This commit is contained in:
Lorenzo Carletti 2023-01-14 19:24:27 +01:00
parent 7291998e59
commit 0bd9e01865
6 changed files with 253 additions and 55 deletions

View File

@ -11,6 +11,7 @@
#define SKIP_SENDS 0x10
#define MAX_WAIT_FOR_SYN 30
#define MIN_WAIT_FOR_SYN 3
#define MAX_NO_NEW_INFO 30
#define NUMBER_OF_ENTITIES 2
@ -59,11 +60,13 @@ u8 syn_transmitted;
u8 has_transmitted_syn;
int last_transfer_counter;
int buffer_counter;
int buffer_counter_out;
u8 start_state_updated;
u8 start_state;
u32 prepared_value;
int skip_sends = 0;
u8 base_pos_out = 0;
u8 increment_out = 0;
u8 last_filtered = 0;
u8 since_last_recv_gen3 = 0;
int own_end_gen3;
@ -169,7 +172,9 @@ u8 get_start_state() {
void reset_transfer_data_between_sync() {
has_transmitted_syn = 0;
syn_transmitted = 0;
increment_out = 0;
buffer_counter = 0;
buffer_counter_out = 0;
last_transfer_counter = 0;
}
@ -198,21 +203,18 @@ __attribute__((optimize(3))) void set_next_vcount_interrupt(void){
IWRAM_CODE __attribute__((optimize(3))) int communicate_buffer(u8 data, u8 is_master) {
u8 ignore_data = 0;
if(!has_transmitted_syn) {
if(syn_transmitted > MAX_WAIT_FOR_SYN) {
if(!is_master) {
has_transmitted_syn = 1;
if(data == SYNCHRONIZE_BYTE) {
base_pos_out = 0;
ignore_data = 1;
}
else
base_pos_out = 1;
if((syn_transmitted > MAX_WAIT_FOR_SYN) && (!is_master)) {
if(data == SYNCHRONIZE_BYTE) {
base_pos_out = 0;
ignore_data = 1;
}
else
syn_transmitted = MAX_WAIT_FOR_SYN;
has_transmitted_syn = 1;
}
else {
if(syn_transmitted < 3) {
if((is_master) && (syn_transmitted >= MAX_WAIT_FOR_SYN))
syn_transmitted = MAX_WAIT_FOR_SYN;
if(syn_transmitted < MIN_WAIT_FOR_SYN) {
if((data != SEND_NO_INFO) && (data == SYNCHRONIZE_BYTE))
syn_transmitted++;
return SYNCHRONIZE_BYTE;
@ -238,12 +240,17 @@ IWRAM_CODE __attribute__((optimize(3))) int communicate_buffer(u8 data, u8 is_ma
reset_transfer_data_between_sync();
if(sizes_index >= get_number_of_buffers())
set_start_state(START_TRADE_DON);
if(base_pos_out)
return out_buffer[base_pos - base_pos_out];
if(buffer_counter_out < transfer_sizes[sizes_index-1])
return out_buffer[base_pos-1];
return SEND_0_INFO;
}
}
return out_buffer[buffer_counter + base_pos - base_pos_out];
buffer_counter_out++;
if(buffer_counter_out > transfer_sizes[sizes_index])
buffer_counter_out = transfer_sizes[sizes_index];
return out_buffer[buffer_counter_out - 1 + base_pos];
}
IWRAM_CODE __attribute__((optimize(3))) int check_if_continue(u8 data, u8* sends, u8* recvs, int size, int new_state, int new_send, u8 filter) {
@ -270,6 +277,8 @@ IWRAM_CODE __attribute__((optimize(3))) int process_data_arrived_gen1(u8 data, u
return check_if_continue(data, gen1_start_trade_start_trade_procedure[is_master], gen1_start_trade_start_trade_procedure_next[is_master], GEN1_START_STATES_NUM, START_TRADE_SYN, SEND_NO_INFO, 1);
case START_TRADE_PAR:
return communicate_buffer(data, is_master);
case START_TRADE_DON:
return SEND_NO_INFO;
case START_TRADE_SYN:
if(is_master)
init_transfer_data();
@ -345,6 +354,8 @@ IWRAM_CODE __attribute__((optimize(3))) int process_data_arrived_gen2(u8 data, u
return check_if_continue(data, gen2_start_trade_start_trade_procedure[is_master], gen2_start_trade_start_trade_procedure_next[is_master], GEN2_START_STATES_NUM, START_TRADE_SYN, SEND_NO_INFO, 0);
case START_TRADE_PAR:
return communicate_buffer(data, is_master);
case START_TRADE_DON:
return SEND_NO_INFO;
case START_TRADE_SYN:
if(is_master)
init_transfer_data();

View File

@ -140,8 +140,21 @@ int main(void)
VBlankIntrWait();
scanKeys();
keys = keysDown();
if(curr_state == START_TRADE)
print_start_trade();
if(curr_state == START_TRADE) {
if(get_start_state_raw() == START_TRADE_DON) {
curr_state = TRADING_MENU;
cursor_y_pos = 0;
cursor_x_pos = 0;
own_menu = 0;
read_comm_buffer(&game_data[1], curr_gen, region);
prepare_options_trade(game_data, curr_gen, own_menu);
print_trade_menu(game_data, 1, curr_gen, 1, own_menu);
cursor_update_trading_menu(cursor_y_pos, cursor_x_pos);
}
else {
print_start_trade();
}
}
}
//PRINT_FUNCTION("%p %p\n", get_communication_buffer(0));
//worst_case_conversion_tester(&counter);
@ -224,8 +237,5 @@ int main(void)
update = 0;
}
//start_gen2_slave();
//start_gen2();
return 0;
}

View File

@ -752,28 +752,28 @@ u32 swap_endian_int(u32 integer) {
return ((integer & 0xFF000000) >> 24) | ((integer & 0xFF) << 24) | ((integer & 0xFF0000) >> 8) | ((integer & 0xFF00) << 8);
}
u8 validate_converting_mon_of_gen1(u8 index, struct gen1_mon* data_src) {
u8 validate_converting_mon_of_gen1(u8 index, struct gen1_mon_data* src) {
// Check for matching index to species
if(index != data_src->data.species)
if(index != src->species)
return 0;
u8 conv_species = get_mon_index_gen1_to_3(data_src->data.species);
u8 conv_species = get_mon_index_gen1_to_3(src->species);
// Is this a valid mon
if((conv_species > LAST_VALID_GEN_1_MON) || (conv_species == 0))
return 0;
// Does it have a valid movepool
if(!has_legal_moves_gen12(data_src->data.moves, 0))
if(!has_legal_moves_gen12(src->moves, 0))
return 0;
// Check for valid types
u8 matched[2] = {0,0};
for(int i = 0; i < 2; i++) {
if((data_src->data.type[i] == pokemon_types_gen1_bin[(2*data_src->data.species)]) && (!matched[0]))
if((src->type[i] == pokemon_types_gen1_bin[(2*src->species)]) && (!matched[0]))
matched[0] = 1;
else if((data_src->data.type[i] == pokemon_types_gen1_bin[(2*data_src->data.species)+1]) && (!matched[1]))
else if((src->type[i] == pokemon_types_gen1_bin[(2*src->species)+1]) && (!matched[1]))
matched[1] = 1;
}
for(int i = 0; i < 2; i++)
@ -783,22 +783,22 @@ u8 validate_converting_mon_of_gen1(u8 index, struct gen1_mon* data_src) {
return 1;
}
u8 validate_converting_mon_of_gen2(u8 index, struct gen2_mon* data_src) {
u8 validate_converting_mon_of_gen2(u8 index, struct gen2_mon_data* src, u8* is_egg) {
if(index == GEN2_EGG)
data_src->is_egg = 1;
*is_egg = 1;
else
data_src->is_egg = 0;
*is_egg = 0;
// Check for matching index to species
if((!data_src->is_egg) && (index != data_src->data.species))
if((!(*is_egg)) && (index != src->species))
return 0;
// Is this a valid mon
if((data_src->data.species > LAST_VALID_GEN_2_MON) || (data_src->data.species == 0))
if((src->species > LAST_VALID_GEN_2_MON) || (src->species == 0))
return 0;
// Does it have a valid movepool
if(!has_legal_moves_gen12(data_src->data.moves, 1))
if(!has_legal_moves_gen12(src->moves, 1))
return 0;
return 1;
@ -1311,6 +1311,8 @@ void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8
// Initial data decryption
if(!decrypt_data(src, decryption)) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
@ -1333,12 +1335,16 @@ void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8
// Species checks
if((growth->species > LAST_VALID_GEN_3_MON) || (growth->species == 0)) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
// Obedience checks
if(((growth->species == MEW_SPECIES) || (growth->species == DEOXYS_SPECIES)) && (!misc->obedience)) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
@ -1355,22 +1361,30 @@ void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8
if(!are_evs_legal_gen3(evs)) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
if(!has_legal_moves_gen3(attacks)) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
if(!is_ability_valid(growth->species, src->pid, misc->ability, misc->met_location, (misc->origins_info>>7) & 0xF, dst->deoxys_form)) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
// Bad egg checks
if(src->is_bad_egg) {
dst->is_valid_gen3 = 0;
dst->is_valid_gen2 = 0;
dst->is_valid_gen1 = 0;
return;
}
@ -1541,10 +1555,10 @@ u8 gen3_to_gen1(struct gen1_mon* dst_data, struct gen3_mon_data_unenc* data_src,
return 1;
}
u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst, u8 index, u8* ot_name, u8* nickname, u8 is_jp) {
struct gen2_mon_data* src = &src_data->data;
struct gen3_mon* dst = &data_dst->src;
u8 gen2_to_gen3(struct gen2_mon_data* src, struct gen3_mon_data_unenc* data_dst, u8 index, u8* ot_name, u8* nickname, u8 is_jp) {
struct gen3_mon* dst = data_dst->src;
u8 no_restrictions = 1;
u8 is_egg = 0;
// Reset everything
for(int i = 0; i < sizeof(struct gen3_mon); i++)
@ -1554,7 +1568,7 @@ u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst,
data_dst->is_valid_gen2 = 0;
// Check if valid
if(!validate_converting_mon_of_gen2(index, src_data))
if(!validate_converting_mon_of_gen2(index, src, &is_egg))
return 0;
data_dst->is_valid_gen3 = 1;
@ -1563,7 +1577,7 @@ u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst,
// Set base data
dst->has_species = 1;
dst->pokerus_rem = 0xFF;
data_dst->is_egg = src_data->is_egg;
data_dst->is_egg = is_egg;
if(is_jp)
dst->language = JAPANESE_LANGUAGE;
@ -1571,7 +1585,7 @@ u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst,
dst->language = ENGLISH_LANGUAGE;
// Handle Nickname + OT conversion
convert_strings_of_gen12(dst, src->species, ot_name, nickname, src_data->is_egg);
convert_strings_of_gen12(dst, src->species, ot_name, nickname, is_egg);
// Handle OT ID, if same as the game owner, set it to the game owner's
dst->ot_id = swap_endian_short(src->ot_id);
@ -1599,11 +1613,11 @@ u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst,
data_dst->growth.item = convert_item_to_gen3(src->item);
// Handle cases in which the nature would be forced
if((dst->level == MAX_LEVEL) || (src_data->is_egg))
if((dst->level == MAX_LEVEL) || (is_egg))
wanted_nature = SWI_DivMod(get_rng(), NUM_NATURES);
// Store egg cycles
if(src_data->is_egg) {
if(is_egg) {
data_dst->growth.friendship = src->friendship;
data_dst->misc.is_egg = 1;
dst->use_egg_name = 1;
@ -1623,7 +1637,7 @@ u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst,
data_dst->misc.obedience = 1;
// Set the PID-Origin-IVs data, they're all connected
set_origin_pid_iv(dst, &data_dst->misc, data_dst->growth.species, src->ivs, wanted_nature, src->ot_gender, src_data->is_egg, no_restrictions);
set_origin_pid_iv(dst, &data_dst->misc, data_dst->growth.species, src->ivs, wanted_nature, src->ot_gender, is_egg, no_restrictions);
// Place all the substructures' data
place_and_encrypt_gen3_data(data_dst, dst);
@ -1636,9 +1650,8 @@ u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst,
return 1;
}
u8 gen1_to_gen3(struct gen1_mon* src_data, struct gen3_mon_data_unenc* data_dst, u8 index, u8* ot_name, u8* nickname, u8 is_jp) {
struct gen1_mon_data* src = &src_data->data;
struct gen3_mon* dst = &data_dst->src;
u8 gen1_to_gen3(struct gen1_mon_data* src, struct gen3_mon_data_unenc* data_dst, u8 index, u8* ot_name, u8* nickname, u8 is_jp) {
struct gen3_mon* dst = data_dst->src;
u8 no_restrictions = 1;
// Reset everything
@ -1649,7 +1662,7 @@ u8 gen1_to_gen3(struct gen1_mon* src_data, struct gen3_mon_data_unenc* data_dst,
data_dst->is_valid_gen1 = 0;
// Check if valid
if(!validate_converting_mon_of_gen1(index, src_data))
if(!validate_converting_mon_of_gen1(index, src))
return 0;
data_dst->is_valid_gen3 = 1;

View File

@ -278,8 +278,8 @@ struct gen1_party {
void process_gen3_data(struct gen3_mon*, struct gen3_mon_data_unenc*, u8, u8);
u8 gen3_to_gen2(struct gen2_mon*, struct gen3_mon_data_unenc*, u32);
u8 gen3_to_gen1(struct gen1_mon*, struct gen3_mon_data_unenc*, u32);
u8 gen2_to_gen3(struct gen2_mon*, struct gen3_mon_data_unenc*, u8, u8*, u8*, u8);
u8 gen1_to_gen3(struct gen1_mon*, struct gen3_mon_data_unenc*, u8, u8*, u8*, u8);
u8 gen2_to_gen3(struct gen2_mon_data*, struct gen3_mon_data_unenc*, u8, u8*, u8*, u8);
u8 gen1_to_gen3(struct gen1_mon_data*, struct gen3_mon_data_unenc*, u8, u8*, u8*, u8);
const u8* get_pokemon_name_raw(struct gen3_mon_data_unenc*);
u16 get_mon_index_raw(struct gen3_mon_data_unenc*);

View File

@ -6,6 +6,8 @@
#include "party_handler.h"
#include "gen3_save.h"
#include "default_gift_ribbons_bin.h"
u32 communication_buffers[2][BUFFER_SIZE>>2];
u16 buffer_sizes[NUM_SIZES];
u8 number_of_sizes;
@ -60,7 +62,7 @@ void prepare_patch_set(u8* buffer, u8* patch_set_buffer, int size, int start_pos
patch_set_buffer[i] = 0;
u32 base = 0;
for(int i = 0; i < size; i++) {
for(int i = start_pos; i < size; i++) {
if(buffer[i] == NO_ACTION_BYTE) {
buffer[i] = 0xFF;
patch_set_buffer[cursor_data++] = i+1-base;
@ -85,6 +87,21 @@ void prepare_patch_set(u8* buffer, u8* patch_set_buffer, int size, int start_pos
patch_set_buffer[cursor_data] = 0xFF;
}
void apply_patch_set(u8* buffer, u8* patch_set_buffer, int size, int start_pos, int patch_set_size, int base_pos) {
u32 base = start_pos;
for(int i = base_pos; i < patch_set_size; i++) {
if(patch_set_buffer[i]) {
if(patch_set_buffer[i] == 0xFF) {
base += NO_ACTION_BYTE-1;
if(base >= size)
return;
}
else if(patch_set_buffer[i] <= NO_ACTION_BYTE-2)
buffer[patch_set_buffer[i]+base-1] = 0xFE;
}
}
}
void prepare_mail_gen2(u8* buffer, int size, u8* patch_set_buffer, u8 patch_set_buffer_size, u32 start_pos) {
for(int i = 0; i < size; i++)
buffer[i] = 0;
@ -169,6 +186,9 @@ void buffer_loader(struct game_data_t* gd, u32* buffer, u16* sizes, u8 index) {
pos += RANDOM_DATA_SIZE;
text_gen3_to_gen12(gd->trainer_name, td+pos, OT_NAME_GEN3_SIZE+1, names_size, gd->game_identifier.game_is_jp, is_jp);
for(int i = 0; i < names_size; i++)
if((td[pos+i] == NO_ACTION_BYTE) || (td[pos+i] == (NO_ACTION_BYTE-1)))
td[pos+i] = NO_ACTION_BYTE-2;
td[pos+names_size-1] = GEN2_EOL;
pos += names_size;
td[pos++] = total_mons;
@ -237,6 +257,9 @@ void load_names_gen12(struct game_data_t* game_data, u8* trainer_name, u8* ot_na
size = STRING_GEN2_JP_SIZE;
text_gen3_to_gen12(game_data->trainer_name, trainer_name, OT_NAME_GEN3_SIZE+1, size, game_data->game_identifier.game_is_jp, is_jp);
for(int i = 0; i < size; i++)
if((trainer_name[i] == NO_ACTION_BYTE) || (trainer_name[i] == (NO_ACTION_BYTE-1)))
trainer_name[i] = NO_ACTION_BYTE-2;
trainer_name[size-1] = GEN2_EOL;
for(int i = 0; i < PARTY_SIZE; i++) {
@ -332,9 +355,9 @@ void prepare_gen2_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_j
safety_bytes[i] = DEFAULT_FILLER;
if(!is_jp)
prepare_patch_set((u8*)(&td_int->trainer_info), td_int->patch_set.patch_set, sizeof(struct trainer_data_gen2_int)-(STRING_GEN2_INT_SIZE + MON_INDEX_SIZE + 1), STRING_GEN2_INT_SIZE + MON_INDEX_SIZE + 1, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
prepare_patch_set((u8*)(&td_int->trainer_info), td_int->patch_set.patch_set, sizeof(struct trainer_data_gen2_int)-(STRING_GEN2_INT_SIZE + MON_INDEX_SIZE), STRING_GEN2_INT_SIZE + MON_INDEX_SIZE, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
else
prepare_patch_set((u8*)(&td_jp->trainer_info), td_jp->patch_set.patch_set, sizeof(struct trainer_data_gen2_jp)-(STRING_GEN2_JP_SIZE + MON_INDEX_SIZE + 1), STRING_GEN2_JP_SIZE + MON_INDEX_SIZE + 1, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
prepare_patch_set((u8*)(&td_jp->trainer_info), td_jp->patch_set.patch_set, sizeof(struct trainer_data_gen2_jp)-(STRING_GEN2_JP_SIZE + MON_INDEX_SIZE), STRING_GEN2_JP_SIZE + MON_INDEX_SIZE, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
u8* useless_sync_bytes = td_int->useless_sync;
if(is_jp)
@ -392,9 +415,9 @@ void prepare_gen1_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_j
safety_bytes[i] = DEFAULT_FILLER;
if(!is_jp)
prepare_patch_set((u8*)(&td_int->trainer_info), td_int->patch_set.patch_set, sizeof(struct trainer_data_gen1_int)-(STRING_GEN2_INT_SIZE + MON_INDEX_SIZE + 1), STRING_GEN2_INT_SIZE + MON_INDEX_SIZE + 1, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
prepare_patch_set((u8*)(&td_int->trainer_info), td_int->patch_set.patch_set, sizeof(struct trainer_data_gen1_int)-(STRING_GEN2_INT_SIZE + MON_INDEX_SIZE), STRING_GEN2_INT_SIZE + MON_INDEX_SIZE, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
else
prepare_patch_set((u8*)(&td_jp->trainer_info), td_jp->patch_set.patch_set, sizeof(struct trainer_data_gen1_jp)-(STRING_GEN2_JP_SIZE + MON_INDEX_SIZE + 1), STRING_GEN2_JP_SIZE + MON_INDEX_SIZE + 1, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
prepare_patch_set((u8*)(&td_jp->trainer_info), td_jp->patch_set.patch_set, sizeof(struct trainer_data_gen1_jp)-(STRING_GEN2_JP_SIZE + MON_INDEX_SIZE), STRING_GEN2_JP_SIZE + MON_INDEX_SIZE, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
sizes[0] = sizeof(struct random_data_t);
if(!is_jp)
@ -409,7 +432,7 @@ void prepare_gen1_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_j
u8 are_checksum_same_gen3(struct gen3_trade_data* td) {
u32 checksum = 0;
for(int i = 0; i < PARTY_SIZE; i++) {
u32* mail_buf = &td->mails_3[i];
u32* mail_buf = (u32*)&td->mails_3[i];
for(int i = 0; i < (sizeof(struct mail_gen3)>>2); i++)
checksum += mail_buf[i];
}
@ -419,7 +442,7 @@ u8 are_checksum_same_gen3(struct gen3_trade_data* td) {
checksum = 0;
u32* party_buf = &td->party_3;
u32* party_buf = (u32*)&td->party_3;
for(int i = 0; i < (sizeof(struct gen3_party)>>2); i++)
checksum += party_buf[i];
@ -444,7 +467,7 @@ void prepare_gen3_trade_data(struct game_data_t* game_data, u32* buffer, u16* si
u32 checksum = 0;
for(int i = 0; i < PARTY_SIZE; i++) {
copy_bytes(&game_data->mails_3[i], &td->mails_3[i], sizeof(struct mail_gen3), 0, 0);
u32* mail_buf = &td->mails_3[i];
u32* mail_buf = (u32*)&td->mails_3[i];
for(int i = 0; i < (sizeof(struct mail_gen3)>>2); i++)
checksum += mail_buf[i];
}
@ -453,7 +476,7 @@ void prepare_gen3_trade_data(struct game_data_t* game_data, u32* buffer, u16* si
checksum = 0;
copy_bytes(&game_data->party_3, &td->party_3, sizeof(struct gen3_party), 0, 0);
u32* party_buf = &td->party_3;
u32* party_buf = (u32*)&td->party_3;
for(int i = 0; i < (sizeof(struct gen3_party)>>2); i++)
checksum += party_buf[i];
@ -482,6 +505,130 @@ void prepare_gen3_trade_data(struct game_data_t* game_data, u32* buffer, u16* si
sizes[0] = sizeof(struct gen3_trade_data);
}
void read_gen12_trade_data(struct game_data_t* game_data, u32* buffer, u8 curr_gen, u8 is_jp) {
struct gen2_trade_data_int* td_int2 = (struct gen2_trade_data_int*) buffer;
struct gen2_trade_data_jp* td_jp2 = (struct gen2_trade_data_jp*) buffer;
struct gen1_trade_data_int* td_int1 = (struct gen1_trade_data_int*) buffer;
struct gen1_trade_data_jp* td_jp1 = (struct gen1_trade_data_jp*) buffer;
u8 names_size = STRING_GEN2_INT_SIZE;
u8* patch_target = (u8*)(&td_int2->trainer_info);
u8* patch_set = (u8*)td_int2->patch_set.patch_set;
int target_size = sizeof(struct trainer_data_gen2_int);
u8* trainer_name = (u8*)td_int2->trainer_info.trainer_name;
struct gen2_party_info* party_info2 = &td_int2->trainer_info.party_info;
struct gen1_party_info* party_info1 = &td_int1->trainer_info.party_info;
u8* ot_names = (u8*)td_int2->trainer_info.ot_names;
u8* nicknames = (u8*)td_int2->trainer_info.nicknames;
if(is_jp) {
names_size = STRING_GEN2_JP_SIZE;
if(curr_gen == 2) {
patch_target = (u8*)(&td_jp2->trainer_info);
patch_set = (u8*)td_jp2->patch_set.patch_set;
target_size = sizeof(struct trainer_data_gen2_jp);
trainer_name = (u8*)td_jp2->trainer_info.trainer_name;
party_info2 = &td_jp2->trainer_info.party_info;
ot_names = (u8*)td_jp2->trainer_info.ot_names;
nicknames = (u8*)td_jp2->trainer_info.nicknames;
}
}
if(curr_gen != 2) {
if(is_jp) {
patch_target = (u8*)(&td_jp1->trainer_info);
patch_set = (u8*)td_jp1->patch_set.patch_set;
target_size = sizeof(struct trainer_data_gen1_jp);
trainer_name = (u8*)td_jp1->trainer_info.trainer_name;
party_info1 = &td_jp1->trainer_info.party_info;
ot_names = (u8*)td_jp1->trainer_info.ot_names;
nicknames = (u8*)td_jp1->trainer_info.nicknames;
}
else {
patch_target = (u8*)(&td_int1->trainer_info);
patch_set = (u8*)td_int1->patch_set.patch_set;
target_size = sizeof(struct trainer_data_gen1_int);
trainer_name = (u8*)td_int1->trainer_info.trainer_name;
ot_names = (u8*)td_int1->trainer_info.ot_names;
nicknames = (u8*)td_int1->trainer_info.nicknames;
}
}
init_game_data(game_data);
game_data->game_identifier.game_is_jp = is_jp;
for(int i = 0; i < PARTY_SIZE; i++)
for(int j = 0; j < sizeof(struct mail_gen3); j++)
((u8*)(&game_data->mails_3[i]))[j] = 0;
for(int i = 0; i < sizeof(struct gen3_party); i++)
((u8*)(&game_data->party_3))[i] = 0;
copy_bytes((u8*)default_gift_ribbons_bin, game_data->giftRibbons, GIFT_RIBBONS, 0, 0);
game_data->trainer_gender = 0;
apply_patch_set(patch_target, patch_set, target_size-(names_size + MON_INDEX_SIZE), names_size + MON_INDEX_SIZE, PATCH_SET_SIZE, PATCH_SET_BASE_POS);
text_gen12_to_gen3(trainer_name, game_data->trainer_name, names_size, OT_NAME_GEN3_SIZE+1, is_jp, is_jp);
if(curr_gen == 2)
game_data->trainer_id = ((party_info2->trainer_id & 0xFF) << 8) | (party_info2->trainer_id >> 8);
if(curr_gen == 2)
game_data->party_3.total = party_info2->num_mons;
else
game_data->party_3.total = party_info1->num_mons;
if(game_data->party_3.total > PARTY_SIZE)
game_data->party_3.total = PARTY_SIZE;
u8 found = 0;
for(int i = 0; i < game_data->party_3.total; i++) {
game_data->party_3_undec[i].src = &game_data->party_3.mons[i];
if(curr_gen == 2)
gen2_to_gen3(&party_info2->mons_data[i], &game_data->party_3_undec[i], party_info2->mons_index[i], ot_names + (i*names_size), nicknames + (i*names_size), is_jp);
else
gen1_to_gen3(&party_info1->mons_data[i], &game_data->party_3_undec[i], party_info1->mons_index[i], ot_names + (i*names_size), nicknames + (i*names_size), is_jp);
process_gen3_data(&game_data->party_3.mons[i], &game_data->party_3_undec[i], game_data->game_identifier.game_main_version, game_data->game_identifier.game_sub_version);
if(game_data->party_3_undec[i].is_valid_gen3)
found = 1;
}
if (!found)
game_data->party_3.total = 0;
}
void read_gen3_trade_data(struct game_data_t* game_data, u32* buffer) {
struct gen3_trade_data* td = (struct gen3_trade_data*)buffer;
init_game_data(game_data);
for(int i = 0; i < PARTY_SIZE; i++)
copy_bytes(&td->mails_3[i], &game_data->mails_3[i], sizeof(struct mail_gen3), 0, 0);
copy_bytes(&td->party_3, &game_data->party_3, sizeof(struct gen3_party), 0, 0);
game_data->game_identifier.game_main_version = td->game_main_code;
game_data->game_identifier.game_sub_version = td->game_sub_code;
game_data->game_identifier.game_is_jp = td->game_is_jp;
copy_bytes(td->giftRibbons, game_data->giftRibbons, GIFT_RIBBONS, 0, 0);
copy_bytes(td->trainer_name, game_data->trainer_name, OT_NAME_GEN3_SIZE+1, 0, 0);
game_data->trainer_gender = td->trainer_gender;
game_data->trainer_id = td->trainer_id;
if(game_data->party_3.total > PARTY_SIZE)
game_data->party_3.total = PARTY_SIZE;
u8 found = 0;
for(int i = 0; i < game_data->party_3.total; i++) {
process_gen3_data(&game_data->party_3.mons[i], &game_data->party_3_undec[i], game_data->game_identifier.game_main_version, game_data->game_identifier.game_sub_version);
if(game_data->party_3_undec[i].is_valid_gen3)
found = 1;
}
if (!found)
game_data->party_3.total = 0;
}
void load_comm_buffer(struct game_data_t* game_data, int curr_gen, u8 is_jp) {
for(int i = 0; i < NUM_SIZES; i++)
@ -514,3 +661,18 @@ void load_comm_buffer(struct game_data_t* game_data, int curr_gen, u8 is_jp) {
#endif
prepare_number_of_sizes();
}
void read_comm_buffer(struct game_data_t* game_data, int curr_gen, u8 is_jp) {
switch(curr_gen) {
case 1:
read_gen12_trade_data(game_data, communication_buffers[OTHER_BUFFER], 1, is_jp);
break;
case 2:
read_gen12_trade_data(game_data, communication_buffers[OTHER_BUFFER], 2, is_jp);
break;
default:
read_gen3_trade_data(game_data, communication_buffers[OTHER_BUFFER]);
break;
}
}

View File

@ -145,6 +145,8 @@ struct gen3_trade_data {
} __attribute__ ((packed));
void load_comm_buffer(struct game_data_t*, int, u8);
void read_comm_buffer(struct game_data_t*, int, u8);
u8 are_checksum_same_gen3(struct gen3_trade_data*);
u32* get_communication_buffer(u8);
u8 get_number_of_buffers();