DJUI: Reimplemented chat

This commit is contained in:
MysterD 2021-07-21 00:53:28 -07:00
parent 321e101b30
commit 64648a8ce3
24 changed files with 415 additions and 64 deletions

View file

@ -3942,6 +3942,8 @@
<ClCompile Include="..\src\pc\djui\djui_base.c" />
<ClCompile Include="..\src\pc\djui\djui_bind.c" />
<ClCompile Include="..\src\pc\djui\djui_button.c" />
<ClCompile Include="..\src\pc\djui\djui_chat_box.c" />
<ClCompile Include="..\src\pc\djui\djui_chat_message.c" />
<ClCompile Include="..\src\pc\djui\djui_checkbox.c" />
<ClCompile Include="..\src\pc\djui\djui_inputbox.c" />
<ClCompile Include="..\src\pc\djui\djui_panel_cheats.c" />
@ -4388,6 +4390,8 @@
<ClInclude Include="..\src\pc\djui\djui_base.h" />
<ClInclude Include="..\src\pc\djui\djui_bind.h" />
<ClInclude Include="..\src\pc\djui\djui_button.h" />
<ClInclude Include="..\src\pc\djui\djui_chat_box.h" />
<ClInclude Include="..\src\pc\djui\djui_chat_message.h" />
<ClInclude Include="..\src\pc\djui\djui_checkbox.h" />
<ClInclude Include="..\src\pc\djui\djui_inputbox.h" />
<ClInclude Include="..\src\pc\djui\djui_panel_cheats.h" />

View file

@ -15264,6 +15264,12 @@
<ClCompile Include="..\src\pc\djui\djui_panel_cheats.c">
<Filter>Source Files\src\pc\djui\panel</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\djui\djui_chat_box.c">
<Filter>Source Files\src\pc\djui\component</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\djui\djui_chat_message.c">
<Filter>Source Files\src\pc\djui\component\compound</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\actors\common0.h">
@ -16348,5 +16354,11 @@
<ClInclude Include="..\src\pc\djui\djui_panel_cheats.h">
<Filter>Source Files\src\pc\djui\panel</Filter>
</ClInclude>
<ClInclude Include="..\src\pc\djui\djui_chat_box.h">
<Filter>Source Files\src\pc\djui\component</Filter>
</ClInclude>
<ClInclude Include="..\src\pc\djui\djui_chat_message.h">
<Filter>Source Files\src\pc\djui\component\compound</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -22,7 +22,6 @@ void djui_init(void) {
djui_panel_main_create(NULL);
//djui_panel_debug_create();
}
djui_cursor_create();
}

View file

@ -28,6 +28,8 @@
#include "djui_selectionbox.h"
#include "djui_bind.h"
#include "djui_popup.h"
#include "djui_chat_box.h"
#include "djui_chat_message.h"
#include "djui_panel.h"
#include "djui_panel_menu.h"

View file

@ -180,7 +180,8 @@ static void djui_base_add_child(struct DjuiBase* parent, struct DjuiBase* base)
baseChild->next = NULL;
// add it to the head
if (parent->child == NULL) {
if (parent->child == NULL || parent->addChildrenToHead) {
baseChild->next = parent->child;
parent->child = baseChild;
return;
}
@ -269,29 +270,29 @@ static void djui_base_render_border(struct DjuiBase* base) {
// events //
////////////
void djui_base_render(struct DjuiBase* base) {
if (!base->visible) { return; }
bool djui_base_render(struct DjuiBase* base) {
if (!base->visible) { return false; }
if (base->on_render_pre != NULL) {
bool skipRender = false;
base->on_render_pre(base, &skipRender);
if (skipRender) { return; }
if (skipRender) { return false; }
}
struct DjuiBaseRect* comp = &base->comp;
struct DjuiBaseRect* clip = &base->clip;
djui_base_compute(base);
if (comp->width <= 0) { return; }
if (comp->height <= 0) { return; }
if (clip->width <= 0) { return; }
if (clip->height <= 0) { return; }
if (comp->width <= 0) { return false; }
if (comp->height <= 0) { return false; }
if (clip->width <= 0) { return false; }
if (clip->height <= 0) { return false; }
if (base->borderWidth.value > 0 && base->borderColor.a > 0) {
djui_base_render_border(base);
}
if (clip->width < 0 || clip->height <= 0) { return; }
if (clip->width < 0 || clip->height <= 0) { return false; }
if (base->render != NULL) {
base->render(base);
@ -301,16 +302,20 @@ void djui_base_render(struct DjuiBase* base) {
// render all children
struct DjuiBaseChild* child = base->child;
bool hasChildRendered = false;
while (child != NULL) {
struct DjuiBaseChild* nextChild = child->next;
djui_base_render(child->base);
bool childRendered = djui_base_render(child->base);
if (base->abandonAfterChildRenderFail && !childRendered && hasChildRendered) { break; }
hasChildRendered = hasChildRendered || childRendered;
if (base->on_child_render != NULL) {
base->on_child_render(base, child->base);
}
child = nextChild;
}
return true;
}
void djui_base_destroy(struct DjuiBase* base) {

View file

@ -43,6 +43,8 @@ struct DjuiBase {
struct DjuiBaseRect comp;
struct DjuiBaseRect clip;
struct DjuiInteractable* interactable;
bool addChildrenToHead;
bool abandonAfterChildRenderFail;
s32 tag;
void (*get_cursor_hover_location)(struct DjuiBase*, f32* x, f32* y);
void (*on_child_render)(struct DjuiBase*, struct DjuiBase*);
@ -67,6 +69,6 @@ void djui_base_set_alignment(struct DjuiBase* base, enum DjuiHAlign hAlign, enum
void djui_base_compute(struct DjuiBase* base);
void djui_base_render(struct DjuiBase* base);
bool djui_base_render(struct DjuiBase* base);
void djui_base_destroy(struct DjuiBase* base);
void djui_base_init(struct DjuiBase* parent, struct DjuiBase* base, void (*render)(struct DjuiBase*), void (*destroy)(struct DjuiBase*));

135
src/pc/djui/djui_chat_box.c Normal file
View file

@ -0,0 +1,135 @@
#include <stdio.h>
#include <string.h>
#include "pc/network/network.h"
#include "djui.h"
struct DjuiChatBox* gDjuiChatBox = NULL;
bool gDjuiChatBoxFocus = false;
void djui_chat_box_render(struct DjuiBase* base) {
struct DjuiChatBox* chatBox = (struct DjuiChatBox*)base;
struct DjuiBase* ccBase = &chatBox->chatContainer->base;
djui_base_set_size(ccBase, 1.0f, chatBox->base.comp.height - 32 - 8);
}
static void djui_chat_box_destroy(struct DjuiBase* base) {
struct DjuiChatBox* chatBox = (struct DjuiChatBox*)base;
free(chatBox);
}
static void djui_chat_box_set_focus_style(void) {
djui_base_set_visible(&gDjuiChatBox->chatInput->base, gDjuiChatBoxFocus);
if (gDjuiChatBoxFocus) {
djui_interactable_set_input_focus(&gDjuiChatBox->chatInput->base);
}
djui_base_set_color(&gDjuiChatBox->chatFlow->base, 0, 0, 0, gDjuiChatBoxFocus ? 128 : 0);
}
static void djui_chat_box_input_enter(struct DjuiInputbox* chatInput) {
djui_interactable_set_input_focus(NULL);
if (strlen(chatInput->buffer) != 0) {
djui_chat_message_create_from(gNetworkPlayerLocal->globalIndex, chatInput->buffer);
network_send_chat(chatInput->buffer, gNetworkPlayerLocal->globalIndex);
}
djui_inputbox_set_text(chatInput, "");
djui_inputbox_select_all(chatInput);
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); }
}
static void djui_chat_box_input_escape(struct DjuiInputbox* chatInput) {
djui_inputbox_set_text(chatInput, "");
djui_inputbox_select_all(chatInput);
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); }
}
static bool djui_chat_box_input_on_key_down(struct DjuiBase* base, int scancode) {
if (gDjuiChatBox == NULL) { return false; }
f32 yMax = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;
f32* yValue = &gDjuiChatBox->chatFlow->base.y.value;
bool canScrollUp = (*yValue > yMax);
bool canScrollDown = (*yValue < 0);
f32 pageAmount = gDjuiChatBox->chatFlow->base.elem.height / 3.0f;
switch (scancode) {
case SCANCODE_UP:
gDjuiChatBox->scrolling = true;
if (canScrollUp) { *yValue = fmax(*yValue - 15, yMax); }
return true;
case SCANCODE_DOWN:
gDjuiChatBox->scrolling = true;
if (canScrollDown) { *yValue = fmin(*yValue + 15, 0); }
return true;
case SCANCODE_PAGE_UP:
gDjuiChatBox->scrolling = true;
if (canScrollUp) { *yValue = fmax(*yValue - pageAmount, yMax); }
return true;
case SCANCODE_PAGE_DOWN:
gDjuiChatBox->scrolling = true;
if (canScrollDown) { *yValue = fmin(*yValue + pageAmount, 0); }
return true;
case SCANCODE_ENTER: djui_chat_box_input_enter(gDjuiChatBox->chatInput); return true;
case SCANCODE_ESCAPE: djui_chat_box_input_escape(gDjuiChatBox->chatInput); return true;
default: return djui_inputbox_on_key_down(base, scancode);
}
}
void djui_chat_box_toggle(void) {
if (gDjuiChatBox == NULL) { return; }
gDjuiChatBoxFocus = !gDjuiChatBoxFocus;
djui_chat_box_set_focus_style();
gDjuiChatBox->scrolling = false;
gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;
}
struct DjuiChatBox* djui_chat_box_create(void) {
if (gDjuiChatBox != NULL) {
djui_base_destroy(&gDjuiChatBox->base);
gDjuiChatBox = NULL;
}
struct DjuiChatBox* chatBox = malloc(sizeof(struct DjuiChatBox));
struct DjuiBase* base = &chatBox->base;
djui_base_init(&gDjuiRoot->base, base, djui_chat_box_render, djui_chat_box_destroy);
djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
djui_base_set_size(base, 600, 1.0f);
djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
djui_base_set_color(base, 0, 0, 0, 0);
djui_base_set_padding(base, 0, 8, 8, 8);
struct DjuiRect* chatContainer = djui_rect_create(base);
struct DjuiBase* ccBase = &chatContainer->base;
djui_base_set_size_type(ccBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(ccBase, 1.0f, 0);
djui_base_set_color(ccBase, 0, 0, 0, 0);
chatBox->chatContainer = chatContainer;
struct DjuiFlowLayout* chatFlow = djui_flow_layout_create(ccBase);
struct DjuiBase* cfBase = &chatFlow->base;
djui_base_set_location(cfBase, 0, 0);
djui_base_set_size_type(cfBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(cfBase, 1.0f, 2);
djui_base_set_color(cfBase, 0, 0, 0, 128);
djui_base_set_padding(cfBase, 2, 2, 2, 2);
djui_flow_layout_set_margin(chatFlow, 2);
djui_flow_layout_set_flow_direction(chatFlow, DJUI_FLOW_DIR_UP);
cfBase->addChildrenToHead = true;
cfBase->abandonAfterChildRenderFail = true;
chatBox->chatFlow = chatFlow;
struct DjuiInputbox* chatInput = djui_inputbox_create(base, 200);
struct DjuiBase* ciBase = &chatInput->base;
djui_base_set_size_type(ciBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(ciBase, 1.0f, 32);
djui_base_set_alignment(ciBase, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
djui_interactable_hook_key(&chatInput->base, djui_chat_box_input_on_key_down, djui_inputbox_on_key_up);
chatBox->chatInput = chatInput;
gDjuiChatBox = chatBox;
djui_chat_box_set_focus_style();
return chatBox;
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "djui.h"
#pragma pack(1)
struct DjuiChatBox {
struct DjuiBase base;
struct DjuiRect* chatContainer;
struct DjuiFlowLayout* chatFlow;
struct DjuiInputbox* chatInput;
bool scrolling;
};
extern struct DjuiChatBox* gDjuiChatBox;
extern bool gDjuiChatBoxFocus;
void djui_chat_box_toggle(void);
struct DjuiChatBox* djui_chat_box_create(void);

View file

@ -0,0 +1,91 @@
#include <stdio.h>
#include "pc/network/network.h"
#include "audio_defines.h"
#include "audio/external.h"
#include "game/mario_misc.h"
#include "djui.h"
#define DJUI_CHAT_LIFE_TIME 10.0f
static void djui_chat_message_render(struct DjuiBase* base) {
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
struct DjuiBase* ctBase = &chatMessage->message->base;
f32 seconds = (clock() - chatMessage->createTime) / (f32)CLOCKS_PER_SEC;
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, 64);
djui_base_set_color(ctBase, 255, 255, 255, 255);
djui_text_set_drop_shadow(chatMessage->message, 0, 0, 0, 200);
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, 1.0f, chatMessage->base.height.value);
} else {
djui_base_set_color(base, 0, 0, 0, 150 * f);
djui_base_set_color(ctBase, 255, 255, 255, 255 * f);
djui_text_set_drop_shadow(chatMessage->message, 0, 0, 0, 200 * 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_rect_render(base);
}
static void djui_chat_message_destroy(struct DjuiBase* base) {
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
free(chatMessage);
}
struct DjuiChatMessage* djui_chat_message_create_from(u8 globalIndex, char* message) {
u8* rgb = get_player_color(globalIndex, 0);
u8 rgb2[3] = { 0 };
for (int i = 0; i < 3; i++) { rgb2[i] = fmin((f32)rgb[i] * 1.3f + 32.0f, 255); }
char chatMsg[256] = { 0 };
snprintf(chatMsg, 256, "\\#%02x%02x%02x\\%s:\\#dcdcdc\\ %s", rgb2[0], rgb2[1], rgb2[2], "Player", message);
play_sound((globalIndex == gNetworkPlayerLocal->globalIndex) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gDefaultSoundArgs);
return djui_chat_message_create(chatMsg);
}
struct DjuiChatMessage* djui_chat_message_create(char* message) {
struct DjuiChatMessage* chatMessage = malloc(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);
djui_text_set_drop_shadow(chatText, 0, 0, 0, 200);
chatMessage->message = chatText;
chatMessage->createTime = clock();
// 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;
return chatMessage;
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "djui.h"
#include <time.h>
#pragma pack(1)
struct DjuiChatMessage {
struct DjuiBase base;
struct DjuiText* message;
f32 messageWidth;
clock_t createTime;
};
struct DjuiChatMessage* djui_chat_message_create_from(u8 globalIndex, char* message);
struct DjuiChatMessage* djui_chat_message_create(char* message);

View file

@ -38,10 +38,14 @@ void djui_inputbox_select_all(struct DjuiInputbox* inputbox) {
inputbox->selection[0] = strlen(inputbox->buffer);
}
void djui_inputbox_hook_enter_press(struct DjuiInputbox* inputbox, void (*on_enter_press)(void)) {
void djui_inputbox_hook_enter_press(struct DjuiInputbox* inputbox, void (*on_enter_press)(struct DjuiInputbox*)) {
inputbox->on_enter_press = on_enter_press;
}
void djui_inputbox_hook_escape_press(struct DjuiInputbox* inputbox, void (*on_escape_press)(struct DjuiInputbox*)) {
inputbox->on_escape_press = on_escape_press;
}
static void djui_inputbox_set_default_style(struct DjuiBase* base) {
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
if (inputbox->base.enabled) {
@ -152,7 +156,7 @@ static void djui_inputbox_delete_selection(struct DjuiInputbox *inputbox) {
djui_inputbox_on_change(inputbox);
}
static bool djui_inputbox_on_key_down(struct DjuiBase *base, int scancode) {
bool djui_inputbox_on_key_down(struct DjuiBase *base, int scancode) {
struct DjuiInputbox *inputbox = (struct DjuiInputbox *) base;
u16 *sel = inputbox->selection;
char *msg = inputbox->buffer;
@ -261,13 +265,16 @@ static bool djui_inputbox_on_key_down(struct DjuiBase *base, int scancode) {
if (scancode == SCANCODE_ESCAPE) {
djui_interactable_set_input_focus(NULL);
if (inputbox->on_escape_press) {
inputbox->on_escape_press(inputbox);
}
return true;
}
if (scancode == SCANCODE_ENTER) {
djui_interactable_set_input_focus(NULL);
if (inputbox->on_enter_press) {
inputbox->on_enter_press();
inputbox->on_enter_press(inputbox);
}
return true;
}
@ -275,7 +282,7 @@ static bool djui_inputbox_on_key_down(struct DjuiBase *base, int scancode) {
return true;
}
static void djui_inputbox_on_key_up(struct DjuiBase *base, int scancode) {
void djui_inputbox_on_key_up(struct DjuiBase *base, int scancode) {
switch (scancode) {
case SCANCODE_CONTROL_LEFT: sHeldControl &= ~(1 << 0); break;
case SCANCODE_CONTROL_RIGHT: sHeldControl &= ~(1 << 1); break;

View file

@ -9,12 +9,16 @@ struct DjuiInputbox {
u16 selection[2];
f32 viewX;
struct DjuiColor textColor;
void (*on_enter_press)(void);
void (*on_enter_press)(struct DjuiInputbox*);
void (*on_escape_press)(struct DjuiInputbox*);
};
void djui_inputbox_set_text_color(struct DjuiInputbox* inputbox, u8 r, u8 g, u8 b, u8 a);
void djui_inputbox_set_text(struct DjuiInputbox* inputbox, char* text);
void djui_inputbox_select_all(struct DjuiInputbox* inputbox);
void djui_inputbox_hook_enter_press(struct DjuiInputbox* inputbox, void (*on_enter_press)(void));
void djui_inputbox_hook_enter_press(struct DjuiInputbox* inputbox, void (*on_enter_press)(struct DjuiInputbox*));
void djui_inputbox_hook_escape_press(struct DjuiInputbox* inputbox, void (*on_escape_press)(struct DjuiInputbox*));
bool djui_inputbox_on_key_down(struct DjuiBase* base, int scancode);
void djui_inputbox_on_key_up(struct DjuiBase* base, int scancode);
struct DjuiInputbox* djui_inputbox_create(struct DjuiBase* parent, u16 bufferSize);

View file

@ -9,15 +9,6 @@
#include "audio_defines.h"
#include "audio/external.h"
#define SCANCODE_UP 328
#define SCANCODE_DOWN 336
#define SCANCODE_LEFT 331
#define SCANCODE_RIGHT 333
#define SCANCODE_ENTER 28
#define SCANCODE_SPACE 57
#define SCANCODE_ESCAPE 1
enum PadHoldDirection { PAD_HOLD_DIR_NONE, PAD_HOLD_DIR_UP, PAD_HOLD_DIR_DOWN, PAD_HOLD_DIR_LEFT, PAD_HOLD_DIR_RIGHT };
static enum PadHoldDirection sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
static u16 sKeyboardButtons = 0;
@ -179,9 +170,11 @@ bool djui_interactable_on_key_down(int scancode) {
if (keyFocused) {
bool consume = sInteractableFocus->interactable->on_key_down(sInteractableFocus, scancode);
sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
sKeyboardButtons = 0;
return consume;
if (consume) {
sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
sKeyboardButtons = 0;
return true;
}
}
if (scancode == SCANCODE_ESCAPE) {
@ -189,6 +182,18 @@ bool djui_interactable_on_key_down(int scancode) {
djui_panel_back();
}
if (gDjuiChatBox != NULL && !gDjuiChatBoxFocus) {
bool pressChat = false;
for (int i = 0; i < MAX_BINDS; i++) {
if (scancode == (int)configKeyChat[i]) { pressChat = true; }
}
if (pressChat) {
djui_chat_box_toggle();
return true;
}
}
switch (scancode) {
case SCANCODE_UP: sKeyboardHoldDirection = PAD_HOLD_DIR_UP; return true;
case SCANCODE_DOWN: sKeyboardHoldDirection = PAD_HOLD_DIR_DOWN; return true;
@ -196,6 +201,7 @@ bool djui_interactable_on_key_down(int scancode) {
case SCANCODE_RIGHT: sKeyboardHoldDirection = PAD_HOLD_DIR_RIGHT; return true;
case SCANCODE_ENTER: sKeyboardButtons |= PAD_BUTTON_A; return true;
}
return false;
}

View file

@ -8,6 +8,18 @@
#define MOUSE_BUTTON_1 ((u16)(1 << 0))
#define SCANCODE_UP 328
#define SCANCODE_DOWN 336
#define SCANCODE_LEFT 331
#define SCANCODE_RIGHT 333
#define SCANCODE_PAGE_DOWN 337
#define SCANCODE_PAGE_UP 329
#define SCANCODE_ENTER 28
#define SCANCODE_SPACE 57
#define SCANCODE_ESCAPE 1
#pragma pack(1)
struct DjuiInteractable {
bool enabled;

View file

@ -19,6 +19,8 @@ static void djui_panel_pause_quit(struct DjuiBase* caller) {
}
void djui_panel_pause_create(struct DjuiBase* caller) {
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); }
f32 bodyHeight = 64 * 3 + 16 * 2;
if (Cheats.EnableCheats) { bodyHeight += 64 + 16; }

View file

@ -169,6 +169,46 @@ static void djui_text_read_line(struct DjuiText* text, u16* index, f32* lineWidt
}*/
}
int djui_text_count_lines(struct DjuiText* text, u16 maxLines) {
struct DjuiBaseRect* comp = &text->base.comp;
u16 startIndex = 0;
u16 endIndex = 0;
f32 maxLineWidth = comp->width / ((f32)text->fontScale);
u16 lineCount = 0;
while (text->message[startIndex] != '\0') {
bool onLastLine = lineCount + 1 >= maxLines;
f32 lineWidth;
bool ellipses;
djui_text_read_line(text, &endIndex, &lineWidth, maxLineWidth, onLastLine, &ellipses);
startIndex = endIndex;
lineCount++;
if (onLastLine) { break; }
}
return lineCount;
}
f32 djui_text_find_width(struct DjuiText* text, u16 maxLines) {
struct DjuiBaseRect* comp = &text->base.comp;
u16 startIndex = 0;
u16 endIndex = 0;
f32 maxLineWidth = comp->width / ((f32)text->fontScale);
u16 lineCount = 0;
f32 largestWidth = 0;
while (text->message[startIndex] != '\0') {
bool onLastLine = lineCount + 1 >= maxLines;
f32 lineWidth;
bool ellipses;
djui_text_read_line(text, &endIndex, &lineWidth, maxLineWidth, onLastLine, &ellipses);
largestWidth = fmax(largestWidth, lineWidth);
startIndex = endIndex;
lineCount++;
if (onLastLine) { break; }
}
return largestWidth * text->fontScale;
}
static int djui_text_render_line_parse_escape(struct DjuiText* text, u16 startIndex, u16 endIndex) {
bool parsingColor = text->message[startIndex + 1] == '#';
u16 i = parsingColor ? (startIndex + 1) : startIndex;
@ -298,20 +338,9 @@ static void djui_text_render(struct DjuiBase* base) {
sSavedA = base->color.a;
// count lines
u16 startIndex = 0;
u16 endIndex = 0;
f32 maxLineWidth = comp->width / ((f32)text->fontScale);
u16 lineCount = 0;
u16 maxLines = comp->height / ((f32)text->font->lineHeight * text->fontScale);
while (text->message[startIndex] != '\0') {
bool onLastLine = lineCount + 1 >= maxLines;
f32 lineWidth;
bool ellipses;
djui_text_read_line(text, &endIndex, &lineWidth, maxLineWidth, onLastLine, &ellipses);
startIndex = endIndex;
lineCount++;
if (onLastLine) { break; }
}
f32 maxLineWidth = comp->width / ((f32)text->fontScale);
u16 lineCount = djui_text_count_lines(text, maxLines);
// do vertical alignment
f32 vOffset = 0;
@ -325,8 +354,8 @@ static void djui_text_render(struct DjuiBase* base) {
djui_text_translate(0, vOffset);
// render lines
startIndex = 0;
endIndex = 0;
u16 startIndex = 0;
u16 endIndex = 0;
f32 lineWidth;
u16 lineIndex = 0;
bool ellipses = false;

View file

@ -18,4 +18,7 @@ void djui_text_set_font_scale(struct DjuiText* text, f32 fontScale);
void djui_text_set_drop_shadow(struct DjuiText* text, f32 r, f32 g, f32 b, f32 a);
void djui_text_set_alignment(struct DjuiText* text, enum DjuiHAlign hAlign, enum DjuiVAlign vAlign);
int djui_text_count_lines(struct DjuiText* text, u16 maxLines);
f32 djui_text_find_width(struct DjuiText* text, u16 maxLines);
struct DjuiText* djui_text_create(struct DjuiBase* parent, const char* message);

View file

@ -10,6 +10,7 @@
#endif
#include "pc/configfile.h"
#include "pc/cheats.h"
#include "pc/djui/djui.h"
#include "pc/debuglog.h"
// Mario 64 specific externs
@ -81,6 +82,8 @@ bool network_init(enum NetworkType inNetworkType) {
network_player_connected(NPT_LOCAL, 0);
extern u8* gOverrideEeprom;
gOverrideEeprom = NULL;
djui_chat_box_create();
} else if (gNetworkType == NT_CLIENT) {
network_player_connected(NPT_SERVER, 0);
}
@ -267,6 +270,11 @@ void network_register_mod(char* modName) {
}
void network_shutdown(bool sendLeaving) {
if (gDjuiChatBox != NULL) {
djui_base_destroy(&gDjuiChatBox->base);
gDjuiChatBox = NULL;
}
network_forget_all_reliable();
if (gNetworkType == NT_NONE) { return; }
if (gNetworkSystem == NULL) { LOG_ERROR("no network system attached"); return; }
@ -277,8 +285,3 @@ void network_shutdown(bool sendLeaving) {
gNetworkType = NT_NONE;
}
// TODO: replace
void chat_add_message(char* message) {
LOG_INFO("chat: %s", message);
}

View file

@ -102,6 +102,4 @@ void network_update(void);
void network_register_mod(char* modName);
void network_shutdown(bool sendLeaving);
// TODO: replace
void chat_add_message(char* message);
#endif

View file

@ -183,8 +183,10 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) {
} else {
// display popup
u8* rgb = get_player_color(np->globalIndex, 0);
u8 rgb2[3] = { 0 };
for (int i = 0; i < 3; i++) { rgb2[i] = fmin((f32)rgb[i] * 1.3f + 32.0f, 255); }
char popupMsg[128] = { 0 };
snprintf(popupMsg, 128, "\\#%02x%02x%02x\\Player\\#dcdcdc\\ connected.", rgb[0], rgb[1], rgb[2]);
snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ connected.", rgb2[0], rgb2[1], rgb2[2], "Player");
djui_popup_create(popupMsg, 1);
}
LOG_INFO("player connected, local %d, global %d", i, np->globalIndex);
@ -229,8 +231,10 @@ u8 network_player_disconnected(u8 globalIndex) {
// display popup
u8* rgb = get_player_color(np->globalIndex, 0);
u8 rgb2[3] = { 0 };
for (int i = 0; i < 3; i++) { rgb2[i] = fmin((f32)rgb[i] * 1.3f + 32.0f, 255); }
char popupMsg[128] = { 0 };
snprintf(popupMsg, 128, "\\#%02x%02x%02x\\Player\\#dcdcdc\\ disconnected.", rgb[0], rgb[1], rgb[2]);
snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ disconnected.", rgb2[0], rgb2[1], rgb2[2], "Player");
djui_popup_create(popupMsg, 1);
packet_ordered_clear(globalIndex);

View file

@ -169,7 +169,7 @@ void network_send_custom(u8 customId, bool reliable, bool levelAreaMustMatch, vo
void network_receive_custom(struct Packet* p);
// packet_chat.c
void network_send_chat(char* message, u8 rgb[3]);
void network_send_chat(char* message, u8 globalIndex);
void network_receive_chat(struct Packet* p);
// packet_kick.c

View file

@ -1,6 +1,7 @@
#include <stdio.h>
#include "../network.h"
#include "../reservation_area.h"
#include "pc/djui/djui.h"
#include "pc/debuglog.h"
#ifdef DEVELOPMENT
@ -28,11 +29,11 @@ static void print_network_player_table(void) {
}
#endif
void network_send_chat(char* message, u8 rgb[3]) {
void network_send_chat(char* message, u8 globalIndex) {
u16 messageLength = strlen(message);
struct Packet p;
packet_init(&p, PACKET_CHAT, true, false);
packet_write(&p, rgb, 3 * sizeof(u8));
packet_write(&p, &globalIndex, sizeof(u8));
packet_write(&p, &messageLength, sizeof(u16));
packet_write(&p, message, messageLength * sizeof(u8));
network_send(&p);
@ -45,16 +46,16 @@ void network_send_chat(char* message, u8 rgb[3]) {
void network_receive_chat(struct Packet* p) {
u16 remoteMessageLength = 0;
char remoteMessage[255] = { 0 };
u8 rgb[3] = { 255, 255, 255};
char remoteMessage[256] = { 0 };
u8 globalIndex;
packet_read(p, rgb, 3 * sizeof(u8));
packet_read(p, &globalIndex, sizeof(u8));
packet_read(p, &remoteMessageLength, sizeof(u16));
if (remoteMessageLength > 255) { remoteMessageLength = 254; }
if (remoteMessageLength > 256) { remoteMessageLength = 255; }
packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8));
// add the message
chat_add_message(remoteMessage);
djui_chat_message_create_from(globalIndex, remoteMessage);
LOG_INFO("rx chat: %s", remoteMessage);
/*
#ifdef DEVELOPMENT

View file

@ -178,6 +178,7 @@ void network_receive_join(struct Packet* p) {
network_player_connected(NPT_SERVER, 0);
network_player_connected(NPT_LOCAL, myGlobalIndex);
djui_chat_box_create();
save_file_load_all(TRUE);

View file

@ -323,7 +323,7 @@ void network_receive_player(struct Packet* p) {
// inform of player death
if (oldData.action != ACT_BUBBLED && data.action == ACT_BUBBLED) {
chat_add_message("player died");
//chat_add_message("player died");
}
// action changed, reset timer