Skip to content

Commit

Permalink
FF7: Rework the custom eye replacement
Browse files Browse the repository at this point in the history
Make the whole approach more solid. Additionally introduce a reset state when index 0 is picked.

Related #589
  • Loading branch information
julianxhokaxhiu committed Dec 16, 2023
1 parent 1cc8580 commit eb17bd2
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 47 deletions.
14 changes: 8 additions & 6 deletions src/ff7.h
Original file line number Diff line number Diff line change
Expand Up @@ -2242,10 +2242,10 @@ struct field_arrow_graphics_data

struct field_model_blink_data
{
byte blink_mode;
byte blink_mode_2;
char unknown;
char model_id;
byte blink_left_eye_mode;
byte blink_right_eye_mode;
char unknown;
char model_id;
};

struct world_event_data
Expand Down Expand Up @@ -2651,9 +2651,9 @@ struct ff7_model_eye_texture_data
{
int has_eyes;
char *custom_left_eye_filename;
const char *static_left_eye_filename;
char *static_left_eye_filename;
char *custom_right_eye_filename;
const char *static_right_eye_filename;
char *static_right_eye_filename;
};


Expand Down Expand Up @@ -2754,6 +2754,7 @@ struct ff7_externals
uint32_t field_models_eye_to_model;
ff7_model_eye_texture_data* field_models_eye_blink_buffer;
int (*field_load_model_eye_tex)(ff7_model_eye_texture_data *eye_data, field_animation_data *anim_data);
void (*field_unload_model_eye_tex)(void* eye_tex);
uint32_t field_sub_60DCED;
void (*destroy_animation)(struct anim_header *);
uint32_t context_chdir;
Expand Down Expand Up @@ -2966,6 +2967,7 @@ struct ff7_externals
void (*field_evaluate_encounter_rate_60B2C6)();
uint32_t field_animate_3d_models_6392BB;
uint32_t field_apply_kawai_op_64A070;
field_model_blink_data* field_model_blink_data_D000C8;
void (*field_blink_3d_model_649B50)(field_animation_data*, field_model_blink_data*);
short *field_player_model_id;
WORD *field_n_models;
Expand Down
2 changes: 1 addition & 1 deletion src/ff7/field/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ namespace ff7::field
void ff7_field_blink_3d_model(field_animation_data* anim_data, field_model_blink_data* blink_data)
{
ff7_externals.field_blink_3d_model_649B50(anim_data, blink_data);
if(blink_data->blink_mode == 2)
if(blink_data->blink_left_eye_mode == 2)
{
auto &field_event_data = (*ff7_externals.field_event_data_ptr)[blink_data->model_id];
if(external_model_data[blink_data->model_id].blinkFrameIndex > 0)
Expand Down
2 changes: 2 additions & 0 deletions src/ff7_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ void ff7_find_externals(struct ff7_game_obj* game_object)
ff7_externals.field_models_eye_to_model = get_relative_call(ff7_externals.field_load_models, 0xA79);
ff7_externals.field_load_animation = get_relative_call(ff7_externals.field_load_models, 0x8DF);
ff7_externals.field_load_model_eye_tex = (int (*)(ff7_model_eye_texture_data*,field_animation_data*))get_relative_call(ff7_externals.field_load_models, 0xB90);
ff7_externals.field_unload_model_eye_tex = (void (*)(void*))get_relative_call((uint32_t)ff7_externals.field_load_model_eye_tex, 0x1DE);
ff7_externals.load_animation = get_relative_call(ff7_externals.field_load_animation, 0x16D);
ff7_externals.destroy_animation = (void (*)(anim_header*))get_relative_call(ff7_externals.load_animation, 0x162);

Expand Down Expand Up @@ -566,6 +567,7 @@ void ff7_find_externals(struct ff7_game_obj* game_object)
ff7_externals.field_evaluate_encounter_rate_60B2C6 = (void (*)())get_relative_call(ff7_externals.field_update_models_positions, 0x90F);
ff7_externals.field_animate_3d_models_6392BB = get_relative_call(field_main_loop, 0xF6);
ff7_externals.field_blink_3d_model_649B50 = (void(*)(field_animation_data*, field_model_blink_data*))get_relative_call(ff7_externals.field_animate_3d_models_6392BB, 0x8A7);
ff7_externals.field_model_blink_data_D000C8 = (field_model_blink_data*)get_absolute_value(ff7_externals.field_animate_3d_models_6392BB, 0x7E6);
ff7_externals.field_apply_kawai_op_64A070 = get_relative_call(ff7_externals.field_animate_3d_models_6392BB, 0x726);
ff7_externals.field_player_model_id = (short*)get_absolute_value(ff7_externals.field_update_models_positions, 0x45D);
ff7_externals.field_n_models = (WORD*)get_absolute_value(ff7_externals.field_update_models_positions, 0x25);
Expand Down
100 changes: 60 additions & 40 deletions src/field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ bool map_changing = false;
int (*opcode_old_kawai)();
int (*opcode_old_pc)();

ff7_model_eye_texture_data ff7_eyes[9];

byte get_field_bank_value(int16_t bank)
{
switch(bank)
Expand Down Expand Up @@ -85,56 +87,51 @@ int opcode_kawai_eye_texture() {
char ext[4];

// LEFT EYE
if (ff7_externals.field_models_eye_blink_buffer[eye_index].custom_left_eye_filename)
_splitpath(ff7_eyes[eye_index].static_left_eye_filename, NULL, NULL, filename, ext);
_snprintf(directpath, sizeof(directpath), "%s/%s/flevel/%s_%d.TEX", basedir, direct_mode_path.c_str(), filename, left_eye_index);
memset(ff7_externals.field_models_eye_blink_buffer[eye_index].static_left_eye_filename, 0, 1024);
if (fileExists(directpath))
_snprintf(ff7_externals.field_models_eye_blink_buffer[eye_index].static_left_eye_filename, 1024, "%s_%d%s", filename, left_eye_index, ext);
else if (trace_all || trace_direct || trace_opcodes)
{
external_free(ff7_externals.field_models_eye_blink_buffer[eye_index].custom_left_eye_filename);
ff7_externals.field_models_eye_blink_buffer[eye_index].custom_left_eye_filename = NULL;
}

if(animation_data[curr_model_id].static_left_eye_tex) external_free(animation_data[curr_model_id].static_left_eye_tex);
if(animation_data[curr_model_id].custom_left_eye_tex) external_free(animation_data[curr_model_id].custom_left_eye_tex);

if (left_eye_index > 0)
{
_splitpath(ff7_externals.field_models_eye_blink_buffer[eye_index].static_left_eye_filename, NULL, NULL, filename, ext);
_snprintf(directpath, sizeof(directpath), "%s/%s/flevel/%s_%d.TEX", basedir, direct_mode_path.c_str(), filename, left_eye_index);

if (fileExists(directpath))
{
char* ret = (char*)external_malloc(1024);
_snprintf(ret, 1024, "%s_%d%s", filename, left_eye_index, ext);
ff7_externals.field_models_eye_blink_buffer[eye_index].custom_left_eye_filename = ret;
}
else if (trace_all || trace_direct || trace_opcodes)
ffnx_trace("opcode[KAWAI]: Custom left eye texture not found: %s\n", directpath);
if (left_eye_index > 2) ffnx_trace("opcode[KAWAI]: Custom left eye texture not found: %s\n", directpath);
_snprintf(ff7_externals.field_models_eye_blink_buffer[eye_index].static_left_eye_filename, 1024, "%s%s", filename, ext);
}

// RIGHT EYE
if (ff7_externals.field_models_eye_blink_buffer[eye_index].custom_right_eye_filename)
_splitpath(ff7_eyes[eye_index].static_right_eye_filename, NULL, NULL, filename, ext);
_snprintf(directpath, sizeof(directpath), "%s/%s/flevel/%s_%d.TEX", basedir, direct_mode_path.c_str(), filename, right_eye_index);
memset(ff7_externals.field_models_eye_blink_buffer[eye_index].static_right_eye_filename, 0, 1024);
if (fileExists(directpath))
_snprintf(ff7_externals.field_models_eye_blink_buffer[eye_index].static_right_eye_filename, 1024, "%s_%d%s", filename, right_eye_index, ext);
else if (trace_all || trace_direct || trace_opcodes)
{
external_free(ff7_externals.field_models_eye_blink_buffer[eye_index].custom_right_eye_filename);
ff7_externals.field_models_eye_blink_buffer[eye_index].custom_right_eye_filename = NULL;
if (right_eye_index > 2) ffnx_trace("opcode[KAWAI]: Custom right eye texture not found: %s\n", directpath);
_snprintf(ff7_externals.field_models_eye_blink_buffer[eye_index].static_right_eye_filename, 1024, "%s%s", filename, ext);
}

if(animation_data[curr_model_id].static_right_eye_tex) external_free(animation_data[curr_model_id].static_right_eye_tex);
if(animation_data[curr_model_id].custom_right_eye_tex) external_free(animation_data[curr_model_id].custom_right_eye_tex);
// Reload TEX data in memory
if(animation_data[curr_model_id].static_left_eye_tex) ff7_externals.field_unload_model_eye_tex(animation_data[curr_model_id].static_left_eye_tex);
if(animation_data[curr_model_id].static_right_eye_tex) ff7_externals.field_unload_model_eye_tex(animation_data[curr_model_id].static_right_eye_tex);
ff7_externals.field_load_model_eye_tex(&ff7_externals.field_models_eye_blink_buffer[eye_index], &animation_data[curr_model_id]);

if (right_eye_index > 0)
// Index is also treated as blink mode, if higher than 2 then "fake a closed eyes" in order to reload textures
if (left_eye_index > 2 || right_eye_index > 2)
{
_splitpath(ff7_externals.field_models_eye_blink_buffer[eye_index].static_right_eye_filename, NULL, NULL, filename, ext);
_snprintf(directpath, sizeof(directpath), "%s/%s/flevel/%s_%d.TEX", basedir, direct_mode_path.c_str(), filename, right_eye_index);

if (fileExists(directpath))
{
char* ret = (char*)external_malloc(1024);
_snprintf(ret, 1024, "%s_%d%s", filename, right_eye_index, ext);
ff7_externals.field_models_eye_blink_buffer[eye_index].custom_right_eye_filename = ret;
}
else if (trace_all || trace_direct || trace_opcodes)
ffnx_trace("opcode[KAWAI]: Custom right eye texture not found: %s\n", directpath);
ff7_externals.field_model_blink_data_D000C8->blink_left_eye_mode = 2;
ff7_externals.field_model_blink_data_D000C8->blink_right_eye_mode = 2;
ff7_externals.field_model_blink_data_D000C8->unknown = 0;
ff7_externals.field_model_blink_data_D000C8->model_id = curr_model_id;
ff7_externals.field_blink_3d_model_649B50(&animation_data[curr_model_id], ff7_externals.field_model_blink_data_D000C8);
}
else if (left_eye_index == 0 || right_eye_index == 0)
{
ff7_externals.field_model_blink_data_D000C8->blink_left_eye_mode = 0;
ff7_externals.field_model_blink_data_D000C8->blink_right_eye_mode = 0;
ff7_externals.field_model_blink_data_D000C8->unknown = 0;
ff7_externals.field_model_blink_data_D000C8->model_id = curr_model_id;
ff7_externals.field_blink_3d_model_649B50(&animation_data[curr_model_id], ff7_externals.field_model_blink_data_D000C8);
}

ff7_externals.field_load_model_eye_tex(&ff7_externals.field_models_eye_blink_buffer[eye_index], &animation_data[curr_model_id]);
}
}

Expand Down Expand Up @@ -179,6 +176,29 @@ void field_init()

// Proxy the window calculation formula so we can offset windows vertically
replace_call_function(common_externals.execute_opcode_table[0x50] + 0x174, field_calc_window_pos);

// ################################
// save static eyes names for later
// ################################
for(int i = 0; i < 9; i++)
{
if (ff7_externals.field_models_eye_blink_buffer[i].has_eyes)
{
if (ff7_externals.field_models_eye_blink_buffer[i].static_left_eye_filename)
{
ff7_eyes[i].static_left_eye_filename = ff7_externals.field_models_eye_blink_buffer[i].static_left_eye_filename;
ff7_externals.field_models_eye_blink_buffer[i].static_left_eye_filename = (char*)external_malloc(1024);
strcpy(ff7_externals.field_models_eye_blink_buffer[i].static_left_eye_filename, ff7_eyes[i].static_left_eye_filename);
}

if (ff7_externals.field_models_eye_blink_buffer[i].static_right_eye_filename)
{
ff7_eyes[i].static_right_eye_filename = ff7_externals.field_models_eye_blink_buffer[i].static_right_eye_filename;
ff7_externals.field_models_eye_blink_buffer[i].static_right_eye_filename = (char*)external_malloc(1024);
strcpy(ff7_externals.field_models_eye_blink_buffer[i].static_right_eye_filename, ff7_eyes[i].static_right_eye_filename);
}
}
}
}
}

Expand Down

0 comments on commit eb17bd2

Please sign in to comment.