Merge pull request #3 from LeazeDev/pb-system

Pb system
This commit is contained in:
Leaze 2023-03-11 17:11:52 +01:00 committed by GitHub
commit 18ed70b073
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 469 additions and 370 deletions

View file

@ -40,9 +40,6 @@
#define TEXT_SOUND_SELECT TEXT_JPHUD_SOUND_SELECT
#define TEXT_FILE_MARIO_A _("マリオA")
#define TEXT_FILE_MARIO_B _("マリオB")
#define TEXT_FILE_MARIO_C _("マリオC")
#define TEXT_FILE_MARIO_D _("マリオD")
// Menu Options
#define TEXT_SCORE _("スコア")
@ -68,9 +65,6 @@
#define TEXT_HI_SCORE _("ハイスコア")
#define TEXT_MY_SCORE _("マイスコア")
#define TEXT_SCORE_MARIO_A _("マリオA")
#define TEXT_SCORE_MARIO_B _("マリオB")
#define TEXT_SCORE_MARIO_C _("マリオC")
#define TEXT_SCORE_MARIO_D _("マリオD")
// Copy Menu
#define TEXT_COPY_IT_TO_WHERE _("どこにコピーしますか?")
@ -137,9 +131,6 @@
#define TEXT_ERASE_FILE _("ERASE FILE")
#define TEXT_SOUND_SELECT _("SOUND SELECT")
#define TEXT_FILE_MARIO_A _("MARIO A")
#define TEXT_FILE_MARIO_B _("MARIO B")
#define TEXT_FILE_MARIO_C _("MARIO C")
#define TEXT_FILE_MARIO_D _("MARIO D")
// Menu Options
#define TEXT_SCORE _("SCORE")
@ -166,9 +157,6 @@
#define TEXT_MY_SCORE _("MY SCORE")
// Score Mario Text ("☺" is the Mario face defined in the US/EU menu char table)
#define TEXT_SCORE_MARIO_A _("☺A")
#define TEXT_SCORE_MARIO_B _("☺B")
#define TEXT_SCORE_MARIO_C _("☺C")
#define TEXT_SCORE_MARIO_D _("☺D")
// Copy Menu
#define TEXT_COPY_IT_TO_WHERE _("COPY IT TO WHERE?")

View file

@ -317,42 +317,47 @@ void render_hud_keys(void) {
}
}
s32 get_y_pos(u8 hudIdx) {
return 24 * hudIdx;
}
/**
* Renders the timer when Mario start sliding in PSS.
* Displays a timer in the top-right
*/
void render_hud_timer(void) {
void render_hud_timer(u16 timeInFrames, u8 timerIdx, const char *prefix, u32 distFromRightEdge) {
u8 *(*hudLUT)[58] = segmented_to_virtual(&main_hud_lut);
u16 timerValFrames = gHudDisplay.timer;
u16 timerMins = timerValFrames / (30 * 60);
u16 timerSecs = (timerValFrames - (timerMins * 1800)) / 30;
u16 timerFracSecs = ((timerValFrames - (timerMins * 1800) - (timerSecs * 30)) & 0xFFFF) / 3;
#ifdef VERSION_EU
switch (eu_get_language()) {
case LANGUAGE_ENGLISH:
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "TIME");
break;
case LANGUAGE_FRENCH:
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(155), 185, "TEMPS");
break;
case LANGUAGE_GERMAN:
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "ZEIT");
break;
}
#else
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "TIME");
#endif
struct TimerDisplay time = frames_to_display_time(timeInFrames);
s32 yPos = 184 - get_y_pos(timerIdx);
s32 yPosApostropes = 32 + get_y_pos(timerIdx);
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(91), 185, "%0d", timerMins);
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(71), 185, "%02d", timerSecs);
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(37), 185, "%d", timerFracSecs);
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(distFromRightEdge), yPos, prefix);
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(91), yPos, "%0d", time.mins);
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(71), yPos, "%02d", time.secs);
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(37), yPos, "%02d", time.fracSecs);
gSPDisplayList(gDisplayListHead++, dl_hud_img_begin);
render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(81), 32, (*hudLUT)[GLYPH_APOSTROPHE]);
render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(46), 32, (*hudLUT)[GLYPH_DOUBLE_QUOTE]);
render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(81), yPosApostropes,
(*hudLUT)[GLYPH_APOSTROPHE]);
render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(45), yPosApostropes,
(*hudLUT)[GLYPH_DOUBLE_QUOTE]);
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
}
/**
* Displays a rank in the top-left
*/
void render_hud_rank(struct RankDisplay rank, u8 timerIdx, u32 distFromLeftEdge, const char *prefix,
u32 prefixLength) {
s32 yPos;
char rankStr[2] = { '\0', '\0' };
rankStr[0] = rank.asChar;
yPos = 184 - get_y_pos(timerIdx);
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(distFromLeftEdge), yPos, prefix);
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(distFromLeftEdge + prefixLength), yPos, rankStr);
}
/**
* Sets HUD status camera value depending of the actions
* defined in update_camera_status.
@ -407,6 +412,7 @@ void render_hud_camera_status(void) {
*/
void render_hud(void) {
s16 hudDisplayFlags = gHudDisplay.flags;
u16 best_time;
if (hudDisplayFlags == HUD_DISPLAY_NONE) {
sPowerMeterHUD.animation = POWER_METER_HIDDEN;
@ -456,7 +462,41 @@ void render_hud(void) {
}
if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER) {
render_hud_timer();
render_hud_timer(gTimer.time, 0, "", 100);
if (gTimer.collectedStarId >= 0) {
best_time = save_file_get_best_time(COURSE_NUM_TO_INDEX(gCurrCourseNum),
gTimer.collectedStarId);
render_hud_timer(best_time, 1, "PB", 120);
render_hud_rank(time_to_rank(gTimer.time, COURSE_NUM_TO_INDEX(gCurrCourseNum),
gTimer.collectedStarId),
0, 10, "RANK", 60);
render_hud_rank(time_to_rank(best_time, COURSE_NUM_TO_INDEX(gCurrCourseNum),
gTimer.collectedStarId),
1, 35, "PB", 35);
}
} else if (hudDisplayFlags & HUD_DISPLAY_FLAG_PSS_TIMER) {
char *prefix;
u32 distFromRightEdge;
#ifdef VERSION_EU
switch (eu_get_language()) {
case LANGUAGE_ENGLISH:
str = "TIME";
distFromRightEdge = 150;
break;
case LANGUAGE_FRENCH:
str = "TEMPS";
distFromRightEdge = 155;
break;
case LANGUAGE_GERMAN:
str = "ZEIT";
distFromRightEdge = 150;
break;
}
#else
prefix = "ZEIT";
distFromRightEdge = 150;
#endif
render_hud_timer(gHudDisplay.timer, 0, prefix, distFromRightEdge);
}
#ifdef DEBUG

View file

@ -813,25 +813,28 @@ s16 get_string_width(u8 *str) {
}
#endif
u8 gHudSymCoin[] = { GLYPH_COIN, GLYPH_SPACE };
u8 gHudSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE };
u8 gHudSymApostrophe[] = { GLYPH_APOSTROPHE, GLYPH_SPACE };
u8 gHudSymDoubleQuote[] = { GLYPH_DOUBLE_QUOTE, GLYPH_SPACE };
u8 textSOB[] = { 0x1C, 0x18, 0x0B, GLOBAR_CHAR_TERMINATOR };
void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileIndex, s8 courseIndex, s16 x, s16 y) {
u8 strNumCoins[4];
s16 numCoins;
void print_hud_my_sob(s8 courseIndex, s16 x, s16 y) {
struct TimerDisplay time;
u8 strMins[4];
u8 strSecs[4];
u8 strFracSecs[4];
u32 sob;
if (!useCourseCoinScore) {
numCoins = (u16)(save_file_get_max_coin_score(courseIndex) & 0xFFFF);
} else {
numCoins = save_file_get_course_coin_score(fileIndex, courseIndex);
}
if (numCoins != 0) {
print_hud_lut_string(HUD_LUT_GLOBAL, x, y, gHudSymCoin);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, gHudSymX);
int_to_str(numCoins, strNumCoins);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, strNumCoins);
}
sob = save_file_get_course_sob(courseIndex);
time = frames_to_display_time(sob);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 6, y, textSOB);
int_to_str(time.mins, strMins);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 50, y, strMins);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 60, y - 8, gHudSymApostrophe);
int_to_str(time.secs, strSecs);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 70, y, strSecs);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 94, y - 8, gHudSymDoubleQuote);
int_to_str(time.fracSecs, strFracSecs);
print_hud_lut_string(HUD_LUT_GLOBAL, x + 104, y, strFracSecs);
}
void print_hud_my_score_stars(s8 fileIndex, s8 courseIndex, s16 x, s16 y) {
@ -2211,7 +2214,25 @@ u8 gTextCourse[][7] = {
#define MYSCORE_X 62
#endif
void render_pause_my_score_coins(void) {
void render_scores_hud_lut(u8 courseIndex) {
int i;
u8 rankText[2] = { 0xFF, 0xFF };
print_hud_my_sob(courseIndex, 178, 103);
print_hud_my_score_stars(gCurrSaveFileNum - 1, courseIndex, 118, 103);
for (i = 0; i < 7; i++) {
const s16 x = 30 + i * 40;
const s16 y = 32;
if (save_file_best_time_exists(courseIndex, i)) {
rankText[0] = time_to_rank(save_file_get_best_time(courseIndex, i), courseIndex, i)
.asU8; // TODO use couseIndex or num everywhere
} else {
rankText[0] = RANK_NONE_2;
}
print_hud_lut_string(HUD_LUT_GLOBAL, x, y, rankText);
}
}
void render_pause_scores(void) {
#ifdef VERSION_EU
u8 textMyScore[][10] = {
{ TEXT_MY_SCORE },
@ -2262,8 +2283,7 @@ void render_pause_my_score_coins(void) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
if (courseIndex <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) {
print_hud_my_score_coins(1, gCurrSaveFileNum - 1, courseIndex, 178, 103);
print_hud_my_score_stars(gCurrSaveFileNum - 1, courseIndex, 118, 103);
render_scores_hud_lut(courseIndex);
}
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
@ -2418,7 +2438,7 @@ void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) {
void render_pause_castle_menu_box(s16 x, s16 y) {
create_dl_translation_matrix(MENU_MTX_PUSH, x - 78, y - 32, 0);
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.2f, 0.8f, 1.0f);
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.2f, 1.0f, 1.0f);
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 105);
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
@ -2429,7 +2449,7 @@ void render_pause_castle_menu_box(s16 x, s16 y) {
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
create_dl_translation_matrix(MENU_MTX_PUSH, x - 9, y - 101, 0);
create_dl_translation_matrix(MENU_MTX_PUSH, x - 9, y - 118, 0);
create_dl_rotation_matrix(MENU_MTX_NOPUSH, 270.0f, 0, 0, 1.0f);
gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
@ -2469,46 +2489,47 @@ void print_hud_pause_colorful_str(void) {
}
void render_pause_castle_course_stars(s16 x, s16 y, s16 fileIndex, s16 courseIndex) {
s16 hasStar = 0;
u8 str[COURSE_STAGES_COUNT * 2];
u8 textStar[] = { TEXT_STAR };
u16 starIdx = 0;
u8 starStr[COURSE_STAGES_COUNT * 2];
u8 rankStr[NUM_SCORES_PER_STAGE * 3];
u8 starFlags = save_file_get_star_flags(fileIndex, courseIndex);
u16 starCount = save_file_get_course_star_count(fileIndex, courseIndex);
u16 nextStar = 0;
if (starFlags & (1 << 6)) {
starCount--;
print_generic_string(x + 89, y - 5, textStar);
}
while (hasStar != starCount) {
if (starFlags & (1 << nextStar)) {
str[nextStar * 2] = DIALOG_CHAR_STAR_FILLED;
hasStar++;
for (starIdx = 0; starIdx < NUM_SCORES_PER_STAGE; starIdx++) {
if (starFlags & (1 << starIdx)) {
starStr[starIdx * 2] = DIALOG_CHAR_STAR_FILLED;
} else {
str[nextStar * 2] = DIALOG_CHAR_STAR_OPEN;
starStr[starIdx * 2] = DIALOG_CHAR_STAR_OPEN;
}
if (save_file_best_time_exists(courseIndex, starIdx)) {
rankStr[starIdx * 3] =
time_to_rank(save_file_get_best_time(courseIndex, starIdx), courseIndex, starIdx).asU8;
} else {
rankStr[starIdx * 3] = RANK_NONE;
}
str[nextStar * 2 + 1] = DIALOG_CHAR_SPACE;
nextStar++;
starStr[starIdx * 2 + 1] = DIALOG_CHAR_SPACE;
rankStr[starIdx * 3 + 1] = DIALOG_CHAR_SPACE;
rankStr[starIdx * 3 + 2] = DIALOG_CHAR_SPACE;
}
if (starCount == nextStar && starCount != 6) {
str[nextStar * 2] = DIALOG_CHAR_STAR_OPEN;
str[nextStar * 2 + 1] = DIALOG_CHAR_SPACE;
nextStar++;
}
starStr[starIdx * 2] = DIALOG_CHAR_TERMINATOR;
rankStr[starIdx * 3] = DIALOG_CHAR_TERMINATOR;
str[nextStar * 2] = DIALOG_CHAR_TERMINATOR;
print_generic_string(x + 14, y + 13, str);
print_generic_string(x + 5, y, starStr);
print_generic_string(x + 3, y - 16, rankStr);
}
u8 hudDialogApostrophe[] = { 0x3E, 0xFF };
u8 hudDialogDoubleQuote[] = { 0xF6, 0xFF };
void render_pause_castle_main_strings(s16 x, s16 y) {
struct TimerDisplay time;
u8 strMins[4];
u8 strSecs[4];
u8 strFracSecs[4];
u32 sob;
#ifdef VERSION_EU
void **courseNameTbl;
#else
@ -2574,14 +2595,21 @@ void render_pause_castle_main_strings(s16 x, s16 y) {
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
if (gDialogLineNum <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { // Main courses
const s16 ySob = y - 25;
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
print_generic_string(x + 44, y - 5, textX);
#endif
int_to_str(save_file_get_course_coin_score(gCurrSaveFileNum - 1, gDialogLineNum), strVal);
print_generic_string(x + 54, y - 5, strVal);
render_pause_castle_course_stars(x, y + 10, gCurrSaveFileNum - 1, gDialogLineNum);
sob = save_file_get_course_sob(gDialogLineNum);
time = frames_to_display_time(sob);
print_generic_string(x + 20, ySob, textSOB);
int_to_str(time.mins, strMins);
print_generic_string(x + 43, ySob, strMins);
print_generic_string(x + 51, ySob, hudDialogApostrophe);
int_to_str(time.secs, strSecs);
print_generic_string(x + 56, ySob, strSecs);
print_generic_string(x + 71, ySob, hudDialogDoubleQuote);
int_to_str(time.fracSecs, strFracSecs);
print_generic_string(x + 78, ySob, strFracSecs);
#ifdef VERSION_EU
print_generic_string(x - 17, y + 30, courseName);
#endif
@ -2633,7 +2661,7 @@ s16 render_pause_courses_and_castle(void) {
case DIALOG_STATE_VERTICAL:
shade_screen();
render_pause_my_score_coins();
render_pause_scores();
render_pause_red_coins();
if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) {

View file

@ -148,7 +148,7 @@ s16 get_str_x_pos_from_center(s16 centerPos, u8 *str, f32 scale);
#if defined(VERSION_JP) || defined(VERSION_EU) || defined(VERSION_SH)
s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale);
#endif
void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileIndex, s8 courseIndex, s16 x, s16 y);
void print_hud_my_sob(s8 courseIndex, s16 x, s16 y);
void int_to_str(s32 num, u8 *dst);
s16 get_dialog_id(void);
void create_dialog_box(s16 dialog);

View file

@ -130,6 +130,7 @@ static u32 sBackwardKnockbackActions[][3] = {
static u8 sDisplayingDoorText = FALSE;
static u8 sJustTeleported = FALSE;
static u8 sPssSlideStarted = FALSE;
static u8 timerStarted = FALSE;
/**
* Returns the type of cap Mario is wearing.
@ -808,6 +809,7 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
m->usedObj = o;
starIndex = (o->oBehParams >> 24) & 0x1F;
gTimer.collectedStarId = starIndex;
save_file_collect_star_or_key(m->numCoins, starIndex);
m->numStars =
@ -1835,7 +1837,7 @@ void check_lava_boost(struct MarioState *m) {
}
void pss_begin_slide(UNUSED struct MarioState *m) {
if (!(gHudDisplay.flags & HUD_DISPLAY_FLAG_TIMER)) {
if (!(gHudDisplay.flags & HUD_DISPLAY_FLAG_PSS_TIMER)) {
level_control_timer(TIMER_CONTROL_SHOW);
level_control_timer(TIMER_CONTROL_START);
sPssSlideStarted = TRUE;
@ -1854,6 +1856,25 @@ void pss_end_slide(struct MarioState *m) {
}
}
void begin_timer(UNUSED struct MarioState *m) {
reset_gtimer();
show_gtimer();
start_gtimer();
}
void end_timer(struct MarioState *m) {
if (sTimerRunning) {
stop_gtimer();
if (gTimer.collectedStarId >= 0) {
bool isPb = save_file_register_new_time(COURSE_NUM_TO_INDEX(gCurrCourseNum),
gTimer.collectedStarId, gTimer.time);
if (isPb) {
save_file_do_save(gCurrSaveFileNum - 1);
}
}
}
}
void mario_handle_special_floors(struct MarioState *m) {
if ((m->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE) {
return;

View file

@ -120,5 +120,7 @@ u32 mario_check_object_grab(struct MarioState *m);
u32 get_door_save_file_flag(struct Object *door);
void mario_process_interactions(struct MarioState *m);
void mario_handle_special_floors(struct MarioState *m);
void begin_timer(UNUSED struct MarioState *m);
void end_timer(struct MarioState *m);
#endif // INTERACTION_H

View file

@ -161,6 +161,9 @@ struct CreditsEntry sCreditsSequence[] = {
struct MarioState gMarioStates[1];
struct HudDisplay gHudDisplay;
struct Timer gTimer;
s8 sTimerRunning;
s16 sCurrPlayMode;
u16 D_80339ECA;
s16 sTransitionTimer;
@ -176,7 +179,7 @@ s32 sDelayedWarpArg;
#if defined(VERSION_EU) || defined(VERSION_SH)
s16 unusedEULevelUpdateBss1;
#endif
s8 sTimerRunning;
s8 sPssTimerRunning;
s8 gNeverEnteredCastle;
struct MarioState *gMarioState = &gMarioStates[0];
@ -188,22 +191,22 @@ u8 unused3[2];
u16 level_control_timer(s32 timerOp) {
switch (timerOp) {
case TIMER_CONTROL_SHOW:
gHudDisplay.flags |= HUD_DISPLAY_FLAG_TIMER;
sTimerRunning = FALSE;
gHudDisplay.flags |= HUD_DISPLAY_FLAG_PSS_TIMER;
sPssTimerRunning = FALSE;
gHudDisplay.timer = 0;
break;
case TIMER_CONTROL_START:
sTimerRunning = TRUE;
sPssTimerRunning = TRUE;
break;
case TIMER_CONTROL_STOP:
sTimerRunning = FALSE;
sPssTimerRunning = FALSE;
break;
case TIMER_CONTROL_HIDE:
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_TIMER;
sTimerRunning = FALSE;
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_PSS_TIMER;
sPssTimerRunning = FALSE;
gHudDisplay.timer = 0;
break;
}
@ -211,6 +214,31 @@ u16 level_control_timer(s32 timerOp) {
return gHudDisplay.timer;
}
void start_gtimer(void) {
sTimerRunning = TRUE;
}
void stop_gtimer(void) {
sTimerRunning = FALSE;
}
void show_gtimer(void) {
gHudDisplay.flags |= HUD_DISPLAY_FLAG_TIMER;
}
void hide_gtimer(void) {
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_TIMER;
}
void reset_gtimer(void) {
gTimer.time = 0;
gTimer.collectedStarId = -1;
}
u16 get_timer_val(void) {
return gHudDisplay.timer;
}
u32 pressed_pause(void) {
u32 dialogActive = get_dialog_id() >= 0;
u32 intangible = (gMarioState->action & ACT_FLAG_INTANGIBLE) != 0;
@ -1019,9 +1047,12 @@ s32 play_mode_normal(void) {
warp_area();
check_instant_warp();
if (sTimerRunning && gHudDisplay.timer < 17999) {
if (sPssTimerRunning && gHudDisplay.timer < 17999) {
gHudDisplay.timer++;
}
if (sTimerRunning && gTimer.time < 17999) {
gTimer.time++;
}
area_update_objects();
update_hud_values();
@ -1214,7 +1245,7 @@ s32 init_level(void) {
gHudDisplay.flags = HUD_DISPLAY_NONE;
}
sTimerRunning = FALSE;
sPssTimerRunning = FALSE;
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
if (sWarpDest.nodeId >= WARP_NODE_CREDITS_MIN) {

View file

@ -87,7 +87,7 @@ extern s16 sDelayedWarpTimer;
extern s16 sSourceWarpNodeId;
extern s32 sDelayedWarpArg;
extern u8 unused3[2];
extern s8 sTimerRunning;
extern s8 sPssTimerRunning;
struct HudDisplay {
/*0x00*/ s16 lives;
@ -102,6 +102,14 @@ struct HudDisplay {
extern struct HudDisplay gHudDisplay;
extern s8 gNeverEnteredCastle;
struct Timer {
u16 time;
s8 collectedStarId; /* ID of the star that has just been collected or -1 otherwise */
};
extern struct Timer gTimer;
extern s8 sTimerRunning;
enum HUDDisplayFlag {
HUD_DISPLAY_FLAG_LIVES = 0x0001,
HUD_DISPLAY_FLAG_COIN_COUNT = 0x0002,
@ -109,15 +117,24 @@ enum HUDDisplayFlag {
HUD_DISPLAY_FLAG_CAMERA_AND_POWER = 0x0008,
HUD_DISPLAY_FLAG_KEYS = 0x0010,
HUD_DISPLAY_FLAG_UNKNOWN_0020 = 0x0020,
HUD_DISPLAY_FLAG_TIMER = 0x0040,
HUD_DISPLAY_FLAG_PSS_TIMER = 0x0040,
HUD_DISPLAY_FLAG_TIMER = 0x0080,
HUD_DISPLAY_FLAG_EMPHASIZE_POWER = 0x8000,
HUD_DISPLAY_NONE = 0x0000,
HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020
HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT
| HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER
| HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020
};
u16 level_control_timer(s32 timerOp);
void start_gtimer(void);
void stop_gtimer(void);
void show_gtimer(void);
void hide_gtimer(void);
void reset_gtimer(void);
u16 get_timer_val(void);
void fade_into_special_warp(u32 arg, u32 color);
void load_level_init_text(u32 arg);
s16 level_trigger_warp(struct MarioState *m, s32 warpOp);

View file

@ -638,7 +638,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) {
}
s32 act_star_dance(struct MarioState *m) {
// TODO end timer
end_timer(m);
m->faceAngle[1] = m->area->camera->yaw;
set_mario_animation(m, m->actionState == 2 ? MARIO_ANIM_RETURN_FROM_STAR_DANCE
: MARIO_ANIM_STAR_DANCE);
@ -651,7 +651,7 @@ s32 act_star_dance(struct MarioState *m) {
}
s32 act_star_dance_water(struct MarioState *m) {
// TODO end timer
end_timer(m);
m->faceAngle[1] = m->area->camera->yaw;
set_mario_animation(m, m->actionState == 2 ? MARIO_ANIM_RETURN_FROM_WATER_STAR_DANCE
: MARIO_ANIM_WATER_STAR_DANCE);
@ -998,6 +998,7 @@ s32 act_emerge_from_pipe(struct MarioState *m) {
}
s32 act_spawn_spin_airborne(struct MarioState *m) {
begin_timer(m);
// entered water, exit action
if (m->pos[1] < m->waterLevel - 100) {
load_level_init_text(0);
@ -1030,6 +1031,7 @@ s32 act_spawn_spin_airborne(struct MarioState *m) {
}
s32 act_spawn_spin_landing(struct MarioState *m) {
begin_timer(m);
stop_and_set_height_to_floor(m);
set_mario_animation(m, MARIO_ANIM_GENERAL_LAND);
if (is_anim_at_end(m)) {
@ -1177,7 +1179,7 @@ s32 act_death_exit(struct MarioState *m) {
/** (Ab-)used as a life-restoring level entry with no control downtime **/
s32 act_unused_death_exit(struct MarioState *m) {
// TODO begin timer
begin_timer(m);
if (launch_mario_until_land(m, ACT_FREEFALL_LAND_STOP, MARIO_ANIM_GENERAL_FALL, 0.0f)) {
#ifdef VERSION_JP
@ -1261,6 +1263,7 @@ s32 act_special_death_exit(struct MarioState *m) {
}
s32 act_spawn_no_spin_airborne(struct MarioState *m) {
begin_timer(m);
launch_mario_until_land(m, ACT_SPAWN_NO_SPIN_LANDING, MARIO_ANIM_GENERAL_FALL, 0.0f);
if (m->pos[1] < m->waterLevel - 100) {
set_water_plunge_action(m);
@ -1269,6 +1272,7 @@ s32 act_spawn_no_spin_airborne(struct MarioState *m) {
}
s32 act_spawn_no_spin_landing(struct MarioState *m) {
begin_timer(m);
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
set_mario_animation(m, MARIO_ANIM_GENERAL_LAND);
stop_and_set_height_to_floor(m);

View file

@ -6,6 +6,7 @@
#include "memory.h"
#include "print.h"
#include "segment2.h"
#include "course_table.h"
/**
* This file handles printing and formatting the colorful text that
@ -457,3 +458,78 @@ void render_text_labels(void) {
sTextLabelsCount = 0;
}
struct TimerDisplay frames_to_display_time(u16 timeInFrames) {
u16 timerMins = timeInFrames / (30 * 60);
u16 timerSecs = (timeInFrames - (timerMins * 1800)) / 30;
u16 timerFracSecs =
(u16) (((timeInFrames - (timerMins * 1800) - (timerSecs * 30)) & 0xFFFF) * 3.34f);
struct TimerDisplay t;
t.mins = timerMins;
t.secs = timerSecs;
t.fracSecs = timerFracSecs;
return t;
}
// Hardcoded Rank Definitions
u32 course_idx_to_rank_idx_map[2][2] = { { COURSE_NUM_TO_INDEX(1) /*COURSE_BOB*/, 1 },
{ COURSE_NUM_TO_INDEX(2) /*COURSE_WF*/, 2 } };
u32 course_idx_to_rank_idx(u32 courseIdx) {
u32 i;
for (i = 0; i < sizeof(course_idx_to_rank_idx_map) / sizeof(course_idx_to_rank_idx_map[0]); i++) {
if (courseIdx == course_idx_to_rank_idx_map[i][0]) {
return course_idx_to_rank_idx_map[i][1];
}
}
return 0;
}
short rank_times[3][7][4] = {
// fallback
{ { _40s(0), _40s(0), _40s(0), _40s(0) },
{ _40s(0), _40s(0), _40s(0), _40s(0) },
{ _40s(0), _40s(0), _40s(0), _40s(0) },
{ _40s(0), _40s(0), _40s(0), _40s(0) },
{ _40s(0), _40s(0), _40s(0), _40s(0) },
{ _40s(0), _40s(0), _40s(0), _40s(0) },
{ _40s(0), _40s(0), _40s(0), _40s(0) } },
// level 1
{ { _7s(6), _8s(0), _10s(20), _12s(0) },
{ _4s(22), _6s(0), _8s(0), _10s(0) },
{ _7s(28), _8s(0), _9s(0), _12s(0) },
{ _14s(27), _16s(0), _20s(0), _25s(0) },
{ _20s(0), _22s(0), _25s(0), _30s(0) },
{ _30s(0), _32s(0), _35s(0), _40s(0) },
{ _25s(0), _28s(0), _30s(0), _35s(0) } },
// level 2
{ { _1s(0), _10s(0), _20s(0), _30s(0) },
{ _1s(0), _10s(0), _20s(0), _30s(0) },
{ _1s(0), _10s(0), _20s(0), _30s(0) },
{ _1s(0), _10s(0), _20s(0), _30s(0) },
{ _1s(0), _10s(0), _20s(0), _30s(0) },
{ _1s(0), _10s(0), _20s(0), _30s(0) },
{ _1s(0), _10s(0), _20s(0), _30s(0) } }
};
struct RankDisplay time_to_rank(u16 timeInFrames, s16 courseIdx, s8 starId) {
struct RankDisplay rank;
short *scores = rank_times[course_idx_to_rank_idx(courseIdx)][starId];
if (timeInFrames < scores[0]) {
rank.asChar = 'S';
rank.asU8 = 0x1C;
} else if (timeInFrames < scores[1]) {
rank.asChar = 'A';
rank.asU8 = 0x0A;
} else if (timeInFrames < scores[2]) {
rank.asChar = 'B';
rank.asU8 = 0x0B;
} else if (timeInFrames < scores[3]) {
rank.asChar = 'C';
rank.asU8 = 0x0C;
} else {
rank.asChar = 'D';
rank.asU8 = 0x0D;
}
return rank;
}

View file

@ -25,9 +25,67 @@
#define GLYPH_DOUBLE_QUOTE 57
#define GLYPH_UMLAUT 58
#define FPS 30
#define _1s(frames) (FPS * 1 + frames)
#define _2s(frames) (FPS * 2 + frames)
#define _3s(frames) (FPS * 3 + frames)
#define _4s(frames) (FPS * 4 + frames)
#define _5s(frames) (FPS * 5 + frames)
#define _6s(frames) (FPS * 6 + frames)
#define _7s(frames) (FPS * 7 + frames)
#define _8s(frames) (FPS * 8 + frames)
#define _9s(frames) (FPS * 9 + frames)
#define _10s(frames) (FPS * 10 + frames)
#define _11s(frames) (FPS * 11 + frames)
#define _12s(frames) (FPS * 12 + frames)
#define _13s(frames) (FPS * 13 + frames)
#define _14s(frames) (FPS * 14 + frames)
#define _15s(frames) (FPS * 15 + frames)
#define _16s(frames) (FPS * 16 + frames)
#define _17s(frames) (FPS * 17 + frames)
#define _18s(frames) (FPS * 18 + frames)
#define _19s(frames) (FPS * 19 + frames)
#define _20s(frames) (FPS * 20 + frames)
#define _21s(frames) (FPS * 21 + frames)
#define _22s(frames) (FPS * 22 + frames)
#define _23s(frames) (FPS * 23 + frames)
#define _24s(frames) (FPS * 24 + frames)
#define _25s(frames) (FPS * 25 + frames)
#define _26s(frames) (FPS * 26 + frames)
#define _27s(frames) (FPS * 27 + frames)
#define _28s(frames) (FPS * 28 + frames)
#define _29s(frames) (FPS * 29 + frames)
#define _30s(frames) (FPS * 30 + frames)
#define _31s(frames) (FPS * 31 + frames)
#define _32s(frames) (FPS * 32 + frames)
#define _33s(frames) (FPS * 33 + frames)
#define _34s(frames) (FPS * 34 + frames)
#define _35s(frames) (FPS * 35 + frames)
#define _36s(frames) (FPS * 36 + frames)
#define _37s(frames) (FPS * 37 + frames)
#define _38s(frames) (FPS * 38 + frames)
#define _39s(frames) (FPS * 39 + frames)
#define _40s(frames) (FPS * 40 + frames)
#define RANK_NONE 0x9F
#define RANK_NONE_2 GLYPH_MULTIPLY
struct TimerDisplay {
u16 mins;
u16 secs;
u16 fracSecs;
};
struct RankDisplay {
char asChar;
u8 asU8;
};
void print_text_fmt_int(s32 x, s32 y, const char *str, s32 n);
void print_text(s32 x, s32 y, const char *str);
void print_text_centered(s32 x, s32 y, const char *str);
void render_text_labels(void);
struct TimerDisplay frames_to_display_time(u16 timeInFrames);
struct RankDisplay time_to_rank(u16 timeInFrames, s16 courseIdx, s8 starId);
#endif // PRINT_H

View file

@ -15,6 +15,7 @@
#define MENU_DATA_MAGIC 0x4849
#define SAVE_FILE_MAGIC 0x4441
STATIC_ASSERT(sizeof(struct HighScores) == sizeof(struct SaveFile) * 4, "HighScores size must match");
STATIC_ASSERT(sizeof(struct SaveBuffer) == EEPROM_SIZE, "eeprom buffer size must match");
extern struct SaveBuffer gSaveBuffer;
@ -265,12 +266,18 @@ void save_file_do_save(s32 fileIndex) {
gSaveFileModified = FALSE;
}
write_eeprom_data(gSaveBuffer.highScores, sizeof(gSaveBuffer.highScores));
save_main_menu_data();
}
void save_file_erase(s32 fileIndex) {
touch_high_score_ages(fileIndex);
bzero(&gSaveBuffer.files[fileIndex][0], sizeof(gSaveBuffer.files[fileIndex][0]));
/* Don't delete highscores on file erase
* // bzero(&gSaveBuffer.highScores, sizeof(gSaveBuffer.highScores));
* // bzero(&gSaveBuffer, sizeof(gSaveBuffer));
*/
gSaveFileModified = TRUE;
save_file_do_save(fileIndex);
@ -408,6 +415,46 @@ void save_file_collect_star_or_key(s16 coinScore, s16 starIndex) {
}
}
bool save_file_register_new_time(s32 courseIndex, s16 starIndex, u16 time) {
if (time > 0 && time < save_file_get_best_time(courseIndex, starIndex)) {
gSaveBuffer.highScores[0].times[courseIndex][starIndex] = time;
return TRUE;
}
return FALSE;
}
u16 save_file_get_best_time(s32 courseIndex, s16 starIndex) {
if (!save_file_best_time_exists(courseIndex, starIndex)) {
return 17999;
}
return gSaveBuffer.highScores[0].times[courseIndex][starIndex];
}
bool save_file_best_time_exists(s32 courseIndex, s16 starIndex) {
return gSaveBuffer.highScores[0].times[courseIndex][starIndex] != 0;
}
u32 save_file_get_course_sob(s32 courseIndex) {
u32 sob;
u32 starFlags;
s16 i;
sob = 0;
starFlags = save_file_get_star_flags(0, courseIndex);
for (i = 0; i < 7; i++) {
if (starFlags & (1 << i) || save_file_best_time_exists(courseIndex, i)) {
u16 starPb = save_file_get_best_time(courseIndex, i);
sob += starPb;
if (sob > 17999) {
sob = 17999;
}
}
}
return sob;
}
s32 save_file_exists(s32 fileIndex) {
return (gSaveBuffer.files[fileIndex][0].flags & SAVE_FLAG_FILE_EXISTS) != 0;
}
@ -563,7 +610,11 @@ void save_file_set_sound_mode(u16 mode) {
}
u16 save_file_get_sound_mode(void) {
return gSaveBuffer.menuData[0].soundMode;
u16 soundMode = gSaveBuffer.menuData[0].soundMode;
if (is_sound_mode_valid(soundMode)) {
return soundMode;
}
return SOUND_MENU_MODE_STEREO;
}
void save_file_move_cap_to_default_location(void) {

View file

@ -9,7 +9,8 @@
#include "course_table.h"
#define EEPROM_SIZE 0x200
#define NUM_SAVE_FILES 4
#define NUM_SAVE_FILES 1
#define NUM_SCORES_PER_STAGE 7
struct SaveBlockSignature {
u16 magic;
@ -36,13 +37,13 @@ struct SaveFile {
struct SaveBlockSignature signature;
};
enum SaveFileIndex {
SAVE_FILE_A,
SAVE_FILE_B,
SAVE_FILE_C,
SAVE_FILE_D
struct HighScores {
u16 times[COURSE_STAGES_COUNT][NUM_SCORES_PER_STAGE];
u8 filler[sizeof(struct SaveFile) * 4 - sizeof(u16) * COURSE_STAGES_COUNT * NUM_SCORES_PER_STAGE];
};
enum SaveFileIndex { SAVE_FILE_A };
struct MainMenuSaveData {
// Each save file has a 2 bit "age" for each course. The higher this value,
// the older the high score is. This is used for tie-breaking when displaying
@ -58,7 +59,8 @@ struct MainMenuSaveData {
#endif
// Pad to match the EEPROM size of 0x200 (10 bytes on JP/US, 8 bytes on EU)
u8 filler[EEPROM_SIZE / 2 - SUBTRAHEND - NUM_SAVE_FILES * (4 + sizeof(struct SaveFile))];
u8 filler[EEPROM_SIZE / 2 - SUBTRAHEND - NUM_SAVE_FILES * (4 + sizeof(struct SaveFile))
- sizeof(struct HighScores) / 2];
struct SaveBlockSignature signature;
};
@ -66,6 +68,7 @@ struct MainMenuSaveData {
struct SaveBuffer {
// Each of the four save files has two copies. If one is bad, the other is used as a backup.
struct SaveFile files[NUM_SAVE_FILES][2];
struct HighScores highScores[1];
// The main menu data has two copies. If one is bad, the other is used as a backup.
struct MainMenuSaveData menuData[2];
};
@ -131,6 +134,13 @@ BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex);
void save_file_load_all(void);
void save_file_reload(void);
void save_file_collect_star_or_key(s16 coinScore, s16 starIndex);
// PB-System
bool save_file_register_new_time(s32 courseIndex, s16 starIndex, u16 time);
u16 save_file_get_best_time(s32 courseIndex, s16 starIndex);
bool save_file_best_time_exists(s32 courseIndex, s16 starIndex);
u32 save_file_get_course_sob(s32 courseIndex);
s32 save_file_exists(s32 fileIndex);
u32 save_file_get_max_coin_score(s32 courseIndex);
s32 save_file_get_course_star_count(s32 fileIndex, s32 courseIndex);

View file

@ -139,11 +139,15 @@ void enable_background_sound(void) {
* Called from threads: thread5_game_loop
*/
void set_sound_mode(u16 soundMode) {
if (soundMode < 3) {
if (is_sound_mode_valid(soundMode)) {
audio_set_sound_mode(sSoundMenuModeToSoundMode[soundMode]);
}
}
bool is_sound_mode_valid(u16 soundMode) {
return soundMode < 3;
}
/**
* Wrapper method by menu used to set the sound via flags.
*

View file

@ -24,6 +24,7 @@ void lower_background_noise(s32 a);
void disable_background_sound(void);
void enable_background_sound(void);
void set_sound_mode(u16 soundMode);
bool is_sound_mode_valid(u16 soundMode);
void play_menu_sounds(s16 soundMenuFlags);
void play_painting_eject_sound(void);
void play_infinite_stairs_music(void);

View file

@ -154,9 +154,6 @@ static unsigned char textSoundModes[][8] = { { TEXT_STEREO }, { TEXT_MONO }, { T
#endif
static unsigned char textMarioA[] = { TEXT_FILE_MARIO_A };
static unsigned char textMarioB[] = { TEXT_FILE_MARIO_B };
static unsigned char textMarioC[] = { TEXT_FILE_MARIO_C };
static unsigned char textMarioD[] = { TEXT_FILE_MARIO_D };
#ifndef VERSION_EU
static unsigned char textNew[] = { TEXT_NEW };
@ -578,36 +575,7 @@ void render_score_menu_buttons(struct Object *scoreButton) {
311, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A]->oMenuButtonScale = 0.11111111f;
// File B
if (save_file_exists(SAVE_FILE_B) == TRUE) {
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B] =
spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton,
-166, 311, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B] =
spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton,
-166, 311, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B]->oMenuButtonScale = 0.11111111f;
// File C
if (save_file_exists(SAVE_FILE_C) == TRUE) {
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C] = spawn_object_rel_with_rot(
scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C] = spawn_object_rel_with_rot(
scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C]->oMenuButtonScale = 0.11111111f;
// File D
if (save_file_exists(SAVE_FILE_D) == TRUE) {
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D] =
spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton,
-166, 0, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D] = spawn_object_rel_with_rot(
scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D]->oMenuButtonScale = 0.11111111f;
// Return to main menu button
sMainMenuButtons[MENU_BUTTON_SCORE_RETURN] = spawn_object_rel_with_rot(
scoreButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0);
@ -700,35 +668,7 @@ void render_copy_menu_buttons(struct Object *copyButton) {
copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 311, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_COPY_FILE_A]->oMenuButtonScale = 0.11111111f;
// File B
if (save_file_exists(SAVE_FILE_B) == TRUE) {
sMainMenuButtons[MENU_BUTTON_COPY_FILE_B] =
spawn_object_rel_with_rot(copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton,
-166, 311, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_COPY_FILE_B] =
spawn_object_rel_with_rot(copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166,
311, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_COPY_FILE_B]->oMenuButtonScale = 0.11111111f;
// File C
if (save_file_exists(SAVE_FILE_C) == TRUE) {
sMainMenuButtons[MENU_BUTTON_COPY_FILE_C] = spawn_object_rel_with_rot(
copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_COPY_FILE_C] = spawn_object_rel_with_rot(
copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_COPY_FILE_C]->oMenuButtonScale = 0.11111111f;
// File D
if (save_file_exists(SAVE_FILE_D) == TRUE) {
sMainMenuButtons[MENU_BUTTON_COPY_FILE_D] = spawn_object_rel_with_rot(
copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_COPY_FILE_D] = spawn_object_rel_with_rot(
copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_COPY_FILE_D]->oMenuButtonScale = 0.11111111f;
// Return to main menu button
sMainMenuButtons[MENU_BUTTON_COPY_RETURN] = spawn_object_rel_with_rot(
copyButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0);
@ -890,36 +830,7 @@ void render_erase_menu_buttons(struct Object *eraseButton) {
311, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_A]->oMenuButtonScale = 0.11111111f;
// File B
if (save_file_exists(SAVE_FILE_B) == TRUE) {
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_B] =
spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton,
-166, 311, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_B] =
spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton,
-166, 311, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_B]->oMenuButtonScale = 0.11111111f;
// File C
if (save_file_exists(SAVE_FILE_C) == TRUE) {
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_C] = spawn_object_rel_with_rot(
eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_C] = spawn_object_rel_with_rot(
eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_C]->oMenuButtonScale = 0.11111111f;
// File D
if (save_file_exists(SAVE_FILE_D) == TRUE) {
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_D] =
spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton,
-166, 0, -100, 0, -0x8000, 0);
} else {
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_D] = spawn_object_rel_with_rot(
eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0);
}
sMainMenuButtons[MENU_BUTTON_ERASE_FILE_D]->oMenuButtonScale = 0.11111111f;
// Return to main menu button
sMainMenuButtons[MENU_BUTTON_ERASE_RETURN] = spawn_object_rel_with_rot(
eraseButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0);
@ -1328,36 +1239,7 @@ void bhv_menu_button_manager_init(void) {
bhvMenuButton, -6400, 2800, 0, 0, 0, 0);
}
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A]->oMenuButtonScale = 1.0f;
// File B
if (save_file_exists(SAVE_FILE_B) == TRUE) {
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B] =
spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE,
bhvMenuButton, 1500, 2800, 0, 0, 0, 0);
} else {
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B] =
spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE,
bhvMenuButton, 1500, 2800, 0, 0, 0, 0);
}
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B]->oMenuButtonScale = 1.0f;
// File C
if (save_file_exists(SAVE_FILE_C) == TRUE) {
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] =
spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE,
bhvMenuButton, -6400, 0, 0, 0, 0, 0);
} else {
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] = spawn_object_rel_with_rot(
gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, bhvMenuButton, -6400, 0, 0, 0, 0, 0);
}
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C]->oMenuButtonScale = 1.0f;
// File D
if (save_file_exists(SAVE_FILE_D) == TRUE) {
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = spawn_object_rel_with_rot(
gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE, bhvMenuButton, 1500, 0, 0, 0, 0, 0);
} else {
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = spawn_object_rel_with_rot(
gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, bhvMenuButton, 1500, 0, 0, 0, 0, 0);
}
sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D]->oMenuButtonScale = 1.0f;
// Score menu button
sMainMenuButtons[MENU_BUTTON_SCORE] = spawn_object_rel_with_rot(
gCurrentObject, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, bhvMenuButton, -6400, -3500, 0, 0, 0, 0);
@ -1432,27 +1314,7 @@ void check_main_menu_clicked_buttons(void) {
func_sh_8024C89C(1);
#endif
break;
case MENU_BUTTON_PLAY_FILE_B:
play_sound(SAVE_FILE_SOUND, gGlobalSoundSource);
#if ENABLE_RUMBLE
queue_rumble_data(60, 70);
func_sh_8024C89C(1);
#endif
break;
case MENU_BUTTON_PLAY_FILE_C:
play_sound(SAVE_FILE_SOUND, gGlobalSoundSource);
#if ENABLE_RUMBLE
queue_rumble_data(60, 70);
func_sh_8024C89C(1);
#endif
break;
case MENU_BUTTON_PLAY_FILE_D:
play_sound(SAVE_FILE_SOUND, gGlobalSoundSource);
#if ENABLE_RUMBLE
queue_rumble_data(60, 70);
func_sh_8024C89C(1);
#endif
break;
// Play sound of the button clicked and render buttons of that menu.
case MENU_BUTTON_SCORE:
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource);
@ -1504,15 +1366,6 @@ void bhv_menu_button_manager_loop(void) {
case MENU_BUTTON_PLAY_FILE_A:
load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A], 1);
break;
case MENU_BUTTON_PLAY_FILE_B:
load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B], 2);
break;
case MENU_BUTTON_PLAY_FILE_C:
load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C], 3);
break;
case MENU_BUTTON_PLAY_FILE_D:
load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D], 4);
break;
case MENU_BUTTON_SCORE:
check_score_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]);
break;
@ -1526,15 +1379,6 @@ void bhv_menu_button_manager_loop(void) {
case MENU_BUTTON_SCORE_FILE_A:
exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A], MENU_BUTTON_SCORE);
break;
case MENU_BUTTON_SCORE_FILE_B:
exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B], MENU_BUTTON_SCORE);
break;
case MENU_BUTTON_SCORE_FILE_C:
exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C], MENU_BUTTON_SCORE);
break;
case MENU_BUTTON_SCORE_FILE_D:
exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D], MENU_BUTTON_SCORE);
break;
case MENU_BUTTON_SCORE_RETURN:
return_to_main_menu(MENU_BUTTON_SCORE, sMainMenuButtons[MENU_BUTTON_SCORE_RETURN]);
break;
@ -1549,12 +1393,6 @@ void bhv_menu_button_manager_loop(void) {
case MENU_BUTTON_COPY_FILE_A:
break;
case MENU_BUTTON_COPY_FILE_B:
break;
case MENU_BUTTON_COPY_FILE_C:
break;
case MENU_BUTTON_COPY_FILE_D:
break;
case MENU_BUTTON_COPY_RETURN:
return_to_main_menu(MENU_BUTTON_COPY, sMainMenuButtons[MENU_BUTTON_COPY_RETURN]);
break;
@ -1569,12 +1407,6 @@ void bhv_menu_button_manager_loop(void) {
case MENU_BUTTON_ERASE_FILE_A:
break;
case MENU_BUTTON_ERASE_FILE_B:
break;
case MENU_BUTTON_ERASE_FILE_C:
break;
case MENU_BUTTON_ERASE_FILE_D:
break;
case MENU_BUTTON_ERASE_RETURN:
return_to_main_menu(MENU_BUTTON_ERASE, sMainMenuButtons[MENU_BUTTON_ERASE_RETURN]);
break;
@ -1620,9 +1452,7 @@ void bhv_menu_button_manager_loop(void) {
*/
void handle_cursor_button_input(void) {
// If scoring a file, pressing A just changes the coin score mode.
if (sSelectedButtonID == MENU_BUTTON_SCORE_FILE_A || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_B
|| sSelectedButtonID == MENU_BUTTON_SCORE_FILE_C
|| sSelectedButtonID == MENU_BUTTON_SCORE_FILE_D) {
if (sSelectedButtonID == MENU_BUTTON_SCORE_FILE_A) {
if (gPlayer3Controller->buttonPressed
#ifdef VERSION_EU
& (B_BUTTON | START_BUTTON | Z_TRIG)
@ -1832,9 +1662,6 @@ void print_main_menu_strings(void) {
#endif
// Print file star counts
print_save_file_star_count(SAVE_FILE_A, SAVEFILE_X1, 78);
print_save_file_star_count(SAVE_FILE_B, SAVEFILE_X2, 78);
print_save_file_star_count(SAVE_FILE_C, SAVEFILE_X1, 118);
print_save_file_star_count(SAVE_FILE_D, SAVEFILE_X2, 118);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
#ifndef VERSION_EU
// Print menu names
@ -1853,9 +1680,6 @@ void print_main_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_menu_generic_string(MARIOTEXT_X1, 65, textMarioA);
print_menu_generic_string(MARIOTEXT_X2, 65, textMarioB);
print_menu_generic_string(MARIOTEXT_X1, 105, textMarioC);
print_menu_generic_string(MARIOTEXT_X2, 105, textMarioD);
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end);
}
@ -1974,9 +1798,6 @@ void print_score_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_save_file_star_count(SAVE_FILE_A, 90, 76);
print_save_file_star_count(SAVE_FILE_B, 211, 76);
print_save_file_star_count(SAVE_FILE_C, 90, 119);
print_save_file_star_count(SAVE_FILE_D, 211, 119);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
#endif
@ -2004,9 +1825,6 @@ void print_score_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_menu_generic_string(89, 62, textMarioA);
print_menu_generic_string(211, 62, textMarioB);
print_menu_generic_string(89, 105, textMarioC);
print_menu_generic_string(211, 105, textMarioD);
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end);
#endif
}
@ -2161,9 +1979,6 @@ void print_copy_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_save_file_star_count(SAVE_FILE_A, 90, 76);
print_save_file_star_count(SAVE_FILE_B, 211, 76);
print_save_file_star_count(SAVE_FILE_C, 90, 119);
print_save_file_star_count(SAVE_FILE_D, 211, 119);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
#endif
// Print menu names
@ -2189,9 +2004,6 @@ void print_copy_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_menu_generic_string(89, 62, textMarioA);
print_menu_generic_string(211, 62, textMarioB);
print_menu_generic_string(89, 105, textMarioC);
print_menu_generic_string(211, 105, textMarioD);
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end);
#endif
}
@ -2434,9 +2246,6 @@ void print_erase_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_save_file_star_count(SAVE_FILE_A, 90, 76);
print_save_file_star_count(SAVE_FILE_B, 211, 76);
print_save_file_star_count(SAVE_FILE_C, 90, 119);
print_save_file_star_count(SAVE_FILE_D, 211, 119);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
#endif
@ -2465,9 +2274,6 @@ void print_erase_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha);
print_menu_generic_string(89, 62, textMarioA);
print_menu_generic_string(211, 62, textMarioB);
print_menu_generic_string(89, 105, textMarioC);
print_menu_generic_string(211, 105, textMarioD);
gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end);
#endif
}
@ -2605,7 +2411,7 @@ void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s1
#endif
unsigned char fileNames[][LENGTH] = {
{ TEXT_4DASHES }, // huh?
{ TEXT_SCORE_MARIO_A }, { TEXT_SCORE_MARIO_B }, { TEXT_SCORE_MARIO_C }, { TEXT_SCORE_MARIO_D },
{ TEXT_SCORE_MARIO_A },
};
#undef LENGTH
// MYSCORE
@ -2807,22 +2613,12 @@ static void print_file_select_strings(void) {
case MENU_BUTTON_SCORE_FILE_A:
print_save_file_scores(SAVE_FILE_A);
break;
case MENU_BUTTON_SCORE_FILE_B:
print_save_file_scores(SAVE_FILE_B);
break;
case MENU_BUTTON_SCORE_FILE_C:
print_save_file_scores(SAVE_FILE_C);
break;
case MENU_BUTTON_SCORE_FILE_D:
print_save_file_scores(SAVE_FILE_D);
break;
case MENU_BUTTON_SOUND_MODE:
print_sound_mode_menu_strings();
break;
}
// If all 4 save file exists, define true to sAllFilesExist to prevent more copies in copy menu
if (save_file_exists(SAVE_FILE_A) == TRUE && save_file_exists(SAVE_FILE_B) == TRUE &&
save_file_exists(SAVE_FILE_C) == TRUE && save_file_exists(SAVE_FILE_D) == TRUE) {
if (save_file_exists(SAVE_FILE_A) == TRUE) {
sAllFilesExist = TRUE;
} else {
sAllFilesExist = FALSE;
@ -2859,27 +2655,11 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) {
sSelectedButtonID = MENU_BUTTON_NONE;
sCurrentMenuLevel = MENU_LAYER_MAIN;
sTextBaseAlpha = 0;
// Place the cursor over the save file that was being played.
// gCurrSaveFileNum is 1 by default when the game boots, as such
// the cursor will point on Mario A save file.
switch (gCurrSaveFileNum) {
case 1: // File A
sCursorPos[0] = -94.0f;
sCursorPos[1] = 46.0f;
break;
case 2: // File B
sCursorPos[0] = 24.0f;
sCursorPos[1] = 46.0f;
break;
case 3: // File C
sCursorPos[0] = -94.0f;
sCursorPos[1] = 5.0f;
break;
case 4: // File D
sCursorPos[0] = 24.0f;
sCursorPos[1] = 5.0f;
break;
}
// set the cursor pos over file A
sCursorPos[0] = -94.0f;
sCursorPos[1] = 46.0f;
sClickPos[0] = -10000;
sClickPos[1] = -10000;
sCursorClickingTimer = 0;

View file

@ -29,9 +29,6 @@ enum MenuButtonTypes {
// Main Menu (SELECT FILE)
MENU_BUTTON_MAIN_MIN,
MENU_BUTTON_PLAY_FILE_A = MENU_BUTTON_MAIN_MIN,
MENU_BUTTON_PLAY_FILE_B,
MENU_BUTTON_PLAY_FILE_C,
MENU_BUTTON_PLAY_FILE_D,
MENU_BUTTON_SCORE,
MENU_BUTTON_COPY,
MENU_BUTTON_ERASE,
@ -40,9 +37,6 @@ enum MenuButtonTypes {
// Score Menu (CHECK FILE)
MENU_BUTTON_SCORE_MIN = MENU_BUTTON_MAIN_MAX,
MENU_BUTTON_SCORE_FILE_A = MENU_BUTTON_SCORE_MIN,
MENU_BUTTON_SCORE_FILE_B,
MENU_BUTTON_SCORE_FILE_C,
MENU_BUTTON_SCORE_FILE_D,
MENU_BUTTON_SCORE_RETURN,
MENU_BUTTON_SCORE_COPY_FILE,
MENU_BUTTON_SCORE_ERASE_FILE,
@ -51,9 +45,6 @@ enum MenuButtonTypes {
// Copy Menu (COPY FILE)
MENU_BUTTON_COPY_MIN = MENU_BUTTON_SCORE_MAX,
MENU_BUTTON_COPY_FILE_A = MENU_BUTTON_COPY_MIN,
MENU_BUTTON_COPY_FILE_B,
MENU_BUTTON_COPY_FILE_C,
MENU_BUTTON_COPY_FILE_D,
MENU_BUTTON_COPY_RETURN,
MENU_BUTTON_COPY_CHECK_SCORE,
MENU_BUTTON_COPY_ERASE_FILE,
@ -62,9 +53,6 @@ enum MenuButtonTypes {
// Erase Menu (ERASE FILE)
MENU_BUTTON_ERASE_MIN = MENU_BUTTON_COPY_MAX,
MENU_BUTTON_ERASE_FILE_A = MENU_BUTTON_ERASE_MIN,
MENU_BUTTON_ERASE_FILE_B,
MENU_BUTTON_ERASE_FILE_C,
MENU_BUTTON_ERASE_FILE_D,
MENU_BUTTON_ERASE_RETURN,
MENU_BUTTON_ERASE_CHECK_SCORE,
MENU_BUTTON_ERASE_COPY_FILE,

View file

@ -304,7 +304,7 @@ void print_act_selector_strings(void) {
// Print the coin highscore.
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
print_hud_my_score_coins(1, gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum), 155, 106);
print_hud_my_sob(COURSE_NUM_TO_INDEX(gCurrCourseNum), 155, 106);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);