From 46f905f4a3fe2ca58340b6db8032f1fc6984fa6e Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 12 Jul 2021 18:29:39 -0700 Subject: [PATCH] DJUI: Created popup system, re-added missing popup messages --- build-windows-visual-studio/sm64ex.vcxproj | 2 + .../sm64ex.vcxproj.filters | 6 + src/pc/djui/djui.c | 1 + src/pc/djui/djui.h | 1 + src/pc/djui/djui_popup.c | 103 ++++++++++++++++++ src/pc/djui/djui_popup.h | 11 ++ src/pc/network/discord/discord.c | 3 +- src/pc/network/network.c | 5 - src/pc/network/network.h | 1 - src/pc/network/network_player.c | 22 +++- src/pc/pc_main.c | 8 +- 11 files changed, 148 insertions(+), 15 deletions(-) create mode 100644 src/pc/djui/djui_popup.c create mode 100644 src/pc/djui/djui_popup.h diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index 3238b1914..3155c82ef 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -3950,6 +3950,7 @@ + @@ -4392,6 +4393,7 @@ + diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index afc2678a0..39eb45dbb 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -15252,6 +15252,9 @@ Source Files\src\pc\utils + + Source Files\src\pc\djui\component\compound + @@ -16324,5 +16327,8 @@ Source Files\src\pc\utils + + Source Files\src\pc\djui\component\compound + \ No newline at end of file diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c index f861a327e..c49ccf0fb 100644 --- a/src/pc/djui/djui.c +++ b/src/pc/djui/djui.c @@ -39,6 +39,7 @@ void djui_render(void) { create_dl_ortho_matrix(); djui_panel_update(); + djui_popup_update(); djui_base_render(&gDjuiRoot->base); diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h index 1bf0a7b74..f4f2d63f9 100644 --- a/src/pc/djui/djui.h +++ b/src/pc/djui/djui.h @@ -27,6 +27,7 @@ #include "djui_flow_layout.h" #include "djui_selectionbox.h" #include "djui_bind.h" +#include "djui_popup.h" #include "djui_panel.h" #include "djui_panel_menu.h" diff --git a/src/pc/djui/djui_popup.c b/src/pc/djui/djui_popup.c new file mode 100644 index 000000000..65c88f8b5 --- /dev/null +++ b/src/pc/djui/djui_popup.c @@ -0,0 +1,103 @@ +#include +#include "djui.h" +#include "pc/network/network.h" +#include "pc/utils/misc.h" + +#define DJUI_POPUP_LIFETIME 6.0f + +struct DjuiPopupList { + struct DjuiPopup* popup; + clock_t createTime; + struct DjuiPopupList* next; +}; + +static struct DjuiPopupList* sPopupListHead = NULL; +static f32 sPopupListY = 0; + +static void djui_popup_add_to_list(struct DjuiPopup* popup) { + struct DjuiPopupList* node = malloc(sizeof(struct DjuiPopupList)); + node->popup = popup; + node->createTime = clock(); + node->next = sPopupListHead; + sPopupListHead = node; +} + +static void djui_popup_render(struct DjuiBase* base) { + djui_rect_render(base); +} + +static void djui_popup_destroy(struct DjuiBase* base) { + struct DjuiPopup* popup = (struct DjuiPopup*)base; + free(popup); +} + +struct DjuiPopup* djui_popup_create(const char* message, int lines) { + struct DjuiPopup* popup = malloc(sizeof(struct DjuiPopup)); + struct DjuiBase* base = &popup->base; + + f32 height = lines * 32 + 32; + djui_base_init(&gDjuiRoot->base, base, djui_popup_render, djui_popup_destroy); + djui_base_set_alignment(base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); + djui_base_set_location(base, 8, -height); + djui_base_set_size(base, 400, height); + djui_base_set_border_width(base, 4); + djui_base_set_color(base, 0, 0, 0, 220); + djui_base_set_border_color(base, 0, 0, 0, 180); + + struct DjuiText* text = djui_text_create(base, message); + djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); + djui_base_set_size(&text->base, 1.0f, 1.0f); + djui_base_set_color(&text->base, 220, 220, 220, 255); + djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER); + djui_text_set_drop_shadow(text, 0, 0, 0, 64); + popup->text = text; + + sPopupListY -= height + 4; + djui_popup_add_to_list(popup); + return popup; +} + +void djui_popup_update(void) { + struct DjuiPopupList* node = sPopupListHead; + struct DjuiPopupList* last = NULL; + f32 y = sPopupListY; + + while (node != NULL) { + struct DjuiPopupList* next = node->next; + djui_base_set_location(&node->popup->base, 4, y); + y += node->popup->base.height.value + 4; + if (gNetworkType != NT_NONE && gNetworkPlayerLocal != NULL) { + f32 elapsed = (clock() - node->createTime) / (f32)CLOCKS_PER_SEC; + + // fade out + f32 alpha = fmin(DJUI_POPUP_LIFETIME - elapsed, 1.0f); + alpha *= alpha; + if (elapsed > DJUI_POPUP_LIFETIME) { alpha = 0; } + djui_base_set_color(&node->popup->base, 0, 0, 0, 220 * alpha); + djui_base_set_border_color(&node->popup->base, 0, 0, 0, 180 * alpha); + djui_base_set_color(&node->popup->text->base, 220, 220, 220, 255 * alpha); + djui_text_set_drop_shadow(node->popup->text, 0, 0, 0, 64 * alpha); + + // remove/deallocate popup + if (alpha == 0) { + if (last != NULL) { last->next = next; } + if (node == sPopupListHead) { sPopupListHead = next; } + djui_base_destroy(&node->popup->base); + free(node); + node = next; + continue; + } + } else { + // prevent popups from fading out when we're not connected + node->createTime = clock(); + } + + // iterate + last = node; + node = next; + } + + // move entire popup list + sPopupListY = sPopupListY * 0.75f + 1; + if (sPopupListY > 4) { sPopupListY = 4; } +} \ No newline at end of file diff --git a/src/pc/djui/djui_popup.h b/src/pc/djui/djui_popup.h new file mode 100644 index 000000000..66c130fd0 --- /dev/null +++ b/src/pc/djui/djui_popup.h @@ -0,0 +1,11 @@ +#pragma once +#include "djui.h" + +#pragma pack(1) +struct DjuiPopup { + struct DjuiBase base; + struct DjuiText* text; +}; + +struct DjuiPopup* djui_popup_create(const char* message, int lines); +void djui_popup_update(void); diff --git a/src/pc/network/discord/discord.c b/src/pc/network/discord/discord.c index 014efc8f7..8f6529b9e 100644 --- a/src/pc/network/discord/discord.c +++ b/src/pc/network/discord/discord.c @@ -5,6 +5,7 @@ #include "discord_network.h" #include "pc/debuglog.h" #include "pc/network/version.h" +#include "pc/djui/djui.h" #if defined(_WIN32) || defined(_WIN64) #include @@ -148,7 +149,7 @@ static bool ns_discord_initialize(enum NetworkType networkType) { DISCORD_REQUIRE(rc); } else if (rc) { LOG_ERROR("DiscordCreate failed: %d", rc); - djui_show_popup("\\#ffa0a0\\Error:\\#c8c8c8\\ Could not detect Discord.\n\nTry closing the game, restarting Discord, and opening the game again."); + djui_popup_create("\\#ffa0a0\\Error:\\#c8c8c8\\ Could not detect Discord.\n\\#a0a0a0\\Try closing the game, restarting Discord, and opening the game again.", 3); gDiscordFailed = true; return false; } diff --git a/src/pc/network/network.c b/src/pc/network/network.c index a516b9555..36adfe944 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -278,8 +278,3 @@ void network_shutdown(bool sendLeaving) { void chat_add_message(char* message) { LOG_INFO("chat: %s", message); } - -// TODO: replace -void djui_show_popup(char* message) { - LOG_INFO("popup: %s", message); -} diff --git a/src/pc/network/network.h b/src/pc/network/network.h index df372d501..f9e18249b 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -103,5 +103,4 @@ void network_shutdown(bool sendLeaving); // TODO: replace void chat_add_message(char* message); -void djui_show_popup(char* message); #endif diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 0ae0653d5..baff5ca83 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -2,6 +2,7 @@ #include "network_player.h" #include "game/mario_misc.h" #include "reservation_area.h" +#include "pc/djui/djui.h" #include "pc/debuglog.h" struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 }; @@ -177,8 +178,15 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { np->lastReceived = clock(); if (gNetworkType == NT_SERVER || type == NPT_SERVER) { gNetworkSystem->save_id(i, 0); } for (int j = 0; j < MAX_SYNC_OBJECTS; j++) { gSyncObjects[j].rxEventId[i] = 0; } - if (type == NPT_SERVER) { gNetworkPlayerServer = np; } - else { chat_add_message("player connected"); } + if (type == NPT_SERVER) { + gNetworkPlayerServer = np; + } else { + // display popup + u8* rgb = get_player_color(np->globalIndex, 0); + char popupMsg[128] = { 0 }; + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\Player\\#dcdcdc\\ connected.", rgb[0], rgb[1], rgb[2]); + djui_popup_create(popupMsg, 1); + } LOG_INFO("player connected, local %d, global %d", i, np->globalIndex); packet_ordered_clear(np->globalIndex); return i; @@ -218,7 +226,13 @@ u8 network_player_disconnected(u8 globalIndex) { gNetworkSystem->clear_id(i); for (int j = 0; j < MAX_SYNC_OBJECTS; j++) { gSyncObjects[j].rxEventId[i] = 0; } LOG_INFO("player disconnected, local %d, global %d", i, globalIndex); - chat_add_message("player disconnected"); + + // display popup + u8* rgb = get_player_color(np->globalIndex, 0); + char popupMsg[128] = { 0 }; + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\Player\\#dcdcdc\\ disconnected.", rgb[0], rgb[1], rgb[2]); + djui_popup_create(popupMsg, 1); + packet_ordered_clear(globalIndex); reservation_area_change(np); return i; @@ -235,6 +249,6 @@ void network_player_shutdown(void) { gNetworkSystem->clear_id(i); } - chat_add_message("network shutdown"); + djui_popup_create("\\#ffa0a0\\Error:\\#dcdcdc\\ network shutdown.", 1); LOG_INFO("cleared all network players"); } diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 7325ceffb..b37f8b1a8 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -269,6 +269,10 @@ void main_func(void) { djui_init(); +#ifdef UNSTABLE_BRANCH + djui_popup_create("This is an \\#ffa0a0\\unstable\\#dcdcdc\\ branch build.\nExpect many strange bugs.", 2); +#endif + if (gCLIOpts.Network == NT_CLIENT) { network_set_system(NS_SOCKET); strncpy(configJoinIp, gCLIOpts.JoinIp, IP_MAX_LEN); @@ -282,10 +286,6 @@ void main_func(void) { network_init(NT_NONE); } -#ifdef UNSTABLE_BRANCH - djui_show_popup("This is an unstable branch build.\n\nExpect many strange bugs.\n\nFor a more stable experience use the normal coop branch."); -#endif - audio_init(); sound_init();