Skip to content

Commit

Permalink
FF7: Tutorial dialogs VA
Browse files Browse the repository at this point in the history
  • Loading branch information
julianxhokaxhiu committed Sep 17, 2023
1 parent ea7c70d commit c3c5d9d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Lighting: Fix Bahamut Zero and Supernova not displaying correctly when lighting enabled
- Lighting: Fix field shadows not displaying during FMV movies
- Renderer: Fix black color in some field maps (`spipe2` for example) ( https://github.com/julianxhokaxhiu/FFNx/pull/587 )
- Voice: Enable tutorial voice acting

## FF8

Expand Down
4 changes: 4 additions & 0 deletions src/ff7.h
Original file line number Diff line number Diff line change
Expand Up @@ -2690,6 +2690,9 @@ struct ff7_externals
void *(*menu_sub_6FAC38)(uint32_t,uint32_t,uint8_t,uint8_t,uint32_t);
BOOL (*write_save_file)(char);
uint32_t *menu_subs_call_table;
int (*menu_tutorial_sub_6C49FD)();
BYTE* menu_tutorial_window_state;
DWORD* menu_tutorial_window_text_ptr;
uint32_t status_menu_sub;
uint32_t draw_status_limit_level_stats;
uint32_t timer_menu_sub;
Expand Down Expand Up @@ -2827,6 +2830,7 @@ struct ff7_externals
uint32_t opcode_message;
uint32_t opcode_ask;
uint32_t opcode_wmode;
uint32_t opcode_tutor;
uint32_t *sfx_initialized;
uint32_t sfx_play_summon;
uint32_t sfx_load_and_play_with_speed;
Expand Down
5 changes: 5 additions & 0 deletions src/ff7_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,15 @@ void ff7_find_externals(struct ff7_game_obj* game_object)
ff7_externals.menu_start = get_absolute_value(main_loop, 0x627);
ff7_externals.menu_sub_6CB56A = get_relative_call(ff7_externals.menu_sub_6CDA83, 0xDE);
ff7_externals.menu_subs_call_table = (uint32_t *)get_absolute_value(ff7_externals.menu_sub_6CB56A, 0x2EC);
ff7_externals.menu_tutorial_sub_6C49FD = (int (*)())get_relative_call(ff7_externals.menu_sub_6CB56A, 0x2B7);
ff7_externals.timer_menu_sub = ff7_externals.menu_subs_call_table[0];
ff7_externals.status_menu_sub = ff7_externals.menu_subs_call_table[5];
ff7_externals.menu_sound_slider_loop = ff7_externals.menu_subs_call_table[8];
ff7_externals.menu_sub_6FEDB0 = ff7_externals.menu_subs_call_table[10];

ff7_externals.menu_tutorial_window_state = (BYTE*)get_absolute_value((uint32_t)ff7_externals.menu_tutorial_sub_6C49FD, 0x9);
ff7_externals.menu_tutorial_window_text_ptr = (DWORD*)get_absolute_value((uint32_t)ff7_externals.menu_tutorial_sub_6C49FD, 0x18);

switch(version)
{
case VERSION_FF7_102_US:
Expand Down Expand Up @@ -479,6 +483,7 @@ void ff7_find_externals(struct ff7_game_obj* game_object)
ff7_externals.field_global_object_ptr = (ff7_modules_global_object**)get_absolute_value(ff7_externals.field_init_event_60BACF, 0x1C);

common_externals.execute_opcode_table = (uint32_t*)get_absolute_value(ff7_externals.execute_opcode, 0x10D);
ff7_externals.opcode_tutor = common_externals.execute_opcode_table[0x21];
ff7_externals.opcode_goldu = common_externals.execute_opcode_table[0x39];
ff7_externals.opcode_dlitm = common_externals.execute_opcode_table[0x59];
ff7_externals.opcode_smtra = common_externals.execute_opcode_table[0x5B];
Expand Down
62 changes: 62 additions & 0 deletions src/voice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ int (*opcode_old_ask)(int);
int (*opcode_old_wmode)();
int (*opcode_wm_old_message)(uint8_t,uint8_t);
int (*opcode_wm_old_ask)(uint8_t,uint8_t,uint8_t,uint8_t,WORD*);
int (*opcode_old_tutor)();
void (*ff7_set_master_music_volume)(uint32_t);

// FF8
Expand Down Expand Up @@ -412,6 +413,15 @@ int opcode_voice_message()
return opcode_old_message();
}

int opcode_voice_tutor()
{
static const int window_id = 0;

current_opcode_message_status[window_id].message_dialog_id = get_field_parameter<byte>(0);

return opcode_old_tutor();
}

int opcode_voice_parse_options(uint8_t window_id, uint8_t dialog_id, uint8_t first_question_id, uint8_t last_question_id, WORD *current_question_id)
{
opcode_ask_current_option = *current_question_id;
Expand Down Expand Up @@ -840,6 +850,54 @@ void ff7_display_battle_action_text()
}
}

// -- MENU --

int ff7_menu_tutorial_render()
{
static const int window_id = 0;
int dialog_id = current_opcode_message_status[window_id].message_dialog_id;

byte message_current_opcode = *ff7_externals.menu_tutorial_window_state;

bool _is_dialog_opening = (current_opcode_message_status[window_id].message_last_opcode == 0 && message_current_opcode == 1);
bool _is_dialog_starting = (current_opcode_message_status[window_id].message_last_opcode == 1 && message_current_opcode == 2);
bool _is_dialog_closing = (current_opcode_message_status[window_id].message_last_opcode == 3 && message_current_opcode == 0);

if (_is_dialog_opening)
{
begin_voice(window_id);
current_opcode_message_status[window_id].message_dialog_id = dialog_id;
}
else if (_is_dialog_starting)
{
std::string decoded_text = decode_ff7_text((char*)*ff7_externals.menu_tutorial_window_text_ptr);
std::string tokenized_dialogue = tokenize_text(decoded_text);

if (trace_all || trace_opcodes) ffnx_trace("[TUTOR]: id=%d,text=%s\n", dialog_id, decoded_text.c_str());

char voice_file[MAX_PATH];
sprintf(voice_file, "_tutor/%04u/%s", dialog_id, tokenized_dialogue.c_str());
current_opcode_message_status[window_id].is_voice_acting = nxAudioEngine.playVoice(voice_file, 0, voice_volume);
}
else if (_is_dialog_closing)
{
end_voice(window_id);
simulate_OK_disabled[window_id] = false;
current_opcode_message_status[window_id].is_voice_acting = false;
}

// Auto close the message if it was voice acted and the audio file has finished playing
if (current_opcode_message_status[window_id].is_voice_acting && !nxAudioEngine.isVoicePlaying(window_id))
{
current_opcode_message_status[window_id].is_voice_acting = false;
if (!simulate_OK_disabled[window_id] && enable_voice_auto_text) (*ff7_externals.field_global_object_ptr)->field_80 |= 0x20;
}

current_opcode_message_status[window_id].message_last_opcode = message_current_opcode;

return ff7_externals.menu_tutorial_sub_6C49FD();
}

//=============================================================================

char* ff8_battle_get_monster_name(int idx)
Expand Down Expand Up @@ -1252,10 +1310,14 @@ void voice_init()
replace_call_function(ff7_externals.world_opcode_ask_sub_75EEBB + 0x3C, opcode_wm_ask);
replace_call_function(ff7_externals.world_sub_75EF46 + 0xAF, opcode_wm_ask);

opcode_old_tutor = (int (*)())ff7_externals.opcode_tutor;
patch_code_dword((uint32_t)&common_externals.execute_opcode_table[0x21], (DWORD)&opcode_voice_tutor);

replace_function(ff7_externals.add_text_to_display_queue, ff7_add_text_to_display_queue);
replace_function(ff7_externals.update_display_text_queue, ff7_update_display_text_queue);
replace_function(ff7_externals.display_battle_action_text_42782A, ff7_display_battle_action_text);
replace_call_function(ff7_externals.run_enemy_ai_script + 0xB7F, ff7_enqueue_script_display_string);
replace_call_function(ff7_externals.menu_sub_6CB56A + 0x2B7, ff7_menu_tutorial_render);
}
else
{
Expand Down

0 comments on commit c3c5d9d

Please sign in to comment.