From 9a4e4354f11500a67912e1bc3fa99d8eb9d2cc8f Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Sun, 31 May 2026 19:56:19 +0200 Subject: [PATCH] [proximity chat] general improvements --- src/pc/network/packets/packet.h | 2 +- src/pc/network/packets/packet_join.c | 7 ++++++ src/pc/proximity_chat.c | 32 +++++++++++++++++++++------- src/pc/proximity_chat.h | 3 ++- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index f66e7af88..535f1fbcb 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -7,7 +7,7 @@ #include #include -#define PACKET_LENGTH 4096 +#define PACKET_LENGTH 3000 #define PACKET_DESTINATION_BROADCAST ((u8)-1) #define PACKET_DESTINATION_SERVER ((u8)-2) diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 0f1602352..0a2ea5116 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -26,6 +26,7 @@ #include "pc/lua/smlua.h" #include "pc/configfile.h" #include "pc/lua/utils/smlua_misc_utils.h" +#include "pc/network/coopnet/coopnet.h" extern u8* gOverrideEeprom; static u8 eeprom[512] = { 0 }; @@ -123,6 +124,7 @@ void network_send_join(struct Packet* joinRequestPacket) { packet_write(&p, &gServerSettings.bubbleDeath, sizeof(u8)); packet_write(&p, &gServerSettings.headlessServer, sizeof(u8)); packet_write(&p, &gServerSettings.nametags, sizeof(u8)); + packet_write(&p, &gServerSettings.proximityChat, sizeof(u8)); packet_write(&p, &gServerSettings.maxPlayers, sizeof(u8)); packet_write(&p, &gServerSettings.pauseAnywhere, sizeof(u8)); packet_write(&p, &gServerSettings.pvpType, sizeof(u8)); @@ -176,11 +178,16 @@ void network_receive_join(struct Packet* p) { packet_read(p, &gServerSettings.bubbleDeath, sizeof(u8)); packet_read(p, &gServerSettings.headlessServer, sizeof(u8)); packet_read(p, &gServerSettings.nametags, sizeof(u8)); + packet_read(p, &gServerSettings.proximityChat, sizeof(u8)); packet_read(p, &gServerSettings.maxPlayers, sizeof(u8)); packet_read(p, &gServerSettings.pauseAnywhere, sizeof(u8)); packet_read(p, &gServerSettings.pvpType, sizeof(u8)); packet_read(p, eeprom, sizeof(u8) * 512); + // force disable proximity chat if in a public lobby + if (gNetworkSystem == &gNetworkSystemCoopNet && gCoopNetPassword[0] == 0) + gServerSettings.proximityChat = false; + network_player_connected(NPT_SERVER, 0, 0, &DEFAULT_MARIO_PALETTE, "Player", "0"); network_player_connected(NPT_LOCAL, myGlobalIndex, configPlayerModel, &configPlayerPalette, configPlayerName, get_local_discord_id()); djui_chat_box_create(); diff --git a/src/pc/proximity_chat.c b/src/pc/proximity_chat.c index f0736099a..8ad9be7c7 100644 --- a/src/pc/proximity_chat.c +++ b/src/pc/proximity_chat.c @@ -16,6 +16,8 @@ #define FRAME_SIZE 960 #define STEREO_SPREAD 0.75 #define DECAY_TIME 20 +#define MIN_FRAMES_REQUIRED 2 +#define MAX_FRAMES 4 #define HEARING_RADIUS 8192 #define FULL_VOL_RADIUS 1024 @@ -28,7 +30,8 @@ typedef struct { } Buffer; static struct { - float volume; + bool muted; + u32 volume; Buffer audio; union { OpusEncoder* encoder; @@ -96,6 +99,14 @@ static void buffer_write(Buffer* buffer, u32 bytes, void* data) { if (buffer->size > buffer->capacity) buffer->size = buffer->capacity; } +static void buffer_drain(Buffer* buffer) { + buffer->head = buffer->tail = buffer->size = 0; +} + +static u32 proxchat_num_frames_in_buffer(Buffer* buffer) { + return buffer->size / FRAME_SIZE / sizeof(s16); +} + static bool proxchat_is_ingame(s32 id) { return gNetworkPlayers[id].connected && gNetworkPlayers[id].currLevelNum == gNetworkPlayers[0].currLevelNum @@ -161,13 +172,13 @@ static void proxchat_callback(const u8* input, u32 bytes) { !gServerSettings.proximityChat || proxchat_muted || is_below_threshold() ) { // drain the pcm buffer - buffer_read(&client->audio, client->audio.size, NULL); + buffer_drain(&client->audio); return; } buffer_write(&client->audio, bytes, samples); - if (client->audio.size >= FRAME_SIZE * sizeof(s16) * 2) + if (proxchat_num_frames_in_buffer(&client->audio) >= MIN_FRAMES_REQUIRED) network_send_proxchat_frame(); } @@ -190,8 +201,8 @@ void proxchat_init() { } else proxchat_error[i] = PROXCHAT_ERR_NONE; - players[i].audio.capacity = FRAME_SIZE * sizeof(s16) * 4; - players[i].audio.dynamic = true; + players[i].audio.capacity = FRAME_SIZE * MAX_FRAMES * sizeof(s16); + players[i].audio.dynamic = false; players[i].volume = 1; } @@ -215,7 +226,7 @@ bool proxchat_inited() { return inited; } -f32* proxchat_player_volume(s32 id) { +u32* proxchat_player_volume(s32 id) { return &players[id].volume; } @@ -259,7 +270,12 @@ void proxchat_mix(s16* out_pcm, u32 num_out_samples) { // skip over player 0 because thats the client for (s32 i = 1; i < MAX_PLAYERS; i++) { - if (!proxchat_is_ingame(i)) continue; + if (!proxchat_is_ingame(i)) { + buffer_drain(&players[i].audio); + continue; + } + + if (proxchat_num_frames_in_buffer(&players[i].audio) < MIN_FRAMES_REQUIRED) continue; float volume; float dist = vec3f_dist(gMarioStates[i].pos, gMarioState->pos); @@ -291,7 +307,7 @@ void proxchat_mix(s16* out_pcm, u32 num_out_samples) { for (s32 s = 0; s < num_samples * 2; s++) { float pan_factor = s % 2 == 0 ? vol_left : vol_right; - s32 mixed_sample = mixed[s] + (s16)(player_pcm[(int)(s / 2)] * pan_factor * volume * players[i].volume * configProxchatVolume / 127.f); + s32 mixed_sample = mixed[s] + (s16)(player_pcm[(int)(s / 2)] * pan_factor * volume * (players[i].volume / 100.f) * (configProxchatVolume / 127.f)); mixed[s] = mixed_sample > 32767 ? 32767 : mixed_sample < -32767 ? -32767 : mixed_sample; } } diff --git a/src/pc/proximity_chat.h b/src/pc/proximity_chat.h index 31158a0b8..dffbc401b 100644 --- a/src/pc/proximity_chat.h +++ b/src/pc/proximity_chat.h @@ -27,7 +27,8 @@ void proxchat_shutdown(); const Texture* proxchat_get_microphone_texture(); -f32* proxchat_player_volume(s32 id); +bool* proxchat_player_muted(s32 id); +u32* proxchat_player_volume(s32 id); bool proxchat_player_is_talking(s32 id); u32 proxchat_encode_audio(u8* packet, u32 max_size);