fix new course/act name replacement system (#506)

* fix new course/act name replacement system

* check array bounds

* fix small oversight from an older pr

* whoops, forgot this
This commit is contained in:
Isaac0-dev 2023-11-08 09:04:08 +10:00 committed by Agent X
parent 960e80a58c
commit cece41f1a8
7 changed files with 38 additions and 48 deletions

View file

@ -2796,8 +2796,6 @@ void render_pause_castle_course_stars(s16 x, s16 y, s16 fileNum, s16 courseNum)
} }
void render_pause_castle_main_strings(s16 x, s16 y) { void render_pause_castle_main_strings(s16 x, s16 y) {
void **courseNameTbl = get_course_name_table();
#ifdef VERSION_EU #ifdef VERSION_EU
u8 textCoin[] = { TEXT_COIN }; u8 textCoin[] = { TEXT_COIN };
u8 textX[] = { TEXT_VARIABLE_X }; u8 textX[] = { TEXT_VARIABLE_X };
@ -2805,7 +2803,8 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
u8 textCoin[] = { TEXT_COIN_X }; u8 textCoin[] = { TEXT_COIN_X };
#endif #endif
void *courseName; u8 courseNum = gDialogLineNum + 1;
const u8 *courseName = get_level_name_sm64(courseNum, courseNum < COURSE_COUNT ? gCourseNumToLevelNumTable[courseNum] : LEVEL_NONE, 1, 1);
u8 strVal[8]; u8 strVal[8];
s16 starNum = gDialogLineNum; s16 starNum = gDialogLineNum;
@ -2839,7 +2838,6 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
if (gDialogLineNum < COURSE_STAGES_COUNT) { if (gDialogLineNum < COURSE_STAGES_COUNT) {
courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]);
render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum); render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum);
print_generic_string(x + 34, y - 5, textCoin); print_generic_string(x + 34, y - 5, textCoin);
#ifdef VERSION_EU #ifdef VERSION_EU
@ -2852,7 +2850,6 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
#endif #endif
} else { } else {
u8 textStarX[] = { TEXT_STAR_X }; u8 textStarX[] = { TEXT_STAR_X };
courseName = segmented_to_virtual(courseNameTbl[COURSE_MAX]);
print_generic_string(x + 40, y + 13, textStarX); print_generic_string(x + 40, y + 13, textStarX);
int_to_str(save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_BONUS_STAGES - 1, COURSE_MAX - 1), strVal); int_to_str(save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_BONUS_STAGES - 1, COURSE_MAX - 1), strVal);
print_generic_string(x + 60, y + 13, strVal); print_generic_string(x + 60, y + 13, strVal);
@ -3002,11 +2999,10 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) {
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
void **courseNameTbl = get_course_name_table(); const u8 *courseName = get_level_name_sm64(gDialogLineNum, gDialogLineNum < COURSE_COUNT ? gCourseNumToLevelNumTable[gDialogLineNum] : LEVEL_NONE, 1, 1);
// Main courses (0-14) // Main courses (0-14)
if (gDialogLineNum < COURSE_STAGES_COUNT) { if (gDialogLineNum < COURSE_STAGES_COUNT) {
const u8 *courseName = courseNameTbl[gDialogLineNum];
const u8 textCoin[] = { TEXT_COIN_X }; const u8 textCoin[] = { TEXT_COIN_X };
u8 textCoinCount[8]; u8 textCoinCount[8];
render_pause_castle_course_name(courseName, 160, y + 30); render_pause_castle_course_name(courseName, 160, y + 30);
@ -3018,14 +3014,12 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) {
// Secret courses (15-24) // Secret courses (15-24)
else if (gDialogLineNum >= COURSE_STAGES_COUNT && gDialogLineNum < INDEX_CASTLE_STARS) { else if (gDialogLineNum >= COURSE_STAGES_COUNT && gDialogLineNum < INDEX_CASTLE_STARS) {
const u8 *courseName = courseNameTbl[gDialogLineNum];
render_pause_castle_course_name(courseName + 3, 160, y + 30); render_pause_castle_course_name(courseName + 3, 160, y + 30);
render_pause_castle_course_stars_extended(x + 20, y); render_pause_castle_course_stars_extended(x + 20, y);
} }
// Castle stars (25) // Castle stars (25)
else if (gDialogLineNum == INDEX_CASTLE_STARS) { else if (gDialogLineNum == INDEX_CASTLE_STARS) {
const u8 *courseName = courseNameTbl[COURSE_MAX];
const u8 textStar[] = { TEXT_STAR_X }; const u8 textStar[] = { TEXT_STAR_X };
u8 textStarCount[8]; u8 textStarCount[8];
render_pause_castle_course_name(courseName + 3, 160, y + 30); render_pause_castle_course_name(courseName + 3, 160, y + 30);
@ -3310,9 +3304,6 @@ void render_course_complete_lvl_info_and_hud_str(void) {
UNUSED u8 textClear[] = { TEXT_CLEAR }; UNUSED u8 textClear[] = { TEXT_CLEAR };
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
#endif #endif
void **actNameTbl = get_act_name_table();
void **courseNameTbl = get_course_name_table();
u8 *name; u8 *name;
u8 strCourseNum[4]; u8 strCourseNum[4];
@ -3321,11 +3312,7 @@ void render_course_complete_lvl_info_and_hud_str(void) {
print_hud_course_complete_coins(118, 103); print_hud_course_complete_coins(118, 103);
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1)); play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
if (gLastCompletedStarNum == 7) { name = (u8*) get_star_name_sm64(gLastCompletedCourseNum, gLastCompletedStarNum, 1);
name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6 + 1]);
} else {
name = segmented_to_virtual(actNameTbl[(gLastCompletedCourseNum - 1) * 6 + gLastCompletedStarNum - 1]);
}
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
int_to_str(gLastCompletedCourseNum, strCourseNum); int_to_str(gLastCompletedCourseNum, strCourseNum);
@ -3337,7 +3324,7 @@ void render_course_complete_lvl_info_and_hud_str(void) {
print_generic_string(CRS_NUM_X3, 167, strCourseNum); print_generic_string(CRS_NUM_X3, 167, strCourseNum);
gSPDisplayList(gDisplayListHead++, dl_ia_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
} else if ((gLastCompletedCourseNum == COURSE_BITDW || gLastCompletedCourseNum == COURSE_BITFS) && gLastCollectedStarOrKey == 1) { } else if ((gLastCompletedCourseNum == COURSE_BITDW || gLastCompletedCourseNum == COURSE_BITFS) && gLastCollectedStarOrKey == 1) {
name = segmented_to_virtual(courseNameTbl[gLastCompletedCourseNum - 1]); name = (u8*) get_level_name_sm64(gLastCompletedCourseNum, gCurrLevelNum, gCurrAreaIndex, 1) + 3;
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
#ifdef VERSION_EU #ifdef VERSION_EU
@ -3358,7 +3345,7 @@ void render_course_complete_lvl_info_and_hud_str(void) {
play_star_fanfare_and_flash_hud(2, 0); //! 2 isn't defined, originally for key hud? play_star_fanfare_and_flash_hud(2, 0); //! 2 isn't defined, originally for key hud?
return; return;
} else { } else {
name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6]); name = (u8*) get_star_name_sm64(gLastCompletedCourseNum, gLastCompletedStarNum, 1);
print_hud_course_complete_coins(118, 103); print_hud_course_complete_coins(118, 103);
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1)); play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
} }

View file

@ -202,12 +202,12 @@ const char *get_level_name_ascii(s16 courseNum, s16 levelNum, s16 areaIndex, s16
} }
} }
if (gReplacedActNameTable[courseNum]->modIndex != -1) { if (courseNum >= 0 && courseNum <= COURSE_MAX && gReplacedActNameTable[courseNum]->modIndex != -1) {
snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->name); snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->name);
} }
else if (!hasCustomName) { else if (!hasCustomName) {
if (COURSE_IS_VALID_COURSE(courseNum)) { if (COURSE_IS_MAIN_COURSE(courseNum)) {
void **courseNameTbl = get_course_name_table(); void **courseNameTbl = get_course_name_table();
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]); const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]);
convert_string_sm64_to_ascii(output, courseName + 3); convert_string_sm64_to_ascii(output, courseName + 3);
@ -261,7 +261,9 @@ const char *get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex) {
const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) { const char *get_star_name_ascii(s16 courseNum, s16 starNum, s16 charCase) {
static char output[256]; static char output[256];
if (gReplacedActNameTable[courseNum]->actName && gReplacedActNameTable[courseNum]->actName[starNum - 1].isModified) { if (starNum >= 0 && starNum <= 6 &&
courseNum >= 0 && courseNum <= COURSE_MAX &&
gReplacedActNameTable[courseNum]->actName && gReplacedActNameTable[courseNum]->actName[starNum - 1].isModified) {
snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->actName[starNum - 1].name); snprintf(output, 256, "%s", gReplacedActNameTable[courseNum]->actName[starNum - 1].name);
} }

View file

@ -54,6 +54,14 @@ s8 gLevelToCourseNumTable[] = {
#undef STUB_LEVEL #undef STUB_LEVEL
#undef DEFINE_LEVEL #undef DEFINE_LEVEL
#define STUB_LEVEL(_0, levelenum, _2, _3, _4, _5, _6, _7, _8) levelenum,
#define DEFINE_LEVEL(_0, levelenum, _2, _3, _4, _5, _6, _7, _8, _9, _10) levelenum,
s8 gCourseNumToLevelNumTable[] = {
#include "levels/level_defines.h"
};
#undef STUB_LEVEL
#undef DEFINE_LEVEL
STATIC_ASSERT(ARRAY_COUNT(gLevelToCourseNumTable) == LEVEL_COUNT - 1, STATIC_ASSERT(ARRAY_COUNT(gLevelToCourseNumTable) == LEVEL_COUNT - 1,
"change this array if you are adding levels"); "change this array if you are adding levels");

View file

@ -80,6 +80,7 @@ extern s8 sUnusedGotGlobalCoinHiScore;
extern u8 gGotFileCoinHiScore; extern u8 gGotFileCoinHiScore;
extern u8 gCurrCourseStarFlags; extern u8 gCurrCourseStarFlags;
extern s8 gLevelToCourseNumTable[]; extern s8 gLevelToCourseNumTable[];
extern s8 gCourseNumToLevelNumTable[];
// game progress flags // game progress flags
#define SAVE_FLAG_FILE_EXISTS /* 0x00000001 */ (1 << 0) #define SAVE_FLAG_FILE_EXISTS /* 0x00000001 */ (1 << 0)

View file

@ -280,10 +280,8 @@ void print_act_selector_strings(void) {
#endif #endif
unsigned char starNumbers[] = { TEXT_ZERO }; unsigned char starNumbers[] = { TEXT_ZERO };
u8 **levelNameTbl = get_course_name_table(); const u8 *currLevelName = get_level_name_sm64(gCurrCourseNum, gCurrLevelNum, gCurrAreaIndex, 1);
u8 *currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]); const u8 *selectedActName = get_star_name_sm64(gCurrCourseNum, sSelectedActIndex + 1, 1);
u8 **actNameTbl = get_act_name_table();
u8 *selectedActName;
#ifndef VERSION_EU #ifndef VERSION_EU
s16 lvlNameX; s16 lvlNameX;
s16 actNameX; s16 actNameX;
@ -314,9 +312,9 @@ void print_act_selector_strings(void) {
if (currLevelName != NULL) { if (currLevelName != NULL) {
#ifdef VERSION_EU #ifdef VERSION_EU
print_generic_string(get_str_x_pos_from_center(160, currLevelName + 3, 10.0f), 33, currLevelName + 3); print_generic_string(get_str_x_pos_from_center(160, (u8*) currLevelName + 3, 10.0f), 33, currLevelName + 3);
#else #else
lvlNameX = get_str_x_pos_from_center(160, currLevelName + 3, 10.0f); lvlNameX = get_str_x_pos_from_center(160, (u8*) currLevelName + 3, 10.0f);
print_generic_string(lvlNameX, 33, currLevelName + 3); print_generic_string(lvlNameX, 33, currLevelName + 3);
#endif #endif
} }
@ -333,12 +331,10 @@ void print_act_selector_strings(void) {
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
// Print the name of the selected act. // Print the name of the selected act.
if (sVisibleStars != 0) { if (sVisibleStars != 0) {
selectedActName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + sSelectedActIndex]);
#ifdef VERSION_EU #ifdef VERSION_EU
print_menu_generic_string(get_str_x_pos_from_center(ACT_NAME_X, selectedActName, 8.0f), 81, selectedActName); print_menu_generic_string(get_str_x_pos_from_center(ACT_NAME_X, (u8*) selectedActName, 8.0f), 81, selectedActName);
#else #else
actNameX = get_str_x_pos_from_center(ACT_NAME_X, selectedActName, 8.0f); actNameX = get_str_x_pos_from_center(ACT_NAME_X, (u8*) selectedActName, 8.0f);
print_menu_generic_string(actNameX, 81, selectedActName); print_menu_generic_string(actNameX, 81, selectedActName);
#endif #endif
} }

View file

@ -24,7 +24,7 @@ static bool sReplacedActName[(COURSE_RR+2)*6] = { 0 };
void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64); void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64);
struct CourseName *gReplacedActNameTable[COURSE_COUNT]; struct CourseName *gReplacedActNameTable[COURSE_END];
// Save all vanilla act names and course names // Save all vanilla act names and course names
AT_STARTUP static void smlua_text_utils_init() { AT_STARTUP static void smlua_text_utils_init() {
@ -33,7 +33,7 @@ AT_STARTUP static void smlua_text_utils_init() {
char courseBuffer[50]; char courseBuffer[50];
char actBuffer[50]; char actBuffer[50];
for (s16 courseNum = 0; courseNum < COURSE_COUNT; courseNum++) { for (s16 courseNum = 0; courseNum < COURSE_END; courseNum++) {
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum]); const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum]);
convert_string_sm64_to_ascii(courseBuffer, courseName); convert_string_sm64_to_ascii(courseBuffer, courseName);
gReplacedActNameTable[courseNum] = malloc(sizeof(struct CourseName)); gReplacedActNameTable[courseNum] = malloc(sizeof(struct CourseName));
@ -179,24 +179,22 @@ void smlua_text_utils_dialog_replace(enum DialogId dialogId, UNUSED u32 unused,
sReplacedDialog[dialogId] = true; sReplacedDialog[dialogId] = true;
} }
#define REPLACE_ACT_NAME(i) \
snprintf(courseActNames->actName[i-1].name, 256, "%s", act##i); \
courseActNames->actName[i-1].isModified = true; \
void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6) { void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6) {
if (courseNum <= 0 || courseNum > COURSE_RR) { return; } if (courseNum <= 0 || courseNum > COURSE_RR) { return; }
struct CourseName* courseActNames = gReplacedActNameTable[courseNum]; struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
snprintf(courseActNames->name, 256, "%s", courseName + 3); snprintf(courseActNames->name, 256, "%s", courseName + 3);
courseActNames->modIndex = gLuaActiveMod->index; courseActNames->modIndex = gLuaActiveMod->index;
#define REPLACE_ACT_NAME(i) \
snprintf(courseActNames->actName[i-1].name, 256, "%s", act##i); \
courseActNames->actName[i-1].isModified = true; \
REPLACE_ACT_NAME(1); REPLACE_ACT_NAME(1);
REPLACE_ACT_NAME(2); REPLACE_ACT_NAME(2);
REPLACE_ACT_NAME(3); REPLACE_ACT_NAME(3);
REPLACE_ACT_NAME(4); REPLACE_ACT_NAME(4);
REPLACE_ACT_NAME(5); REPLACE_ACT_NAME(5);
REPLACE_ACT_NAME(6); REPLACE_ACT_NAME(6);
LOG_INFO("%d (%s) replacing act names 1-6 of course %d, (%s), act 1: %s", courseActNames->modIndex, gLuaActiveMod->name, courseNum, courseName, act1);
} }
void smlua_text_utils_course_name_replace(s16 courseNum, const char* name) { void smlua_text_utils_course_name_replace(s16 courseNum, const char* name) {

View file

@ -200,6 +200,11 @@ void produce_interpolation_frames_and_delay(void) {
} }
inline static void buffer_audio(void) { inline static void buffer_audio(void) {
const f32 master_mod = (f32)configMasterVolume / 127.0f;
set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * master_mod);
set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * master_mod);
set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * master_mod);
int samples_left = audio_api->buffered(); int samples_left = audio_api->buffered();
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW; u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_HIGH * 2 * 2]; s16 audio_buffer[SAMPLES_HIGH * 2 * 2];
@ -214,17 +219,10 @@ void produce_one_frame(void) {
CTX_EXTENT(CTX_INTERP, patch_interpolations_before); CTX_EXTENT(CTX_INTERP, patch_interpolations_before);
const f32 master_mod = (f32)configMasterVolume / 127.0f;
set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * master_mod);
set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * master_mod);
set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * master_mod);
CTX_EXTENT(CTX_GAME_LOOP, game_loop_one_iteration); CTX_EXTENT(CTX_GAME_LOOP, game_loop_one_iteration);
CTX_EXTENT(CTX_SMLUA, smlua_update); CTX_EXTENT(CTX_SMLUA, smlua_update);
thread6_rumble_loop(NULL);
CTX_EXTENT(CTX_AUDIO, buffer_audio); CTX_EXTENT(CTX_AUDIO, buffer_audio);
CTX_EXTENT(CTX_RENDER, produce_interpolation_frames_and_delay); CTX_EXTENT(CTX_RENDER, produce_interpolation_frames_and_delay);