diff --git a/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp b/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp index fc4f8eff..4e275790 100644 --- a/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp +++ b/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp @@ -26,9 +26,9 @@ public: LinkedVectorPacket(LinkedVectorPacket&&) noexcept; LinkedVectorPacket& operator=(LinkedVectorPacket&&) noexcept; - uint16_t packet_code() const; - uint16_t length_of_block() const; - uint16_t value_of_vector() const; + uint16_t packet_code() const; + uint16_t length_of_block() const; + std::optional value_of_vector() const; size_t data_size() const override; diff --git a/wxdata/include/scwx/wsr88d/rpg/unlinked_vector_packet.hpp b/wxdata/include/scwx/wsr88d/rpg/unlinked_vector_packet.hpp new file mode 100644 index 00000000..ac2d3e5f --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/unlinked_vector_packet.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class UnlinkedVectorPacketImpl; + +class UnlinkedVectorPacket : public Packet +{ +public: + explicit UnlinkedVectorPacket(); + ~UnlinkedVectorPacket(); + + UnlinkedVectorPacket(const UnlinkedVectorPacket&) = delete; + UnlinkedVectorPacket& operator=(const UnlinkedVectorPacket&) = delete; + + UnlinkedVectorPacket(UnlinkedVectorPacket&&) noexcept; + UnlinkedVectorPacket& operator=(UnlinkedVectorPacket&&) noexcept; + + uint16_t packet_code() const; + uint16_t length_of_block() const; + std::optional value_of_vector() 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/include/scwx/wsr88d/rpg/vector2d.hpp b/wxdata/include/scwx/wsr88d/rpg/vector2d.hpp deleted file mode 100644 index 87f3c4b8..00000000 --- a/wxdata/include/scwx/wsr88d/rpg/vector2d.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace scwx -{ -namespace wsr88d -{ -namespace rpg -{ - -class Vector2DImpl; - -class Vector2D : public Message -{ -public: - explicit Vector2D(); - ~Vector2D(); - - Vector2D(const Vector2D&) = delete; - Vector2D& operator=(const Vector2D&) = delete; - - Vector2D(Vector2D&&) noexcept; - Vector2D& operator=(Vector2D&&) noexcept; - - int16_t start_i() const; - int16_t start_j() const; - int16_t end_i() const; - int16_t end_j() const; - - size_t data_size() const override; - - bool Parse(std::istream& is) override; - - static constexpr size_t SIZE = 8u; - -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 07420020..3f74ff51 100644 --- a/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp +++ b/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp @@ -1,9 +1,6 @@ #include -#include -#include #include -#include #include #include @@ -22,14 +19,23 @@ class LinkedVectorPacketImpl { public: explicit LinkedVectorPacketImpl() : - packetCode_ {}, lengthOfBlock_ {}, valueOfVector_ {}, vectorList_ {} {}; + packetCode_ {}, + lengthOfBlock_ {}, + valueOfVector_ {}, + startI_ {}, + startJ_ {}, + endI_ {}, + endJ_ {} {}; ~LinkedVectorPacketImpl() = default; uint16_t packetCode_; uint16_t lengthOfBlock_; uint16_t valueOfVector_; - std::vector vectorList_; + uint16_t startI_; + uint16_t startJ_; + std::vector endI_; + std::vector endJ_; }; LinkedVectorPacket::LinkedVectorPacket() : @@ -52,9 +58,16 @@ uint16_t LinkedVectorPacket::length_of_block() const return p->lengthOfBlock_; } -uint16_t LinkedVectorPacket::value_of_vector() const +std::optional LinkedVectorPacket::value_of_vector() const { - return p->valueOfVector_; + std::optional value; + + if (p->packetCode_ == 9) + { + value = p->valueOfVector_; + } + + return value; } size_t LinkedVectorPacket::data_size() const @@ -72,7 +85,7 @@ bool LinkedVectorPacket::Parse(std::istream& is) p->packetCode_ = ntohs(p->packetCode_); p->lengthOfBlock_ = ntohs(p->lengthOfBlock_); - size_t vectorSize = p->lengthOfBlock_; + int vectorSize = static_cast(p->lengthOfBlock_) - 2; if (is.eof()) { @@ -87,15 +100,28 @@ bool LinkedVectorPacket::Parse(std::istream& is) vectorSize -= 2; } - // The number of vectors is equal to the size divided by the number of bytes - // in a vector - size_t vectorCount = Vector2D::SIZE / 8; + is.read(reinterpret_cast(&p->startI_), 2); + is.read(reinterpret_cast(&p->startJ_), 2); - for (size_t v = 0; v < vectorCount && !is.eof(); v++) + 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 / 4; + uint16_t endI; + uint16_t endJ; + + for (int v = 0; v < vectorCount && !is.eof(); v++) { - Vector2D vector; - vector.Parse(is); - p->vectorList_.push_back(std::move(vector)); + is.read(reinterpret_cast(&endI), 2); + is.read(reinterpret_cast(&endJ), 2); + + endI = ntohs(endI); + endJ = ntohs(endJ); + + p->endI_.push_back(endI); + p->endJ_.push_back(endJ); } if (is.eof()) diff --git a/wxdata/source/scwx/wsr88d/rpg/unlinked_vector_packet.cpp b/wxdata/source/scwx/wsr88d/rpg/unlinked_vector_packet.cpp new file mode 100644 index 00000000..1a04a937 --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/unlinked_vector_packet.cpp @@ -0,0 +1,150 @@ +#include + +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rpg::unlinked_vector_packet] "; + +class UnlinkedVectorPacketImpl +{ +public: + explicit UnlinkedVectorPacketImpl() : + packetCode_ {}, + lengthOfBlock_ {}, + valueOfVector_ {}, + beginI_ {}, + beginJ_ {}, + endI_ {}, + endJ_ {} {}; + ~UnlinkedVectorPacketImpl() = default; + + uint16_t packetCode_; + uint16_t lengthOfBlock_; + uint16_t valueOfVector_; + + std::vector beginI_; + std::vector beginJ_; + std::vector endI_; + std::vector endJ_; +}; + +UnlinkedVectorPacket::UnlinkedVectorPacket() : + p(std::make_unique()) +{ +} +UnlinkedVectorPacket::~UnlinkedVectorPacket() = default; + +UnlinkedVectorPacket::UnlinkedVectorPacket(UnlinkedVectorPacket&&) noexcept = + default; +UnlinkedVectorPacket& +UnlinkedVectorPacket::operator=(UnlinkedVectorPacket&&) noexcept = default; + +uint16_t UnlinkedVectorPacket::packet_code() const +{ + return p->packetCode_; +} + +uint16_t UnlinkedVectorPacket::length_of_block() const +{ + return p->lengthOfBlock_; +} + +std::optional UnlinkedVectorPacket::value_of_vector() const +{ + std::optional value; + + if (p->packetCode_ == 10) + { + value = p->valueOfVector_; + } + + return value; +} + +size_t UnlinkedVectorPacket::data_size() const +{ + return p->lengthOfBlock_ + 4u; +} + +bool UnlinkedVectorPacket::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_); + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else if (p->packetCode_ == 10) + { + is.read(reinterpret_cast(&p->valueOfVector_), 2); + p->valueOfVector_ = ntohs(p->valueOfVector_); + + vectorSize -= 2; + } + + // The number of vectors is equal to the size divided by the number of bytes + // in a vector + int vectorCount = vectorSize / 8; + uint16_t beginI; + uint16_t beginJ; + uint16_t endI; + uint16_t endJ; + + for (int v = 0; v < vectorCount && !is.eof(); v++) + { + is.read(reinterpret_cast(&beginI), 2); + is.read(reinterpret_cast(&beginJ), 2); + is.read(reinterpret_cast(&endI), 2); + is.read(reinterpret_cast(&endJ), 2); + + beginI = ntohs(beginI); + beginJ = ntohs(beginJ); + endI = ntohs(endI); + endJ = ntohs(endJ); + + p->beginI_.push_back(beginI); + p->beginJ_.push_back(beginJ); + p->endI_.push_back(endI); + p->endJ_.push_back(endJ); + } + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else + { + if (p->packetCode_ != 7 && p->packetCode_ != 10) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid packet code: " << p->packetCode_; + blockValid = false; + } + } + + return blockValid; +} + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/vector2d.cpp b/wxdata/source/scwx/wsr88d/rpg/vector2d.cpp deleted file mode 100644 index 9a86effa..00000000 --- a/wxdata/source/scwx/wsr88d/rpg/vector2d.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include - -#include -#include -#include -#include - -#include - -namespace scwx -{ -namespace wsr88d -{ -namespace rpg -{ - -static const std::string logPrefix_ = "[scwx::wsr88d::rpg::vector2d] "; - -class Vector2DImpl -{ -public: - explicit Vector2DImpl() : startI_ {}, startJ_ {}, endI_ {}, endJ_ {} {}; - ~Vector2DImpl() = default; - - int16_t startI_; - int16_t startJ_; - int16_t endI_; - int16_t endJ_; -}; - -Vector2D::Vector2D() : p(std::make_unique()) {} -Vector2D::~Vector2D() = default; - -Vector2D::Vector2D(Vector2D&&) noexcept = default; -Vector2D& Vector2D::operator=(Vector2D&&) noexcept = default; - -int16_t Vector2D::start_i() const -{ - return p->startI_; -} - -int16_t Vector2D::start_j() const -{ - return p->startJ_; -} - -int16_t Vector2D::end_i() const -{ - return p->endI_; -} - -int16_t Vector2D::end_j() const -{ - return p->endJ_; -} - -size_t Vector2D::data_size() const -{ - return SIZE; -} - -bool Vector2D::Parse(std::istream& is) -{ - bool blockValid = true; - - is.read(reinterpret_cast(&p->startI_), 2); - is.read(reinterpret_cast(&p->startJ_), 2); - is.read(reinterpret_cast(&p->endI_), 2); - is.read(reinterpret_cast(&p->endJ_), 2); - - p->startI_ = ntohs(p->startI_); - p->startJ_ = ntohs(p->startJ_); - p->endI_ = ntohs(p->endI_); - p->endJ_ = ntohs(p->endJ_); - - if (is.eof()) - { - BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; - blockValid = false; - } - - return blockValid; -} - -} // namespace rpg -} // namespace wsr88d -} // namespace scwx