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 GitHub
parent fce6182c50
commit 2df9c80782
7 changed files with 38 additions and 48 deletions

View File

@ -2807,8 +2807,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 **courseNameTbl = get_course_name_table();
#ifdef VERSION_EU
u8 textCoin[] = { TEXT_COIN };
u8 textX[] = { TEXT_VARIABLE_X };
@ -2816,7 +2814,8 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
u8 textCoin[] = { TEXT_COIN_X };
#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];
s16 starNum = gDialogLineNum;
@ -2850,7 +2849,6 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
if (gDialogLineNum < COURSE_STAGES_COUNT) {
courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]);
render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gDialogLineNum);
print_generic_string(x + 34, y - 5, textCoin);
#ifdef VERSION_EU
@ -2863,7 +2861,6 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
#endif
} else {
u8 textStarX[] = { TEXT_STAR_X };
courseName = segmented_to_virtual(courseNameTbl[COURSE_MAX]);
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);
print_generic_string(x + 60, y + 13, strVal);
@ -3013,11 +3010,10 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) {
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
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)
if (gDialogLineNum < COURSE_STAGES_COUNT) {
const u8 *courseName = courseNameTbl[gDialogLineNum];
const u8 textCoin[] = { TEXT_COIN_X };
u8 textCoinCount[8];
render_pause_castle_course_name(courseName, 160, y + 30);
@ -3029,14 +3025,12 @@ void render_pause_castle_main_strings_extended(s16 x, s16 y) {
// Secret courses (15-24)
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_stars_extended(x + 20, y);
}
// Castle stars (25)
else if (gDialogLineNum == INDEX_CASTLE_STARS) {
const u8 *courseName = courseNameTbl[COURSE_MAX];
const u8 textStar[] = { TEXT_STAR_X };
u8 textStarCount[8];
render_pause_castle_course_name(courseName + 3, 160, y + 30);
@ -3313,9 +3307,6 @@ void render_course_complete_lvl_info_and_hud_str(void) {
UNUSED u8 textClear[] = { TEXT_CLEAR };
u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE };
#endif
void **actNameTbl = get_act_name_table();
void **courseNameTbl = get_course_name_table();
u8 *name;
u8 strCourseNum[4];
@ -3324,11 +3315,7 @@ void render_course_complete_lvl_info_and_hud_str(void) {
print_hud_course_complete_coins(118, 103);
play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1));
if (gLastCompletedStarNum == 7) {
name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6 + 1]);
} else {
name = segmented_to_virtual(actNameTbl[(gLastCompletedCourseNum - 1) * 6 + gLastCompletedStarNum - 1]);
}
name = (u8*) get_star_name_sm64(gLastCompletedCourseNum, gLastCompletedStarNum, 1);
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
int_to_str(gLastCompletedCourseNum, strCourseNum);
@ -3340,7 +3327,7 @@ void render_course_complete_lvl_info_and_hud_str(void) {
print_generic_string(CRS_NUM_X3, 167, strCourseNum);
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
} 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);
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha);
#ifdef VERSION_EU
@ -3361,7 +3348,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?
return;
} 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);
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);
}
else if (!hasCustomName) {
if (COURSE_IS_VALID_COURSE(courseNum)) {
if (COURSE_IS_MAIN_COURSE(courseNum)) {
void **courseNameTbl = get_course_name_table();
const u8 *courseName = segmented_to_virtual(courseNameTbl[courseNum - COURSE_BOB]);
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) {
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);
}

View File

@ -54,6 +54,14 @@ s8 gLevelToCourseNumTable[] = {
#undef STUB_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,
"change this array if you are adding levels");

View File

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

View File

@ -279,10 +279,8 @@ void print_act_selector_strings(void) {
#endif
unsigned char starNumbers[] = { TEXT_ZERO };
u8 **levelNameTbl = get_course_name_table();
u8 *currLevelName = segmented_to_virtual(levelNameTbl[gCurrCourseNum - 1]);
u8 **actNameTbl = get_act_name_table();
u8 *selectedActName;
const u8 *currLevelName = get_level_name_sm64(gCurrCourseNum, gCurrLevelNum, gCurrAreaIndex, 1);
const u8 *selectedActName = get_star_name_sm64(gCurrCourseNum, sSelectedActIndex + 1, 1);
#ifndef VERSION_EU
s16 lvlNameX;
s16 actNameX;
@ -313,9 +311,9 @@ void print_act_selector_strings(void) {
if (currLevelName != NULL) {
#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
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);
#endif
}
@ -332,12 +330,10 @@ void print_act_selector_strings(void) {
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
// Print the name of the selected act.
if (sVisibleStars != 0) {
selectedActName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + sSelectedActIndex]);
#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
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);
#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);
struct CourseName *gReplacedActNameTable[COURSE_COUNT];
struct CourseName *gReplacedActNameTable[COURSE_END];
// Save all vanilla act names and course names
AT_STARTUP static void smlua_text_utils_init() {
@ -33,7 +33,7 @@ AT_STARTUP static void smlua_text_utils_init() {
char courseBuffer[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]);
convert_string_sm64_to_ascii(courseBuffer, 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;
}
#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) {
if (courseNum <= 0 || courseNum > COURSE_RR) { return; }
struct CourseName* courseActNames = gReplacedActNameTable[courseNum];
snprintf(courseActNames->name, 256, "%s", courseName + 3);
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(2);
REPLACE_ACT_NAME(3);
REPLACE_ACT_NAME(4);
REPLACE_ACT_NAME(5);
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) {

View File

@ -198,6 +198,11 @@ void produce_interpolation_frames_and_delay(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();
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_HIGH * 2 * 2];
@ -212,17 +217,10 @@ void produce_one_frame(void) {
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_SMLUA, smlua_update);
thread6_rumble_loop(NULL);
CTX_EXTENT(CTX_AUDIO, buffer_audio);
CTX_EXTENT(CTX_RENDER, produce_interpolation_frames_and_delay);
@ -297,7 +295,7 @@ void* main_game_init(UNUSED void* arg) {
snprintf(configPlayerName, MAX_PLAYER_STRING, "%s", gCLIOpts.PlayerName);
printf("\nCustom Playername (Start-Parameter): %s\n\n", configPlayerName);
}
if (!gGfxInited) {
gfx_init(&WAPI, &RAPI, TITLE);
WAPI.set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input);