From df9b2cd9bf080432723767ddfb2ab6b20bc80f38 Mon Sep 17 00:00:00 2001 From: Boondorl Date: Fri, 5 Jan 2024 15:08:49 -0500 Subject: [PATCH] Added 64-bit networking support Mainly for use with doubles as ZScript can now take advantage of it. Enforced sizing on ints passed to and read from net functions. --- src/d_net.cpp | 42 ++++++++++-- src/d_net.h | 8 ++- src/d_protocol.cpp | 65 +++++++++++++++--- src/d_protocol.h | 16 +++-- src/events.cpp | 118 +++++++++++++++++++++++--------- src/events.h | 50 +++++++++++++- wadsrc/static/zscript/events.zs | 7 +- 7 files changed, 243 insertions(+), 63 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 83204dbc2c..6253d98e91 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -259,7 +259,7 @@ static struct TicSpecial streamoffs = 0; } - TicSpecial &operator << (uint8_t it) + TicSpecial &operator << (int8_t it) { if (streamptr) { @@ -269,7 +269,7 @@ static struct TicSpecial return *this; } - TicSpecial &operator << (short it) + TicSpecial &operator << (int16_t it) { if (streamptr) { @@ -279,7 +279,7 @@ static struct TicSpecial return *this; } - TicSpecial &operator << (int it) + TicSpecial &operator << (int32_t it) { if (streamptr) { @@ -289,6 +289,16 @@ static struct TicSpecial return *this; } + TicSpecial& operator << (int64_t it) + { + if (streamptr) + { + CheckSpace(8); + WriteInt64(it, &streamptr); + } + return *this; + } + TicSpecial &operator << (float it) { if (streamptr) @@ -299,6 +309,16 @@ static struct TicSpecial return *this; } + TicSpecial& operator << (double it) + { + if (streamptr) + { + CheckSpace(8); + WriteDouble(it, &streamptr); + } + return *this; + } + TicSpecial &operator << (const char *it) { if (streamptr) @@ -2047,17 +2067,22 @@ void Net_NewMakeTic (void) specials.NewMakeTic (); } -void Net_WriteInt8 (uint8_t it) +void Net_WriteInt8 (int8_t it) { specials << it; } -void Net_WriteInt16 (short it) +void Net_WriteInt16 (int16_t it) { specials << it; } -void Net_WriteInt32 (int it) +void Net_WriteInt32 (int32_t it) +{ + specials << it; +} + +void Net_WriteInt64(int64_t it) { specials << it; } @@ -2067,6 +2092,11 @@ void Net_WriteFloat (float it) specials << it; } +void Net_WriteDouble(double it) +{ + specials << it; +} + void Net_WriteString (const char *it) { specials << it; diff --git a/src/d_net.h b/src/d_net.h index 99020f0915..54b6c74417 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -64,10 +64,12 @@ void Net_CheckLastReceived(int); // [RH] Functions for making and using special "ticcmds" void Net_NewMakeTic (); -void Net_WriteInt8 (uint8_t); -void Net_WriteInt16 (short); -void Net_WriteInt32 (int); +void Net_WriteInt8 (int8_t); +void Net_WriteInt16 (int16_t); +void Net_WriteInt32 (int32_t); +void Net_WriteInt64(int64_t); void Net_WriteFloat (float); +void Net_WriteDouble(double); void Net_WriteString (const char *); void Net_WriteBytes (const uint8_t *, int len); diff --git a/src/d_protocol.cpp b/src/d_protocol.cpp index 367de19b77..7efdd25732 100644 --- a/src/d_protocol.cpp +++ b/src/d_protocol.cpp @@ -55,38 +55,57 @@ const char *ReadStringConst(uint8_t **stream) return string; } -int ReadInt8 (uint8_t **stream) +int8_t ReadInt8 (uint8_t **stream) { - uint8_t v = **stream; + int8_t v = **stream; *stream += 1; return v; } -int ReadInt16 (uint8_t **stream) +int16_t ReadInt16 (uint8_t **stream) { - short v = (((*stream)[0]) << 8) | (((*stream)[1])); + int16_t v = (((*stream)[0]) << 8) | (((*stream)[1])); *stream += 2; return v; } -int ReadInt32 (uint8_t **stream) +int32_t ReadInt32 (uint8_t **stream) { - int v = (((*stream)[0]) << 24) | (((*stream)[1]) << 16) | (((*stream)[2]) << 8) | (((*stream)[3])); + int32_t v = (((*stream)[0]) << 24) | (((*stream)[1]) << 16) | (((*stream)[2]) << 8) | (((*stream)[3])); *stream += 4; return v; } +int64_t ReadInt64(uint8_t** stream) +{ + int64_t v = (int64_t((*stream)[0]) << 56) | (int64_t((*stream)[1]) << 48) | (int64_t((*stream)[2]) << 40) | (int64_t((*stream)[3]) << 32) + | (int64_t((*stream)[4]) << 24) | (int64_t((*stream)[5]) << 16) | (int64_t((*stream)[6]) << 8) | (int64_t((*stream)[7])); + *stream += 8; + return v; +} + float ReadFloat (uint8_t **stream) { union { - int i; + int32_t i; float f; } fakeint; fakeint.i = ReadInt32 (stream); return fakeint.f; } +double ReadDouble(uint8_t** stream) +{ + union + { + int64_t i; + double f; + } fakeint; + fakeint.i = ReadInt64(stream); + return fakeint.f; +} + void WriteString (const char *string, uint8_t **stream) { char *p = *((char **)stream); @@ -100,20 +119,20 @@ void WriteString (const char *string, uint8_t **stream) } -void WriteInt8 (uint8_t v, uint8_t **stream) +void WriteInt8 (int8_t v, uint8_t **stream) { **stream = v; *stream += 1; } -void WriteInt16 (short v, uint8_t **stream) +void WriteInt16 (int16_t v, uint8_t **stream) { (*stream)[0] = v >> 8; (*stream)[1] = v & 255; *stream += 2; } -void WriteInt32 (int v, uint8_t **stream) +void WriteInt32 (int32_t v, uint8_t **stream) { (*stream)[0] = v >> 24; (*stream)[1] = (v >> 16) & 255; @@ -122,17 +141,41 @@ void WriteInt32 (int v, uint8_t **stream) *stream += 4; } +void WriteInt64(int64_t v, uint8_t** stream) +{ + (*stream)[0] = v >> 56; + (*stream)[1] = (v >> 48) & 255; + (*stream)[2] = (v >> 40) & 255; + (*stream)[3] = (v >> 32) & 255; + (*stream)[4] = (v >> 24) & 255; + (*stream)[5] = (v >> 16) & 255; + (*stream)[6] = (v >> 8) & 255; + (*stream)[7] = v & 255; + *stream += 8; +} + void WriteFloat (float v, uint8_t **stream) { union { - int i; + int32_t i; float f; } fakeint; fakeint.f = v; WriteInt32 (fakeint.i, stream); } +void WriteDouble(double v, uint8_t** stream) +{ + union + { + int64_t i; + double f; + } fakeint; + fakeint.f = v; + WriteInt64(fakeint.i, stream); +} + // Returns the number of bytes read int UnpackUserCmd (usercmd_t *ucmd, const usercmd_t *basis, uint8_t **stream) { diff --git a/src/d_protocol.h b/src/d_protocol.h index d00f3f9089..c619e6da5a 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -247,16 +247,20 @@ int SkipTicCmd (uint8_t **stream, int count); void ReadTicCmd (uint8_t **stream, int player, int tic); void RunNetSpecs (int player, int buf); -int ReadInt8 (uint8_t **stream); -int ReadInt16 (uint8_t **stream); -int ReadInt32 (uint8_t **stream); +int8_t ReadInt8 (uint8_t **stream); +int16_t ReadInt16 (uint8_t **stream); +int32_t ReadInt32 (uint8_t **stream); +int64_t ReadInt64(uint8_t** stream); float ReadFloat (uint8_t **stream); +double ReadDouble(uint8_t** stream); char *ReadString (uint8_t **stream); const char *ReadStringConst(uint8_t **stream); -void WriteInt8 (uint8_t val, uint8_t **stream); -void WriteInt16 (short val, uint8_t **stream); -void WriteInt32 (int val, uint8_t **stream); +void WriteInt8 (int8_t val, uint8_t **stream); +void WriteInt16 (int16_t val, uint8_t **stream); +void WriteInt32 (int32_t val, uint8_t **stream); +void WriteInt64(int64_t val, uint8_t** stream); void WriteFloat (float val, uint8_t **stream); +void WriteDouble(double val, uint8_t** stream); void WriteString (const char *string, uint8_t **stream); #endif //__D_PROTOCOL_H__ diff --git a/src/events.cpp b/src/events.cpp index e68eaf0b0d..1f212076c5 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -115,6 +115,12 @@ void DNetworkBuffer::AddFloat(double msg) _buffer.Push({ NET_FLOAT, msg }); } +void DNetworkBuffer::AddDouble(double msg) +{ + _size += 8u; + _buffer.Push({ NET_DOUBLE, msg }); +} + void DNetworkBuffer::AddString(const FString& msg) { _size += msg.Len() + 1u; @@ -154,9 +160,10 @@ void DNetworkBuffer::Serialize(FSerializer& arc) { switch (value.GetType()) { + case NET_DOUBLE: case NET_FLOAT: { - double f = value.GetFloat(); + double f = value.GetDouble(); arc(nullptr, f); break; } @@ -233,6 +240,14 @@ void DNetworkBuffer::Serialize(FSerializer& arc) break; } + case NET_DOUBLE: + { + double f = 0.0; + arc(nullptr, f); + AddDouble(f); + break; + } + case NET_STRING: { FString s = {}; @@ -404,6 +419,10 @@ bool EventManager::SendNetworkCommand(const FName& cmd, VMVa_List& args) bytes += 4u; break; + case NET_DOUBLE: + bytes += 8u; + break; + case NET_STRING: { ++bytes; // Strings will always consume at least one byte. @@ -452,6 +471,10 @@ bool EventManager::SendNetworkCommand(const FName& cmd, VMVa_List& args) Net_WriteFloat(ListGetDouble(args)); break; + case NET_DOUBLE: + Net_WriteDouble(ListGetDouble(args)); + break; + case NET_STRING: { const FString* str = ListGetString(args); @@ -498,7 +521,11 @@ bool EventManager::SendNetworkBuffer(const FName& cmd, const DNetworkBuffer* buf break; case NET_FLOAT: - Net_WriteFloat(value.GetFloat()); + Net_WriteFloat(value.GetDouble()); + break; + + case NET_DOUBLE: + Net_WriteDouble(value.GetDouble()); break; case NET_STRING: @@ -1047,6 +1074,13 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadFloat) ACTION_RETURN_FLOAT(self->ReadFloat()); } +DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadDouble) +{ + PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); + + ACTION_RETURN_FLOAT(self->ReadDouble()); +} + DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadString) { PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); @@ -1092,8 +1126,8 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector2) PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); DVector2 vec = {}; - vec.X = self->ReadFloat(); - vec.Y = self->ReadFloat(); + vec.X = self->ReadDouble(); + vec.Y = self->ReadDouble(); ACTION_RETURN_VEC2(vec); } @@ -1102,9 +1136,9 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector3) PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); DVector3 vec = {}; - vec.X = self->ReadFloat(); - vec.Y = self->ReadFloat(); - vec.Z = self->ReadFloat(); + vec.X = self->ReadDouble(); + vec.Y = self->ReadDouble(); + vec.Z = self->ReadDouble(); ACTION_RETURN_VEC3(vec); } @@ -1113,10 +1147,10 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector4) PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); DVector4 vec = {}; - vec.X = self->ReadFloat(); - vec.Y = self->ReadFloat(); - vec.Z = self->ReadFloat(); - vec.W = self->ReadFloat(); + vec.X = self->ReadDouble(); + vec.Y = self->ReadDouble(); + vec.Z = self->ReadDouble(); + vec.W = self->ReadDouble(); ACTION_RETURN_VEC4(vec); } @@ -1125,10 +1159,10 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadQuat) PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); DQuaternion quat = {}; - quat.X = self->ReadFloat(); - quat.Y = self->ReadFloat(); - quat.Z = self->ReadFloat(); - quat.W = self->ReadFloat(); + quat.X = self->ReadDouble(); + quat.Y = self->ReadDouble(); + quat.Z = self->ReadDouble(); + quat.W = self->ReadDouble(); ACTION_RETURN_QUAT(quat); } @@ -1160,14 +1194,20 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadIntArray) return 0; } -DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadFloatArray) +DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadDoubleArray) { PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_OUTPOINTER(values, TArray); + PARAM_BOOL(doublePrecision); unsigned int size = self->ReadInt(); for (unsigned int i = 0u; i < size; ++i) - values->Push(self->ReadFloat()); + { + if (doublePrecision) + values->Push(self->ReadDouble()); + else + values->Push(self->ReadFloat()); + } return 0; } @@ -1225,6 +1265,14 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddFloat) return 0; } +DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddDouble) +{ + PARAM_SELF_PROLOGUE(DNetworkBuffer); + PARAM_FLOAT(value); + self->AddDouble(value); + return 0; +} + DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddString) { PARAM_SELF_PROLOGUE(DNetworkBuffer); @@ -1264,8 +1312,8 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector2) PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_FLOAT(x); PARAM_FLOAT(y); - self->AddFloat(x); - self->AddFloat(y); + self->AddDouble(x); + self->AddDouble(y); return 0; } @@ -1275,9 +1323,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector3) PARAM_FLOAT(x); PARAM_FLOAT(y); PARAM_FLOAT(z); - self->AddFloat(x); - self->AddFloat(y); - self->AddFloat(z); + self->AddDouble(x); + self->AddDouble(y); + self->AddDouble(z); return 0; } @@ -1288,10 +1336,10 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector4) PARAM_FLOAT(y); PARAM_FLOAT(z); PARAM_FLOAT(w); - self->AddFloat(x); - self->AddFloat(y); - self->AddFloat(z); - self->AddFloat(w); + self->AddDouble(x); + self->AddDouble(y); + self->AddDouble(z); + self->AddDouble(w); return 0; } @@ -1302,10 +1350,10 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddQuat) PARAM_FLOAT(y); PARAM_FLOAT(z); PARAM_FLOAT(w); - self->AddFloat(x); - self->AddFloat(y); - self->AddFloat(z); - self->AddFloat(w); + self->AddDouble(x); + self->AddDouble(y); + self->AddDouble(z); + self->AddDouble(w); return 0; } @@ -1338,15 +1386,21 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddIntArray) return 0; } -DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddFloatArray) +DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddDoubleArray) { PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_POINTER(values, TArray); + PARAM_BOOL(doublePrecision); unsigned int size = values->Size(); self->AddInt(size); for (unsigned int i = 0u; i < size; ++i) - self->AddFloat((*values)[i]); + { + if (doublePrecision) + self->AddDouble((*values)[i]); + else + self->AddFloat((*values)[i]); + } return 0; } diff --git a/src/events.h b/src/events.h index dc27eed1b9..facad2b059 100755 --- a/src/events.h +++ b/src/events.h @@ -26,6 +26,7 @@ enum ENetCmd NET_INT16, NET_INT, NET_FLOAT, + NET_DOUBLE, NET_STRING, }; @@ -95,7 +96,7 @@ public: return value; } - // Floats without their first 9 bits are pretty meaningless so those are done first. + // Floats without their first bits are pretty meaningless so those are done first. double ReadFloat() { if (!IsValid()) @@ -115,13 +116,55 @@ public: union { - int i; + int32_t i; float f; } floatCaster; floatCaster.i = value; return floatCaster.f; } + double ReadDouble() + { + if (!IsValid()) + return 0.0; + + int64_t value = int64_t(_stream[_index++]) << 56; + if (IsValid()) + { + value |= int64_t(_stream[_index++]) << 48; + if (IsValid()) + { + value |= int64_t(_stream[_index++]) << 40; + if (IsValid()) + { + value |= int64_t(_stream[_index++]) << 32; + if (IsValid()) + { + value |= int64_t(_stream[_index++]) << 24; + if (IsValid()) + { + value |= int64_t(_stream[_index++]) << 16; + if (IsValid()) + { + value |= int64_t(_stream[_index++]) << 8; + if (IsValid()) + value |= int64_t(_stream[_index++]); + } + } + } + } + } + } + + union + { + int64_t i; + double f; + } floatCaster; + floatCaster.i = value; + return floatCaster.f; + } + const char* ReadString() { if (!IsValid()) @@ -159,7 +202,7 @@ public: return std::get(_message); } - inline double GetFloat() const + inline double GetDouble() const { return std::get(_message); } @@ -194,6 +237,7 @@ public: void AddInt16(int word); void AddInt(int msg); void AddFloat(double msg); + void AddDouble(double msg); void AddString(const FString& msg); void OnDestroy() override; void Serialize(FSerializer& arc) override; diff --git a/wadsrc/static/zscript/events.zs b/wadsrc/static/zscript/events.zs index 438b249dce..738af124e8 100644 --- a/wadsrc/static/zscript/events.zs +++ b/wadsrc/static/zscript/events.zs @@ -4,6 +4,7 @@ enum ENetCmd NET_INT16, NET_INT, NET_FLOAT, + NET_DOUBLE, NET_STRING, } @@ -16,6 +17,7 @@ struct NetworkCommand native play version("4.12") native int ReadInt16(); native int ReadInt(); native double ReadFloat(); + native double ReadDouble(); native string ReadString(); // Wrappers @@ -27,7 +29,7 @@ struct NetworkCommand native play version("4.12") native Vector4 ReadVector4(); native Quat ReadQuat(); native void ReadIntArray(out Array values, ENetCmd intSize = NET_INT); - native void ReadFloatArray(out Array values); + native void ReadDoubleArray(out Array values, bool doublePrecision = true); native void ReadStringArray(out Array values, bool skipEmpty = false); } @@ -37,6 +39,7 @@ class NetworkBuffer native version("4.12") native void AddInt16(int value); native void AddInt(int value); native void AddFloat(double value); + native void AddDouble(double value); native void AddString(string value); // Wrappers @@ -48,7 +51,7 @@ class NetworkBuffer native version("4.12") native void AddVector4(Vector4 value); native void AddQuat(Quat value); native void AddIntArray(Array values, ENetCmd intSize = NET_INT); - native void AddFloatArray(Array values); + native void AddDoubleArray(Array values, bool doublePrecision = true); native void AddStringArray(Array values); }