From b65e9a35610ad5067a6320e887392ad4fe286d11 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Mon, 27 Dec 2021 21:23:58 -0600 Subject: [PATCH] Text and special symbol packet, fixing linked vector packet size --- .../rpg/text_and_special_symbol_packet.hpp | 44 ++++++ .../scwx/wsr88d/rpg/linked_vector_packet.cpp | 2 +- .../rpg/text_and_special_symbol_packet.cpp | 139 ++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 wxdata/include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp create mode 100644 wxdata/source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp diff --git a/wxdata/include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp b/wxdata/include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp new file mode 100644 index 00000000..bdbbf4dc --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/text_and_special_symbol_packet.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class TextAndSpecialSymbolPacketImpl; + +class TextAndSpecialSymbolPacket : public Packet +{ +public: + explicit TextAndSpecialSymbolPacket(); + ~TextAndSpecialSymbolPacket(); + + TextAndSpecialSymbolPacket(const TextAndSpecialSymbolPacket&) = delete; + TextAndSpecialSymbolPacket& + operator=(const TextAndSpecialSymbolPacket&) = delete; + + TextAndSpecialSymbolPacket(TextAndSpecialSymbolPacket&&) noexcept; + TextAndSpecialSymbolPacket& operator=(TextAndSpecialSymbolPacket&&) noexcept; + + uint16_t packet_code() const; + uint16_t length_of_block() const; + std::optional value_of_text() const; + + size_t data_size() const override; + + bool Parse(std::istream& is) override; + +private: + std::unique_ptr p; +}; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp b/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp index f935d938..4ef3d303 100644 --- a/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp +++ b/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp @@ -85,7 +85,7 @@ bool LinkedVectorPacket::Parse(std::istream& is) p->packetCode_ = ntohs(p->packetCode_); p->lengthOfBlock_ = ntohs(p->lengthOfBlock_); - int vectorSize = static_cast(p->lengthOfBlock_) - 2; + int vectorSize = static_cast(p->lengthOfBlock_) - 4; if (is.eof()) { diff --git a/wxdata/source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp b/wxdata/source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp new file mode 100644 index 00000000..a37e77ed --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/text_and_special_symbol_packet.cpp @@ -0,0 +1,139 @@ +#include + +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rpg::text_and_special_symbol_packet] "; + +class TextAndSpecialSymbolPacketImpl +{ +public: + explicit TextAndSpecialSymbolPacketImpl() : + packetCode_ {}, + lengthOfBlock_ {}, + valueOfText_ {}, + startI_ {}, + startJ_ {}, + characters_ {} {}; + ~TextAndSpecialSymbolPacketImpl() = default; + + uint16_t packetCode_; + uint16_t lengthOfBlock_; + uint16_t valueOfText_; + int16_t startI_; + int16_t startJ_; + + std::vector characters_; +}; + +TextAndSpecialSymbolPacket::TextAndSpecialSymbolPacket() : + p(std::make_unique()) +{ +} +TextAndSpecialSymbolPacket::~TextAndSpecialSymbolPacket() = default; + +TextAndSpecialSymbolPacket::TextAndSpecialSymbolPacket( + TextAndSpecialSymbolPacket&&) noexcept = default; +TextAndSpecialSymbolPacket& TextAndSpecialSymbolPacket::operator=( + TextAndSpecialSymbolPacket&&) noexcept = default; + +uint16_t TextAndSpecialSymbolPacket::packet_code() const +{ + return p->packetCode_; +} + +uint16_t TextAndSpecialSymbolPacket::length_of_block() const +{ + return p->lengthOfBlock_; +} + +std::optional TextAndSpecialSymbolPacket::value_of_text() const +{ + std::optional value; + + if (p->packetCode_ == 8) + { + value = p->valueOfText_; + } + + return value; +} + +size_t TextAndSpecialSymbolPacket::data_size() const +{ + return p->lengthOfBlock_ + 4u; +} + +bool TextAndSpecialSymbolPacket::Parse(std::istream& is) +{ + bool blockValid = true; + + is.read(reinterpret_cast(&p->packetCode_), 2); + is.read(reinterpret_cast(&p->lengthOfBlock_), 2); + + p->packetCode_ = ntohs(p->packetCode_); + p->lengthOfBlock_ = ntohs(p->lengthOfBlock_); + + int vectorSize = static_cast(p->lengthOfBlock_) - 4; + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else if (p->packetCode_ == 8) + { + is.read(reinterpret_cast(&p->valueOfText_), 2); + p->valueOfText_ = ntohs(p->valueOfText_); + + vectorSize -= 2; + } + + is.read(reinterpret_cast(&p->startI_), 2); + is.read(reinterpret_cast(&p->startJ_), 2); + + p->startI_ = ntohs(p->startI_); + p->startJ_ = ntohs(p->startJ_); + + // The number of vectors is equal to the size divided by the number of bytes + // in a vector coordinate + int vectorCount = vectorSize; + char c; + + for (int v = 0; v < vectorCount && !is.eof(); v++) + { + is.get(c); + p->characters_.push_back(c); + } + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else + { + if (p->packetCode_ != 1 && p->packetCode_ != 2 && p->packetCode_ != 8) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid packet code: " << p->packetCode_; + blockValid = false; + } + } + + return blockValid; +} + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx