colorize chat messages with player color

This commit is contained in:
fgsfds 2021-04-06 02:30:37 +03:00
parent 109e713689
commit 511b1352b8
8 changed files with 63 additions and 17 deletions

View file

@ -5,6 +5,7 @@
#include "chat.h"
#include "game_init.h"
#include "ingame_menu.h"
#include "mario_misc.h"
#include "segment2.h"
#include "gfx_dimensions.h"
#include "config.h"
@ -23,6 +24,7 @@ struct ChatMessage {
u8 dialog[CHAT_DIALOG_MAX];
enum ChatMessageType type;
u16 life;
u8 color[3];
};
static char inputMessage[CHAT_DIALOG_MAX] = { 0 };
@ -73,18 +75,31 @@ static void render_chat_message(struct ChatMessage* chatMessage, u8 index) {
case CMT_LOCAL: textR = 200; textG = 200; textB = 255; break;
case CMT_INPUT: textR = 0; textG = 0; textB = 0; break;
case CMT_SYSTEM: textR = 255; textG = 255; textB = 190; break;
default: textR = 255; textG = 255; textB = 255;
default: textR = 255; textG = 255; textB = 255; break;
}
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
gDPSetEnvColor(gDisplayListHead++, textR, textG, textB, 255 * alphaScale);
print_generic_string(CHAT_X, CHAT_Y, chatMessage->dialog);
if (chatMessage->type == CMT_REMOTE || chatMessage->type == CMT_SYSTEM) {
// if it's someone else's message, highlight the icon with their color
u8 starR = chatMessage->color[0];
u8 starG = chatMessage->color[1];
u8 starB = chatMessage->color[2];
gDPSetEnvColor(gDisplayListHead++, starR, starG, starB, 255 * alphaScale);
create_dl_translation_matrix(MENU_MTX_PUSH, CHAT_X, CHAT_Y, 0.0f);
render_generic_char(chatMessage->dialog[0]);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
}
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
}
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
void chat_add_message_ext(char* ascii, enum ChatMessageType chatMessageType, const u8 color[3]) {
u8 character = '?';
switch (chatMessageType) {
case CMT_INPUT:
@ -98,10 +113,18 @@ void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
str_ascii_to_dialog(ascii, &msg->dialog[2], MIN(strlen(ascii), CHAT_DIALOG_MAX - 3));
msg->life = (sSelectedFileNum != 0) ? CHAT_LIFE_MAX : CHAT_LIFE_MAX / 3;
msg->type = chatMessageType;
msg->color[0] = color[0];
msg->color[1] = color[1];
msg->color[2] = color[2];
onMessageIndex = (onMessageIndex + 1) % CHAT_MESSAGES_MAX;
play_sound((msg->type == CMT_LOCAL) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gDefaultSoundArgs);
}
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
const u8 defaultColor[3] = { 255, 255, 255 };
chat_add_message_ext(ascii, chatMessageType, defaultColor);
}
static void chat_stop_input(void) {
sInChatInput = FALSE;
keyboard_stop_text_input();
@ -112,7 +135,8 @@ static void chat_send_input(void) {
keyboard_stop_text_input();
if (strlen(gTextInput) == 0) { return; }
chat_add_message(gTextInput, CMT_LOCAL);
network_send_chat(gTextInput);
// our message has the same color as our shirt
network_send_chat(gTextInput, get_player_color(gNetworkPlayerLocal->globalIndex, 0));
}
void chat_start_input(void) {

View file

@ -10,6 +10,7 @@ enum ChatMessageType {
void render_chat(void);
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType);
void chat_add_message_ext(char* ascii, enum ChatMessageType chatMessageType, const u8 color[3]);
void chat_start_input(void);
#endif

View file

@ -53,8 +53,8 @@ enum UnlockDoorStarStates {
};
struct PlayerColor {
Lights1 pants;
Lights1 shirt;
Lights1 pants;
};
/**
@ -80,13 +80,13 @@ struct GraphNodeObject gMirrorMario[MAX_PLAYERS]; // copy of Mario's geo node f
struct PlayerColor gPlayerColors[MAX_PLAYERS] = {
// default mario
{
gdSPDefLights1(0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x28, 0x28, 0x28),
gdSPDefLights1(0x7f, 0x00, 0x00, 0xff, 0x00, 0x00, 0x28, 0x28, 0x28),
gdSPDefLights1(0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x28, 0x28, 0x28),
},
// default luigi
{
gdSPDefLights1(0x00, 0x00, 0x7f, 0x00, 0x00, 0xfe, 0x28, 0x28, 0x28),
gdSPDefLights1(0x00, 0x4c, 0x00, 0x00, 0x98, 0x00, 0x28, 0x28, 0x28),
gdSPDefLights1(0x00, 0x00, 0x7f, 0x00, 0x00, 0xfe, 0x28, 0x28, 0x28),
},
};
@ -101,7 +101,7 @@ struct PlayerColor gPlayerColors[MAX_PLAYERS] = {
* The 4th component is the shade factor (difference between ambient and diffuse),
* usually set to 1.
*/
void set_player_colors(u8 globalIndex, const u8 pants[4], const u8 shirt[4]) {
void set_player_colors(u8 globalIndex, const u8 shirt[4], const u8 pants[4]) {
const u8 pAmb[3] = { pants[0] >> pants[4], pants[1] >> pants[4], pants[2] >> pants[4] };
const u8 sAmb[3] = { shirt[0] >> shirt[4], shirt[1] >> shirt[4], shirt[2] >> shirt[4] };
gPlayerColors[globalIndex].pants =
@ -110,6 +110,20 @@ void set_player_colors(u8 globalIndex, const u8 pants[4], const u8 shirt[4]) {
(Lights1) gdSPDefLights1(sAmb[0], sAmb[1], sAmb[2], shirt[0], shirt[1], shirt[2], 0x28, 0x28, 0x28);
}
/**
* Return the specified color for player globalIndex.
* 0 = shirt, 1 = pants
* Returns RGB, not RGBA!
*/
u8 *get_player_color(u8 globalIndex, const int which) {
if (globalIndex >= MAX_PLAYERS)
globalIndex = 0;
if (which == 0)
return gPlayerColors[globalIndex].shirt.l[0].l.col;
else
return gPlayerColors[globalIndex].pants.l[0].l.col;
}
/**
* Geo node script that draws Mario's head on the title screen.
*/

View file

@ -9,7 +9,9 @@
extern struct GraphNodeObject gMirrorMario[MAX_PLAYERS];
extern struct MarioBodyState gBodyStates[MAX_PLAYERS];
void set_player_colors(u8 globalIndex, const u8 pants[4], const u8 shirt[4]);
void set_player_colors(u8 globalIndex, const u8 shirt[4], const u8 pants[4]);
u8 *get_player_color(u8 globalIndex, const int which);
Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *c);
void bhv_toad_message_loop(void);
void bhv_toad_message_init(void);

View file

@ -1,6 +1,7 @@
#include <stdio.h>
#include "network_player.h"
#include "game/chat.h"
#include "game/mario_misc.h"
#include "pc/debuglog.h"
struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 };
@ -105,7 +106,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) {
gNetworkSystem->save_id(i);
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", CMT_SYSTEM); }
else { chat_add_message_ext("player connected", CMT_SYSTEM, get_player_color(np->globalIndex, 0)); }
LOG_INFO("player connected, local %d, global %d", i, np->globalIndex);
extern s16 sCurrPlayMode;
if (gNetworkType == NT_SERVER && sCurrPlayMode == PLAY_MODE_SYNC_LEVEL) {
@ -142,7 +143,7 @@ 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", CMT_SYSTEM);
chat_add_message_ext("player disconnected", CMT_SYSTEM, get_player_color(globalIndex, 0));
return i;
}
return UNKNOWN_GLOBAL_INDEX;

View file

@ -141,7 +141,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);
void network_send_chat(char* message, u8 rgb[3]);
void network_receive_chat(struct Packet* p);
// packet_kick.c

View file

@ -17,10 +17,11 @@ static void print_sync_object_table(void) {
}
#endif
void network_send_chat(char* message) {
void network_send_chat(char* message, u8 rgb[3]) {
u16 messageLength = strlen(message);
struct Packet p;
packet_init(&p, PACKET_CHAT, true, false);
packet_write(&p, rgb, 3 * sizeof(u8));
packet_write(&p, &messageLength, sizeof(u16));
packet_write(&p, message, messageLength * sizeof(u8));
network_send(&p);
@ -34,13 +35,15 @@ void network_send_chat(char* message) {
void network_receive_chat(struct Packet* p) {
u16 remoteMessageLength = 0;
char remoteMessage[255] = { 0 };
u8 rgb[3] = { 255, 255, 255};
packet_read(p, rgb, 3 * sizeof(u8));
packet_read(p, &remoteMessageLength, sizeof(u16));
if (remoteMessageLength > 255) { remoteMessageLength = 254; }
packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8));
// add the message
chat_add_message(remoteMessage, CMT_REMOTE);
chat_add_message_ext(remoteMessage, CMT_REMOTE, rgb);
LOG_INFO("rx chat: %s", remoteMessage);
#ifdef DEVELOPMENT

View file

@ -10,6 +10,7 @@
#include "engine/surface_collision.h"
#include "game/object_list_processor.h"
#include "game/chat.h"
#include "game/mario_misc.h"
#include "pc/configfile.h"
#pragma pack(1)
@ -336,7 +337,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", CMT_SYSTEM);
chat_add_message_ext("player died", CMT_SYSTEM, get_player_color(globalIndex, 0));
}
// action changed, reset timer