From b5f1e2a294892783c91bd8b520c7afaccad31500 Mon Sep 17 00:00:00 2001 From: Emerald Lockdown <86802223+EmeraldLoc@users.noreply.github.com> Date: Sun, 7 Aug 2022 22:14:28 -0500 Subject: [PATCH] Customizations to the main menu and a fix for the title screen bug (#130) --- src/game/level_update.c | 214 +++++++++++++++++++++++++- src/pc/configfile.c | 6 + src/pc/configfile.h | 3 + src/pc/djui/djui.h | 1 + src/pc/djui/djui_panel_menu_options.c | 55 +++++++ src/pc/djui/djui_panel_menu_options.h | 4 + src/pc/djui/djui_panel_options.c | 10 +- 7 files changed, 284 insertions(+), 9 deletions(-) create mode 100644 src/pc/djui/djui_panel_menu_options.c create mode 100644 src/pc/djui/djui_panel_menu_options.h diff --git a/src/game/level_update.c b/src/game/level_update.c index c3057b53b..4f0adf28e 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -19,6 +19,7 @@ #include "object_list_processor.h" #include "ingame_menu.h" #include "obj_behaviors.h" +#include "game/object_helpers.h" #include "save_file.h" #include "hardcoded.h" #include "debug_course.h" @@ -1309,6 +1310,200 @@ static s32 play_mode_unused(void) { } s32 update_level(void) { + + //Probably an awful spot to put this, but hey, it works. + if (gDjuiInMainMenu) { + + int curLevel = 0; + + switch (configMenuLevel) { + case 0: + curLevel = LEVEL_CASTLE_GROUNDS; + break; + case 1: + curLevel = LEVEL_BOB; + break; + case 2: + curLevel = LEVEL_WF; + break; + case 3: + curLevel = LEVEL_WMOTR; + break; + case 4: + curLevel = LEVEL_JRB; + break; + case 5: + curLevel = LEVEL_SSL; + break; + case 6: + curLevel = LEVEL_TTM; + break; + case 7: + curLevel = LEVEL_SL; + break; + case 8: + curLevel = LEVEL_BBH; + break; + case 9: + curLevel = LEVEL_LLL; + break; + case 10: + curLevel = LEVEL_THI; + break; + + default: + curLevel = 16; + break; + } + + if (gCurrLevelNum != curLevel) { + if (curLevel == LEVEL_JRB) { + dynos_warp_to_level(curLevel, 1, 2); + } else if (curLevel == LEVEL_THI) { + dynos_warp_to_level(curLevel, 2, 6); + } else { + dynos_warp_to_level(curLevel, 1, 6); + } + } else if (curLevel == LEVEL_CASTLE_GROUNDS && gCurrActNum != 16) { + dynos_warp_to_level(curLevel, 1, 16); + } + + if (gCurrLevelNum == LEVEL_CASTLE_GROUNDS) { + gMarioState->pos[0] = -1328; + gMarioState->pos[1] = 260; + gMarioState->pos[2] = 4664; + gLakituState.curPos[1] = 390; + gLakituState.curPos[0] = -1328; + gLakituState.curPos[2] = 6064; + } else if (gCurrLevelNum == LEVEL_BOB) { + gMarioState->pos[0] = 7008; + gMarioState->pos[1] = 864; + gMarioState->pos[2] = 1943; + gLakituState.curPos[1] = 1064; + gLakituState.curPos[2] = 2843; + gLakituState.curPos[0] = 7908; + gMarioState->faceAngle[1] = 0x2000; + + // delete all goombas as they interfere with the main menu + + struct Object *o; + + o = find_object_with_behavior(bhvGoomba); + + if (o != NULL) { + if (obj_has_behavior(o, bhvGoomba)) { + obj_mark_for_deletion(o); + } + } + + } else if (gCurrLevelNum == LEVEL_WF) { + gLakituState.curPos[1] = 2760; + gLakituState.curPos[2] = -777; + gLakituState.curPos[0] = -4504; + gMarioState->pos[1] = 2560; + gMarioState->pos[2] = -327; + gMarioState->pos[0] = -2904; + gMarioState->faceAngle[1] = -31072 / 2; + } else if (gCurrLevelNum == LEVEL_WMOTR) { + gLakituState.curPos[1] = -2438; + gLakituState.curPos[2] = 6063; + gLakituState.curPos[0] = 3548; + gMarioState->pos[1] = -2738; + gMarioState->pos[2] = 4663; + gMarioState->pos[0] = 3548; + gMarioState->faceAngle[1] = 0; + } else if (gCurrLevelNum == LEVEL_JRB) { + gLakituState.curPos[1] = 1736; + gLakituState.curPos[2] = 6402; + gLakituState.curPos[0] = 5039; + gMarioState->pos[1] = 1536; + gMarioState->pos[2] = 6202; + gMarioState->pos[0] = 3639; + } else if (gCurrLevelNum == LEVEL_SSL) { + gLakituState.curPos[1] = 356; + gLakituState.curPos[2] = 2461; + gLakituState.curPos[0] = -2048; + gMarioState->pos[1] = 256; + gMarioState->pos[2] = 961; + gMarioState->pos[0] = -2048; + gMarioState->faceAngle[1] = 0; + } else if (gCurrLevelNum == LEVEL_TTM) { + gLakituState.curPos[1] = 1763; + gLakituState.curPos[2] = 3411; + gLakituState.curPos[0] = 3488; + gMarioState->pos[1] = 1460; + gMarioState->pos[2] = 2011; + gMarioState->pos[0] = 2488; + gMarioState->faceAngle[1] = 0x1000; + } else if (gCurrLevelNum == LEVEL_SL) { + gLakituState.curPos[1] = 1124; + gLakituState.curPos[2] = 443; + gLakituState.curPos[0] = 6994; + gMarioState->pos[1] = 1024; + gMarioState->pos[2] = 443; + gMarioState->pos[0] = 5494; + gMarioState->faceAngle[1] = 0x4000; + } else if (gCurrLevelNum == LEVEL_BBH) { + gLakituState.curPos[1] = -204; + gLakituState.curPos[2] = 6803; + gLakituState.curPos[0] = 666; + gMarioState->pos[1] = -204; + gMarioState->pos[2] = 5303; + gMarioState->pos[0] = 666; + gMarioState->faceAngle[1] = 0; + } else if (gCurrLevelNum == LEVEL_LLL) { + gLakituState.curPos[1] = 938; + gLakituState.curPos[2] = 1576; + gLakituState.curPos[0] = -3576; + gMarioState->pos[1] = 638; + gMarioState->pos[2] = 956; + gMarioState->pos[0] = -2376; + gMarioState->faceAngle[1] = -0x2800; + } else if (gCurrLevelNum == LEVEL_THI) { + gLakituState.curPos[1] = 431; + gLakituState.curPos[2] = -324; + gLakituState.curPos[0] = -2246; + gMarioState->pos[1] = 341; + gMarioState->pos[2] = -324; + gMarioState->pos[0] = -1010; + gMarioState->faceAngle[1] = -0x4000; + + // delete all goombas as they interfere with the main menu + + struct Object *o; + + o = find_object_with_behavior(bhvGoomba); + + if (o != NULL) { + if (obj_has_behavior(o, bhvGoomba)) { + obj_mark_for_deletion(o); + } + } + } + + gMarioState->input = 0; + + if (!configMenuSound) { + reset_volume(); + disable_background_sound(); + set_background_music(0, 0x0021, 0); + } + else { + reset_volume(); + disable_background_sound(); + + if (get_current_background_music() == 0x0021) { + if (curLevel == LEVEL_JRB) { + dynos_warp_to_level(curLevel, 1, 2); + } else if (curLevel == LEVEL_THI) { + dynos_warp_to_level(curLevel, 2, 6); + } else { + dynos_warp_to_level(curLevel, 1, 6); + } + } + } + } + s32 changeLevel = 0; if (gChangeLevel != -1) { @@ -1420,7 +1615,18 @@ s32 init_level(void) { if (gMarioState->action != ACT_UNINITIALIZED) { bool skipIntro = (gNetworkType == NT_NONE || gServerSettings.skipIntro != 0); if (gDjuiInMainMenu && (gNetworkType == NT_NONE)) { - set_mario_action(gMarioState, ACT_INTRO_CUTSCENE, 7); + set_mario_action(gMarioState, ACT_IDLE, 0); + if (configMenuRandom) { + #include + + int lower = 0, upper = 10; + + srand(time(0)); + + int randLevel = (rand() % (upper - lower + 1)) + lower; + + configMenuLevel = randLevel; + } } else if (skipIntro || save_file_exists(gCurrSaveFileNum - 1)) { set_mario_action(gMarioState, ACT_IDLE, 0); } else { @@ -1468,12 +1674,6 @@ s32 lvl_init_or_update(s16 initOrUpdate, UNUSED s32 unused) { case 0: result = init_level(); - // HACK: play main menu music - // this is in a terrible spot but I couldn't find a better one. - if (gDjuiInMainMenu) { - set_background_music(0, 0x0021, 0); - } - break; case 1: result = update_level(); diff --git a/src/pc/configfile.c b/src/pc/configfile.c index e26ee32b6..1a4113414 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -133,6 +133,9 @@ unsigned int configStayInLevelAfterStar = 0; unsigned int configNetworkSystem = 0; char configPlayerName[MAX_PLAYER_STRING] = ""; unsigned int configPlayerModel = 0; +unsigned int configMenuLevel = 0; +bool configMenuSound = true; +bool configMenuRandom = true; struct PlayerPalette configPlayerPalette = {{{0xff, 0x00, 0x00}, {0x00, 0x00, 0xff}, {0xff, 0xff, 0xff}}}; bool configUncappedFramerate = true; unsigned int configFrameLimit = 60; @@ -220,6 +223,9 @@ static const struct ConfigOption options[] = { {.name = "coop_player_knockback_strength", .type = CONFIG_TYPE_UINT , .uintValue = &configPlayerKnockbackStrength}, {.name = "coop_player_model", .type = CONFIG_TYPE_UINT , .uintValue = &configPlayerModel}, {.name = "coop_player_name", .type = CONFIG_TYPE_STRING, .stringValue = (char*)&configPlayerName, .maxStringLength = MAX_PLAYER_STRING}, + {.name = "coop_menu_level", .type = CONFIG_TYPE_UINT , .uintValue = &configMenuLevel}, + {.name = "coop_menu_sound", .type = CONFIG_TYPE_BOOL , .boolValue = &configMenuSound}, + {.name = "coop_menu_random", .type = CONFIG_TYPE_BOOL , .boolValue = &configMenuRandom}, {.name = "coop_player_palette_shirt", .type = CONFIG_TYPE_COLOR , .colorValue = &configPlayerPalette.parts[SHIRT]}, {.name = "coop_player_palette_pants", .type = CONFIG_TYPE_COLOR , .colorValue = &configPlayerPalette.parts[PANTS]}, {.name = "coop_player_palette_gloves", .type = CONFIG_TYPE_COLOR , .colorValue = &configPlayerPalette.parts[GLOVES]}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index b01ec11c4..656b19137 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -90,6 +90,9 @@ extern unsigned int configStayInLevelAfterStar; extern unsigned int configNetworkSystem; extern char configPlayerName[]; extern unsigned int configPlayerModel; +extern unsigned int configMenuLevel; +extern bool configMenuSound; +extern bool configMenuRandom; extern struct PlayerPalette configPlayerPalette; extern bool configUncappedFramerate; extern unsigned int configFrameLimit; diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h index 02dba6b79..278a82316 100644 --- a/src/pc/djui/djui.h +++ b/src/pc/djui/djui.h @@ -56,6 +56,7 @@ #include "djui_panel_display.h" #include "djui_panel_dynos.h" #include "djui_panel_sound.h" +#include "djui_panel_menu_options.h" #include "djui_panel_confirm.h" #include "djui_panel_cheats.h" diff --git a/src/pc/djui/djui_panel_menu_options.c b/src/pc/djui/djui_panel_menu_options.c new file mode 100644 index 000000000..4ef757fe3 --- /dev/null +++ b/src/pc/djui/djui_panel_menu_options.c @@ -0,0 +1,55 @@ +#include "djui.h" +#include "src/pc/utils/misc.h" +#include "src/pc/configfile.h" + +static struct DjuiSelectionbox* sLevelBox = NULL; + +static void djui_panel_random_menu(UNUSED struct DjuiBase* caller) { + djui_base_set_enabled(&sLevelBox->base, !configMenuRandom); +} + +void djui_panel_main_menu_create(struct DjuiBase* caller) { + f32 bodyHeight = 32 * 4 + 64 * 1 + 16 * 4; + + struct DjuiBase* defaultBase = NULL; + struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\M\\#1be700\\A\\#00b3ff\\I\\#ffef00\\N \\#ff0800\\M\\#ff0800\\E\\#1be700\\N\\#ffef00\\U\\#ff0800\\"); + struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel); + + { + char* levelChoices[11] = { + "CG", + "BOB", + "WF", + "WMOTR", + "JRB", + "SSL", + "TTM", + "SL", + "BBH", + "LLL", + "THI", + }; + struct DjuiSelectionbox* selectionbox1 = djui_selectionbox_create(&body->base, "Level", levelChoices, 11, &configMenuLevel); + djui_base_set_size_type(&selectionbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&selectionbox1->base, 1.0f, 32); + djui_base_set_enabled(&selectionbox1->base, !configMenuRandom); + sLevelBox = selectionbox1; + + struct DjuiCheckbox* checkbox1 = djui_checkbox_create(&body->base, "Use Stage Music", &configMenuSound); + djui_base_set_size_type(&checkbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox1->base, 1.0f, 32); + + struct DjuiCheckbox* checkbox2 = djui_checkbox_create(&body->base, "Random Stage", &configMenuRandom); + djui_base_set_size_type(&checkbox2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox2->base, 1.0f, 32); + djui_interactable_hook_value_change(&checkbox2->base, djui_panel_random_menu); + + struct DjuiButton* button1 = djui_button_create(&body->base, "Back"); + djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button1->base, 1.0f, 64); + djui_button_set_style(button1, 1); + djui_interactable_hook_click(&button1->base, djui_panel_menu_back); + } + + djui_panel_add(caller, &panel->base, defaultBase); +} diff --git a/src/pc/djui/djui_panel_menu_options.h b/src/pc/djui/djui_panel_menu_options.h new file mode 100644 index 000000000..497825ea8 --- /dev/null +++ b/src/pc/djui/djui_panel_menu_options.h @@ -0,0 +1,4 @@ +#pragma once +#include "djui.h" + +void djui_panel_main_menu_create(struct DjuiBase* caller); diff --git a/src/pc/djui/djui_panel_options.c b/src/pc/djui/djui_panel_options.c index aee3e1b31..6cc457692 100644 --- a/src/pc/djui/djui_panel_options.c +++ b/src/pc/djui/djui_panel_options.c @@ -32,9 +32,9 @@ void djui_panel_options_debug_create(struct DjuiBase* caller) { void djui_panel_options_create(struct DjuiBase* caller) { #ifdef DEVELOPMENT - f32 bodyHeight = 64 * 7 + 16 * 6; + f32 bodyHeight = 64 * 7 + 16 * 12; #else - f32 bodyHeight = 64 * 6 + 16 * 5; + f32 bodyHeight = 64 * 6 + 16 * 11; #endif struct DjuiBase* defaultBase = NULL; @@ -69,6 +69,7 @@ void djui_panel_options_create(struct DjuiBase* caller) { djui_base_set_size_type(&button5->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button5->base, 1.0f, 64); djui_interactable_hook_click(&button5->base, djui_panel_sound_create); + #ifdef DEVELOPMENT struct DjuiButton* button6 = djui_button_create(&body->base, "Debug"); djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); @@ -76,6 +77,11 @@ void djui_panel_options_create(struct DjuiBase* caller) { djui_interactable_hook_click(&button6->base, djui_panel_options_debug_create); #endif + struct DjuiButton* button8 = djui_button_create(&body->base, "Menu Options"); + djui_base_set_size_type(&button8->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button8->base, 1.0f, 64); + djui_interactable_hook_click(&button8->base, djui_panel_main_menu_create); + struct DjuiButton* button7 = djui_button_create(&body->base, "Back"); djui_base_set_size_type(&button7->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button7->base, 1.0f, 64);