From 6d89ed5a9fccea37f3194e152a5eb304faee046e Mon Sep 17 00:00:00 2001 From: MysterD Date: Tue, 15 Sep 2020 09:47:26 -0700 Subject: [PATCH] Added warning when Discord isn't detected. Added missing sounds to buttons and events in menu --- build-windows-visual-studio/sm64ex.vcxproj | 3 + .../sm64ex.vcxproj.filters | 9 +++ src/game/ingame_menu.c | 25 ++++++- src/game/ingame_menu.h | 2 + src/menu/custom_menu.c | 34 ++++++--- src/menu/custom_menu.h | 2 +- src/menu/custom_menu_system.c | 74 ++++++++++++++++--- src/menu/custom_menu_system.h | 6 +- src/menu/file_select.c | 1 + src/pc/network/discord/discord.c | 2 + src/pc/network/packets/packet_save_file.c | 3 +- 11 files changed, 135 insertions(+), 26 deletions(-) diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index c09f789ea..068cde8d3 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -3846,6 +3846,7 @@ + @@ -3957,6 +3958,7 @@ + @@ -4313,6 +4315,7 @@ + diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index 3345c01ca..0369aef02 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -15042,6 +15042,12 @@ Source Files\src\menu + + Source Files\src\game + + + Source Files\src\pc\network\packets + @@ -15988,5 +15994,8 @@ Header Files\src\menu + + Header Files\src\game + \ No newline at end of file diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index bc8903ab7..ca95ffa43 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -438,13 +438,20 @@ void str_ascii_to_dialog(const char* string, u8* dialog, u16 length) { } f32 get_generic_dialog_width(u8* dialog) { + f32 largestWidth = 0; f32 width = 0; u8* d = dialog; while (*d != DIALOG_CHAR_TERMINATOR) { + if (*d == DIALOG_CHAR_NEWLINE) { + width = 0; + d++; + continue; + } width += (f32)(gDialogCharWidths[*d]); + largestWidth = MAX(width, largestWidth); d++; } - return width; + return largestWidth; } f32 get_generic_ascii_string_width(const char* ascii) { @@ -453,6 +460,22 @@ f32 get_generic_ascii_string_width(const char* ascii) { return get_generic_dialog_width(dialog); } +f32 get_generic_dialog_height(u8* dialog) { + int lines = 0; + u8* d = dialog; + while (*d != DIALOG_CHAR_TERMINATOR) { + if (*d == DIALOG_CHAR_NEWLINE) { lines++; } + d++; + } + return lines * 14; +} + +f32 get_generic_ascii_string_height(const char* ascii) { + u8 dialog[256] = { DIALOG_CHAR_TERMINATOR }; + str_ascii_to_dialog(ascii, dialog, strlen(ascii)); + return get_generic_dialog_height(dialog); +} + void print_generic_ascii_string(s16 x, s16 y, const char* ascii) { u8 dialog[256] = { DIALOG_CHAR_TERMINATOR }; str_ascii_to_dialog(ascii, dialog, strlen(ascii)); diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index 15985b5e9..10a140058 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -119,6 +119,8 @@ void create_dl_ortho_matrix(void); void str_ascii_to_dialog(const char* string, u8* dialog, u16 length); f32 get_generic_dialog_width(u8* dialog); f32 get_generic_ascii_string_width(const char* ascii); +f32 get_generic_dialog_height(u8* dialog); +f32 get_generic_ascii_string_height(const char* ascii); void print_generic_ascii_string(s16 x, s16 y, const char* ascii); void print_generic_string(s16 x, s16 y, const u8 *str); void print_hud_lut_string(s8 hudLUT, s16 x, s16 y, const u8 *str); diff --git a/src/menu/custom_menu.c b/src/menu/custom_menu.c index 305d7258d..1e77a4d76 100644 --- a/src/menu/custom_menu.c +++ b/src/menu/custom_menu.c @@ -15,10 +15,12 @@ #include "object_fields.h" #include "model_ids.h" #include "behavior_data.h" +#include "audio_defines.h" +#include "audio/external.h" #define MAIN_MENU_HEADER_TEXT "SM64 COOP" -char gConnectionJoinError[128] = { 0 }; +char sConnectionJoinError[128] = { 0 }; char gConnectionText[128] = { 0 }; struct CustomMenu* sConnectMenu = NULL; u8 gOpenConnectMenu = FALSE; @@ -118,10 +120,10 @@ static void connect_menu_draw_strings(void) { return; } - if (*gConnectionJoinError) { + if (*sConnectionJoinError) { f32 red = (f32)fabs(sin(gGlobalTimer / 20.0f)); gDPSetEnvColor(gDisplayListHead++, 222, 222 * red, 222 * red, gMenuStringAlpha); - print_generic_ascii_string(30, 130, gConnectionJoinError); + print_generic_ascii_string(30, 130, sConnectionJoinError); return; } @@ -141,6 +143,8 @@ static void connect_menu_draw_strings(void) { } static void connect_menu_on_connection_attempt(void) { + play_sound(SOUND_GENERAL_COIN, gDefaultSoundArgs); + keyboard_stop_text_input(); if (gNetworkType != NT_NONE) { return; } @@ -176,7 +180,7 @@ static void connect_menu_on_connection_attempt(void) { } static void connect_menu_on_click(void) { - gConnectionJoinError[0] = '\0'; + sConnectionJoinError[0] = '\0'; keyboard_start_text_input(TIM_IP, MAX_TEXT_INPUT, custom_menu_close, connect_menu_on_connection_attempt); @@ -204,22 +208,22 @@ void custom_menu_init(struct CustomMenu* head) { // create sub menus and buttons struct CustomMenu* hostMenu = custom_menu_create(head, "HOST", -266, 0); hostMenu->draw_strings = host_menu_draw_strings; - custom_menu_create_button(hostMenu, "CANCEL", 700, -400 + (250 * 3), custom_menu_close); - custom_menu_create_button(hostMenu, "HOST", 700, -400, host_menu_do_host); - custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 3), host_menu_setting_network_system); - custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 2), host_menu_setting_interaction); - custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 1), host_menu_setting_knockback); - custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 0), host_menu_setting_stay_in_level); + custom_menu_create_button(hostMenu, "CANCEL", 700, -400 + (250 * 3), SOUND_MENU_CAMERA_ZOOM_OUT, custom_menu_close); + custom_menu_create_button(hostMenu, "HOST", 700, -400, SOUND_MENU_CAMERA_ZOOM_IN, host_menu_do_host); + custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 3), SOUND_ACTION_BONK, host_menu_setting_network_system); + custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 2), SOUND_ACTION_BONK, host_menu_setting_interaction); + custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 1), SOUND_ACTION_BONK, host_menu_setting_knockback); + custom_menu_create_button(hostMenu, "", -700, -400 + (250 * 0), SOUND_ACTION_BONK, host_menu_setting_stay_in_level); struct CustomMenu* joinMenu = custom_menu_create(head, "JOIN", 266, 0); - custom_menu_create_button(joinMenu, "CANCEL", -266, -320, custom_menu_close); + custom_menu_create_button(joinMenu, "CANCEL", -266, -320, SOUND_MENU_CAMERA_ZOOM_OUT, custom_menu_close); joinMenu->draw_strings = join_menu_draw_strings; struct CustomMenu* connectMenu = custom_menu_create(joinMenu, "CONNECT", 266, -320); connectMenu->me->on_click = connect_menu_on_click; connectMenu->on_close = connect_menu_on_close; connectMenu->draw_strings = connect_menu_draw_strings; - custom_menu_create_button(connectMenu, "CANCEL", 0, -400, custom_menu_close); + custom_menu_create_button(connectMenu, "CANCEL", 0, -400, SOUND_MENU_CAMERA_ZOOM_OUT, custom_menu_close); sConnectMenu = connectMenu; } @@ -247,4 +251,10 @@ void custom_menu_on_load_save_file(s8 saveFileNum) { void custom_menu_goto_game(s16 saveFileNum) { sGotoGame = saveFileNum; +} + +void custom_menu_version_mismatch(void) { + play_sound(SOUND_MARIO_MAMA_MIA, gDefaultSoundArgs); + strcpy(sConnectionJoinError, "Your versions don't match, both should rebuild!"); + network_shutdown(); } \ No newline at end of file diff --git a/src/menu/custom_menu.h b/src/menu/custom_menu.h index 04b9e2b6a..69b734709 100644 --- a/src/menu/custom_menu.h +++ b/src/menu/custom_menu.h @@ -2,12 +2,12 @@ #define CUSTOM_MENU_H #include "custom_menu_system.h" -extern char gConnectionJoinError[]; extern u8 gOpenConnectMenu; void custom_menu_init(struct CustomMenu* head); void custom_menu_loop(void); void custom_menu_on_load_save_file(s8 saveFileNum); void custom_menu_goto_game(s16 saveFileNum); +void custom_menu_version_mismatch(void); #endif // CUSTOM_MENU_H diff --git a/src/menu/custom_menu_system.c b/src/menu/custom_menu_system.c index 128e173c5..f7d7c4fa6 100644 --- a/src/menu/custom_menu_system.c +++ b/src/menu/custom_menu_system.c @@ -14,15 +14,20 @@ #include "behavior_data.h" #include "audio_defines.h" #include "audio/external.h" +#include "gfx_dimensions.h" +#include "config.h" -#define MAIN_MENU_HEADER_TEXT "SM64 COOP" +#define MAX_ERROR_MESSAGE_LENGTH 128 static struct CustomMenu* sHead = NULL; static struct CustomMenu* sCurrentMenu = NULL; static struct CustomMenu* sLastMenu = NULL; -u8 gMenuStringAlpha = 255; -struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, char* label, u16 x, u16 y, void (*on_click)(void)) { +u8 gMenuStringAlpha = 255; +static u8 sErrorDialog[MAX_ERROR_MESSAGE_LENGTH] = { 0 }; +static u8 sErrorDialogShow = FALSE; + +struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, char* label, u16 x, u16 y, s32 clickSound, void (*on_click)(void)) { struct CustomMenuButton* button = calloc(1, sizeof(struct CustomMenuButton)); if (parent->buttons == NULL) { parent->buttons = button; @@ -35,6 +40,7 @@ struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, ch strcpy(button->label, label); button->on_click = on_click; + button->clickSound = clickSound; struct Object* obj = spawn_object_rel_with_rot(parent->me->object, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, x * -1, y, -1, 0, 0x8000, 0); obj->oMenuButtonScale = 0.11111111f; @@ -50,7 +56,7 @@ struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, ch } struct CustomMenu* custom_menu_create(struct CustomMenu* parent, char* label, u16 x, u16 y) { - struct CustomMenuButton* button = custom_menu_create_button(parent, label, x, y, NULL); + struct CustomMenuButton* button = custom_menu_create_button(parent, label, x, y, SOUND_MENU_CAMERA_ZOOM_IN, NULL); struct CustomMenu* menu = calloc(1, sizeof(struct CustomMenu)); menu->parent = parent; menu->depth = parent->depth + 1; @@ -154,7 +160,6 @@ void custom_menu_open(struct CustomMenu* menu) { gMenuStringAlpha = 0; sLastMenu = sCurrentMenu; sCurrentMenu = menu; - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); } void custom_menu_close(void) { @@ -167,13 +172,11 @@ void custom_menu_close(void) { if (sCurrentMenu->parent != NULL) { sCurrentMenu = sCurrentMenu->parent; } - play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gDefaultSoundArgs); } void custom_menu_close_system(void) { sHead->me->object->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING; gInCustomMenu = FALSE; - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); } static s32 cursor_inside_button(struct CustomMenuButton* button, f32 cursorX, f32 cursorY) { @@ -191,6 +194,7 @@ static s32 cursor_inside_button(struct CustomMenuButton* button, f32 cursorX, f3 } void custom_menu_cursor_click(f32 cursorX, f32 cursorY) { + #ifdef VERSION_EU u16 cursorClickButtons = (A_BUTTON | B_BUTTON | START_BUTTON | Z_TRIG); #else @@ -199,12 +203,31 @@ void custom_menu_cursor_click(f32 cursorX, f32 cursorY) { if (!(gPlayer3Controller->buttonPressed & cursorClickButtons)) { return; } if (sCurrentMenu->me->object->oMenuButtonState != MENU_BUTTON_STATE_FULLSCREEN) { return; } + if (sErrorDialogShow) { + sErrorDialogShow = FALSE; + play_sound(SOUND_ACTION_BONK, gDefaultSoundArgs); + return; + } + struct CustomMenuButton* button = sCurrentMenu->buttons; while (button != NULL) { if (cursor_inside_button(button, cursorX, cursorY)) { u8 didSomething = FALSE; - if (button->menu != NULL) { custom_menu_open(button->menu); didSomething = TRUE; } - if (button->on_click != NULL) { button->on_click(); didSomething = TRUE; } + + if (button->menu != NULL) { + custom_menu_open(button->menu); + didSomething = TRUE; + } + + if (button->on_click != NULL) { + button->on_click(); + didSomething = TRUE; + } + + if (button->clickSound != 0) { + play_sound(button->clickSound, gDefaultSoundArgs); + } + if (didSomething) { break; } } button = button->next; @@ -260,7 +283,34 @@ void custom_menu_print_strings(void) { } if (sCurrentMenu->draw_strings != NULL) { sCurrentMenu->draw_strings(); } gSPDisplayList(gDisplayListHead++, dl_ia_text_end); +} +void custom_menu_render_top(void) { + // print error message + if (sErrorDialogShow) { + // black screen + create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 240.0f, 0); + create_dl_scale_matrix(MENU_MTX_NOPUSH, GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT / 130.0f, 3.0f, 1.0f); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 240); + gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box); + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); + + // print text + gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); + f32 textWidth = get_generic_dialog_width(sErrorDialog); + f32 textHeight = get_generic_dialog_height(sErrorDialog); + + f32 xPos = (SCREEN_WIDTH - textWidth) / 2.0f; + f32 yPos = (SCREEN_HEIGHT + textHeight) / 2.0f; + + gDPSetEnvColor(gDisplayListHead++, 30, 30, 30, 255); + print_generic_string(xPos, yPos, sErrorDialog); + + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); + print_generic_string((xPos - 1), (yPos + 1), sErrorDialog); + + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); + } } /** @@ -321,3 +371,9 @@ void bhv_menu_button_shrinking_to_custom(struct Object* button) { button->oMenuButtonTimer = 0; } } + +void custom_menu_error(char* message) { + str_ascii_to_dialog(message, sErrorDialog, MIN(strlen(message), MAX_ERROR_MESSAGE_LENGTH - 1)); + if (!sErrorDialogShow) { play_sound(SOUND_MARIO_OOOF2, gDefaultSoundArgs); } + sErrorDialogShow = TRUE; +} \ No newline at end of file diff --git a/src/menu/custom_menu_system.h b/src/menu/custom_menu_system.h index 018eca3de..9bc5ed70d 100644 --- a/src/menu/custom_menu_system.h +++ b/src/menu/custom_menu_system.h @@ -6,6 +6,7 @@ struct CustomMenuButton { struct Object* object; char* label; void (*on_click)(void); + u32 clickSound; struct CustomMenu* menu; struct CustomMenuButton* next; }; @@ -24,10 +25,11 @@ extern u8 gMenuStringAlpha; void custom_menu_system_init(void); struct CustomMenu* custom_menu_create(struct CustomMenu* parent, char* label, u16 x, u16 y); -struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, char* label, u16 x, u16 y, void (*on_click)(void)); +struct CustomMenuButton* custom_menu_create_button(struct CustomMenu* parent, char* label, u16 x, u16 y, s32 clickSound, void (*on_click)(void)); void custom_menu_system_loop(void); void custom_menu_print_strings(void); +void custom_menu_render_top(void); void custom_menu_cursor_click(f32 x, f32 y); void custom_menu_open(struct CustomMenu* menu); @@ -37,4 +39,6 @@ void custom_menu_close_system(void); void bhv_menu_button_growing_from_custom(struct Object* button); void bhv_menu_button_shrinking_to_custom(struct Object* button); +void custom_menu_error(char* message); + #endif // CUSTOM_MENU_SYSTEM_H diff --git a/src/menu/file_select.c b/src/menu/file_select.c index 041d73e3a..86ccf5908 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -2804,6 +2804,7 @@ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct Grap if (callContext == GEO_CONTEXT_RENDER) { print_file_select_strings(); print_menu_cursor(); + custom_menu_render_top(); } return NULL; } diff --git a/src/pc/network/discord/discord.c b/src/pc/network/discord/discord.c index c97283e00..e39845e96 100644 --- a/src/pc/network/discord/discord.c +++ b/src/pc/network/discord/discord.c @@ -4,6 +4,7 @@ #include "lobby.h" #include "discord_network.h" #include "pc/debuglog.h" +#include "menu/custom_menu_system.h" #if defined(_WIN32) || defined(_WIN64) #include @@ -83,6 +84,7 @@ static bool ns_discord_initialize(enum NetworkType networkType) { int rc = DiscordCreate(DISCORD_VERSION, ¶ms, &app.core); if (rc) { LOG_ERROR("DiscordCreate failed: %d", rc); + custom_menu_error("Could not detect Discord.\n\nTry closing the game,\nrestarting Discord,\nand opening the game again."); return false; } diff --git a/src/pc/network/packets/packet_save_file.c b/src/pc/network/packets/packet_save_file.c index 34f8e19f7..6e792c71b 100644 --- a/src/pc/network/packets/packet_save_file.c +++ b/src/pc/network/packets/packet_save_file.c @@ -69,8 +69,7 @@ void network_receive_save_file(struct Packet* p) { save_file_load_all(TRUE); if (memcmp(hash, remoteHash, HASH_LENGTH) != 0) { - strcpy(gConnectionJoinError, "Your versions don't match, both should rebuild!"); - network_shutdown(); + custom_menu_version_mismatch(); return; } custom_menu_goto_game(gCurrSaveFileNum);