diff --git a/Source/multi.cpp b/Source/multi.cpp index 1ee83c543..10799f784 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -303,12 +303,11 @@ void HandleAllPackets(int pnum, byte *pData, size_t nSize) void ProcessTmsgs() { - size_t cnt; - TPkt pkt; + uint8_t cnt; + std::unique_ptr msg; - while ((cnt = tmsg_get((byte *)&pkt)) != 0) { - HandleAllPackets(MyPlayerId, (byte *)&pkt, cnt); - } + while ((cnt = tmsg_get(&msg)) != 0) + HandleAllPackets(MyPlayerId, msg.get(), cnt); } void SendPlayerInfo(int pnum, _cmd_id cmd) diff --git a/Source/tmsg.cpp b/Source/tmsg.cpp index d3f938696..b908d1fcd 100644 --- a/Source/tmsg.cpp +++ b/Source/tmsg.cpp @@ -3,67 +3,61 @@ * * Implementation of functionality transmitting chat messages. */ +#include #include "tmsg.h" - #include "diablo.h" namespace devilution { namespace { -TMsg *sgpTimedMsgHead; +struct TMsg { + uint32_t time; + std::unique_ptr body; + uint8_t len; + + TMsg(uint32_t time, byte *data, uint8_t len) + : time(time) + , body(new byte[len]) + , len(len) + { + memcpy(body.get(), data, len); + } +}; + +std::list TimedMsgList; } // namespace -size_t tmsg_get(byte *pbMsg) +uint8_t tmsg_get(std::unique_ptr *msg) { - TMsg *head; - - if (sgpTimedMsgHead == nullptr) + if (TimedMsgList.empty()) return 0; - if ((int)(sgpTimedMsgHead->hdr.dwTime - SDL_GetTicks()) >= 0) + TMsg &head = TimedMsgList.front(); + if ((int)(head.time - SDL_GetTicks()) >= 0) return 0; - head = sgpTimedMsgHead; - sgpTimedMsgHead = head->hdr.pNext; - size_t len = head->hdr.bLen; - // BUGFIX: ignores dwMaxLen - memcpy(pbMsg, head->body, len); - std::free(head); + + uint8_t len = head.len; + *msg = std::move(head.body); + TimedMsgList.pop_front(); return len; } -void tmsg_add(byte *pbMsg, uint8_t bLen) +void tmsg_add(byte *msg, uint8_t len) { - TMsg **tail; - - TMsg *msg = static_cast(std::malloc(bLen + sizeof(*msg))); - if (msg == nullptr) - app_fatal("Failed to allocate memory"); - msg->hdr.pNext = nullptr; - msg->hdr.dwTime = SDL_GetTicks() + gnTickDelay * 10; - msg->hdr.bLen = bLen; - memcpy(msg->body, pbMsg, bLen); - for (tail = &sgpTimedMsgHead; *tail != nullptr; tail = &(*tail)->hdr.pNext) { - ; - } - *tail = msg; + uint32_t time = SDL_GetTicks() + gnTickDelay * 10; + TimedMsgList.emplace_back(time, msg, len); } void tmsg_start() { - assert(!sgpTimedMsgHead); + assert(TimedMsgList.empty()); } void tmsg_cleanup() { - TMsg *next; - - while (sgpTimedMsgHead != nullptr) { - next = sgpTimedMsgHead->hdr.pNext; - std::free(sgpTimedMsgHead); - sgpTimedMsgHead = next; - } + TimedMsgList.clear(); } } // namespace devilution diff --git a/Source/tmsg.h b/Source/tmsg.h index 1c7937220..a57e50f1c 100644 --- a/Source/tmsg.h +++ b/Source/tmsg.h @@ -6,28 +6,14 @@ #pragma once #include +#include #include "utils/stdcompat/cstddef.hpp" namespace devilution { -#pragma pack(push, 1) -struct TMsgHdr { - struct TMsg *pNext; - int32_t dwTime; - uint8_t bLen; -}; - -struct TMsg { - TMsgHdr hdr; - // this is actually alignment padding, but the message body is appended to the struct - // so it's convenient to use byte-alignment and name it "body" - byte body[3]; -}; -#pragma pack(pop) - -size_t tmsg_get(byte *pbMsg); -void tmsg_add(byte *pbMsg, uint8_t bLen); +uint8_t tmsg_get(std::unique_ptr *msg); +void tmsg_add(byte *msg, uint8_t bLen); void tmsg_start(); void tmsg_cleanup();