mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-29 07:23:01 +00:00
colorize chat messages with player color
This commit is contained in:
parent
109e713689
commit
511b1352b8
8 changed files with 63 additions and 17 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue