sm64coopdx/src/pc/djui/djui_chat_message.c
2024-12-10 02:31:39 -06:00

116 lines
4.7 KiB
C

#include <stdio.h>
#include "pc/network/network.h"
#include "pc/utils/misc.h"
#include "sounds.h"
#include "audio/external.h"
#include "game/mario_misc.h"
#include "djui.h"
#include "djui_hud_utils.h"
#include "pc/debuglog.h"
#include "pc/lua/smlua_hooks.h"
#define DJUI_CHAT_LIFE_TIME 10.0f
static bool djui_chat_message_render(struct DjuiBase* base) {
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
struct DjuiBase* ctBase = &chatMessage->message->base;
f32 seconds = clock_elapsed() - chatMessage->createTime;
f32 f = 1.0f;
if (seconds >= (DJUI_CHAT_LIFE_TIME - 1)) {
f = fmax(1.0f - (seconds - (DJUI_CHAT_LIFE_TIME - 1)), 0.0f);
f *= f;
f *= f;
}
if (gDjuiChatBoxFocus) {
djui_base_set_color(base, 0, 0, 0, 120);
djui_base_set_color(ctBase, 255, 255, 255, 255);
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, 1.0f, chatMessage->base.height.value);
} else if (f <= 0.1f) {
return false;
} else {
djui_base_set_color(base, 0, 0, 0, 180 * f);
djui_base_set_color(ctBase, 255, 255, 255, 255 * f);
djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, chatMessage->messageWidth, chatMessage->base.height.value);
}
djui_text_set_font(chatMessage->message, gDjuiFonts[configDjuiThemeFont == 0 ? FONT_NORMAL : FONT_ALIASED]);
djui_rect_render(base);
return true;
}
static void djui_chat_message_destroy(struct DjuiBase* base) {
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
free(chatMessage);
}
void djui_chat_message_create_from(u8 globalIndex, const char* message) {
struct NetworkPlayer* np = network_player_from_global_index(globalIndex);
if (np == NULL) {
LOG_ERROR("Could not find network player, global index: %u", globalIndex);
return;
}
bool returnValue = true;
smlua_call_event_hooks_on_chat_message(HOOK_ON_CHAT_MESSAGE, &gMarioStates[np->localIndex], message, &returnValue);
if (!returnValue) {
return;
}
const char* playerColorString = network_get_player_text_color_string(np->localIndex);
char chatMsg[256] = { 0 };
snprintf(chatMsg, 256, "%s%s\\#dcdcdc\\: %s", playerColorString, (np != NULL) ? np->name : "Player", message);
play_sound((globalIndex == gNetworkPlayerLocal->globalIndex) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gGlobalSoundSource);
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY)
if (gCLIOpts.console) return;
#endif
djui_chat_message_create(chatMsg);
}
void djui_chat_message_create(const char* message) {
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY)
if (gCLIOpts.console) printf("%s\n",message);
#endif
if (gDjuiChatBox == NULL || gDjuiChatBox->chatFlow == NULL) { return; }
struct DjuiChatMessage* chatMessage = calloc(1, sizeof(struct DjuiChatMessage));
struct DjuiBase* base = &chatMessage->base;
djui_base_init(&gDjuiChatBox->chatFlow->base, base, djui_chat_message_render, djui_chat_message_destroy);
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, 1.0f, 0);
djui_base_set_color(base, 0, 0, 0, 64);
djui_base_set_padding(base, 2, 4, 2, 4);
djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
f32 maxTextWidth = gDjuiChatBox->base.width.value - gDjuiChatBox->base.padding.left.value - gDjuiChatBox->base.padding.right.value - base->padding.left.value - base->padding.right.value;
struct DjuiText* chatText = djui_text_create(base, message);
struct DjuiBase* ctBase = &chatText->base;
djui_base_set_size_type(ctBase, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
djui_base_set_size(ctBase, maxTextWidth, 1.0f);
djui_base_set_color(ctBase, 255, 255, 255, 255);
djui_base_set_location(ctBase, 0, 0);
djui_text_set_alignment(chatText, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
chatMessage->message = chatText;
chatMessage->createTime = clock_elapsed();
// figure out chat message height
chatText->base.comp.width = maxTextWidth;
f32 messageHeight = djui_text_count_lines(chatText, 10) * (chatText->font->lineHeight * chatText->font->defaultFontScale) + 8;
djui_base_set_size(base, 1.0f, messageHeight);
gDjuiChatBox->chatFlow->base.height.value += messageHeight + gDjuiChatBox->chatFlow->margin.value;
if (!gDjuiChatBox->scrolling) {
gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;
}
// figure out chat message width
f32 messageWidth = djui_text_find_width(chatText, 10);
chatMessage->messageWidth = messageWidth + 8;
}