Big net::msg conversion
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
#include "net_msg.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "q_stdinc.hpp"
|
||||
#include "quakedef.hpp"
|
||||
#include "common.hpp"
|
||||
#include "mathlib.hpp"
|
||||
|
||||
namespace net {
|
||||
void msg::write_lores_coord(const float f) {
|
||||
write_short(static_cast<short>(std::round(f * 8)));
|
||||
}
|
||||
|
||||
void msg::write_hires_coord(const float f) {
|
||||
write_short(static_cast<short>(f));
|
||||
write_byte(static_cast<int>(f * 255) % 255);
|
||||
}
|
||||
|
||||
std::optional<float> msg::read_lores_coord() {
|
||||
const auto c = read_short();
|
||||
|
||||
if (!c.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return c.value() * (1.0 / 8);
|
||||
}
|
||||
|
||||
std::optional<float> msg::read_hires_coord() {
|
||||
const auto c = read_short();
|
||||
const auto d = read_byte();
|
||||
|
||||
if (!c.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return c.value() + (d.value() * (1.0 / 255));
|
||||
}
|
||||
|
||||
void msg::clear() {
|
||||
_data.clear();
|
||||
_eos = false;
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
void msg::write_char(const char c) {
|
||||
_data.push_back(c);
|
||||
}
|
||||
|
||||
void msg::write_byte(const std::uint8_t b) {
|
||||
_data.push_back(b);
|
||||
}
|
||||
|
||||
void msg::write_short(const short s) {
|
||||
_data.push_back(s & 0xFF);
|
||||
_data.push_back((s >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
void msg::write_long(const int l) {
|
||||
_data.push_back(l & 0xFF);
|
||||
_data.push_back((l >> 8) & 0xFF);
|
||||
_data.push_back((l >> 16) & 0xFF);
|
||||
_data.push_back((l >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
void msg::write_float(const float f) {
|
||||
write_long(std::bit_cast<std::int32_t>(f));
|
||||
}
|
||||
|
||||
void msg::write_string(const std::string_view s) {
|
||||
if (!s.empty()) {
|
||||
for (const auto &c: s) {
|
||||
_data.push_back(c);
|
||||
}
|
||||
}
|
||||
_data.push_back('\0');
|
||||
}
|
||||
|
||||
static rmq_flags operator&(rmq_flags lhs, rmq_flags rhs) {
|
||||
return static_cast<rmq_flags>(static_cast<int>(lhs) & static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
void msg::write_coord(const float f, const rmq_flags flags) {
|
||||
if ((flags & rmq_flags::float_coord) != rmq_flags::none) {
|
||||
write_float(f);
|
||||
} else if ((flags & rmq_flags::int_coord) != rmq_flags::none) {
|
||||
write_long(static_cast<int>(std::round(f * 16)));
|
||||
} else if ((flags & rmq_flags::hires_coord) != rmq_flags::none) {
|
||||
write_hires_coord(f);
|
||||
} else {
|
||||
write_lores_coord(f);
|
||||
}
|
||||
}
|
||||
|
||||
void msg::write_angle(const float f, const rmq_flags flags) {
|
||||
if ((flags & rmq_flags::float_angle) != rmq_flags::none) {
|
||||
write_float(f);
|
||||
} else if ((flags & rmq_flags::short_angle) != rmq_flags::none) {
|
||||
const auto rounded = static_cast<int>(std::round(f * 65536.0 / 360.0));
|
||||
write_short(static_cast<short>(rounded & 65535));
|
||||
} else {
|
||||
const auto rounded = static_cast<int>(std::round(f * 256.0 / 360.0));
|
||||
write_byte(static_cast<std::uint8_t>(rounded & 255));
|
||||
}
|
||||
}
|
||||
|
||||
void msg::write_angle_16(const float f, const rmq_flags flags) {
|
||||
if ((flags & rmq_flags::float_angle) != rmq_flags::none) {
|
||||
write_float(f);
|
||||
} else {
|
||||
const auto rounded = static_cast<int>(std::round(f * 65536.0 / 360.0));
|
||||
write_short(static_cast<short>(rounded & 65535));
|
||||
}
|
||||
}
|
||||
|
||||
void msg::begin_reading() {
|
||||
_offset = 0;
|
||||
_eos = false;
|
||||
}
|
||||
|
||||
std::optional<char> msg::read_char() {
|
||||
if (_eos || _offset + 1 > _data.size()) {
|
||||
_eos = true;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return _data[_offset++];
|
||||
}
|
||||
|
||||
std::optional<std::uint8_t> msg::read_byte() {
|
||||
if (_eos || _offset + 1 > _data.size()) {
|
||||
_eos = true;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return _data[_offset++];
|
||||
}
|
||||
|
||||
std::optional<short> msg::read_short() {
|
||||
if (_eos || _offset + 2 > _data.size()) {
|
||||
_eos = true;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto res = static_cast<short>(_data[_offset] + (_data[_offset + 1] << 8));
|
||||
|
||||
_offset += 2;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::optional<int> msg::read_long() {
|
||||
if (_eos || _offset + 4 > _data.size()) {
|
||||
_eos = true;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto res = _data[_offset] + (_data[_offset + 1] << 8) + (_data[_offset + 2] << 16) + (
|
||||
_data[_offset + 3] << 24);
|
||||
|
||||
_offset += 4;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
std::optional<float> msg::read_float() {
|
||||
if (_eos || _offset + 4 > _data.size()) {
|
||||
_eos = true;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto res = std::bit_cast<float>(read_long().value());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::optional<std::string> msg::read_string() {
|
||||
std::string res{};
|
||||
|
||||
if (_eos) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
do {
|
||||
auto c = read_char();
|
||||
if (!c.has_value() || c.value() == 0) {
|
||||
break;
|
||||
}
|
||||
res += c.value();
|
||||
} while (!_eos);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::optional<float> msg::read_coord(const rmq_flags flags) {
|
||||
if ((flags & rmq_flags::float_coord) != rmq_flags::none) {
|
||||
return read_float();
|
||||
}
|
||||
if ((flags & rmq_flags::int_coord) != rmq_flags::none) {
|
||||
const auto i = read_long();
|
||||
if (!i.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return i.value() * (1.0 / 16.0);
|
||||
}
|
||||
if ((flags & rmq_flags::hires_coord) != rmq_flags::none) {
|
||||
return read_hires_coord();
|
||||
}
|
||||
return read_lores_coord();
|
||||
}
|
||||
|
||||
std::optional<float> msg::read_angle(const rmq_flags flags) {
|
||||
if ((flags & rmq_flags::float_angle) != rmq_flags::none) {
|
||||
return read_float();
|
||||
}
|
||||
if ((flags & rmq_flags::short_angle) != rmq_flags::none) {
|
||||
auto a = read_short();
|
||||
if (!a.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return a.value() * (360.0 / 65536);
|
||||
}
|
||||
const auto c = read_char();
|
||||
if (!c.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return c.value() * (360.0 / 256);
|
||||
}
|
||||
|
||||
std::optional<float> msg::read_angle_16(rmq_flags flags) {
|
||||
if ((flags & rmq_flags::float_angle) != rmq_flags::none) {
|
||||
return read_float();
|
||||
}
|
||||
const auto s = read_short();
|
||||
if (!s.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return s.value() * (360.0 / 65536);
|
||||
}
|
||||
|
||||
void msg::write(const std::uint8_t *data, std::size_t size) {
|
||||
for (auto i = 0; i < size; i++) {
|
||||
_data.push_back(data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user