From 1957e40bc0bceb4fa9923121368bdaa4344696ed Mon Sep 17 00:00:00 2001 From: Scott Barrett Date: Fri, 25 Feb 2022 00:38:14 -0500 Subject: [PATCH 01/29] add new code for assignment --- RoboCat/Chapter3.vcxproj | 7 +- RoboCat/Inc/ByteSwap.h | 117 +++++++++++++++++++ RoboCat/Inc/LinkingContext.h | 67 +++++++++++ RoboCat/Inc/MemoryBitStream.h | 161 ++++++++++++++++++++++++++ RoboCat/Inc/RoboCatShared.h | 6 + RoboCat/Inc/RoboMath.h | 199 ++++++++++++++++++++++++++++++++ RoboCat/Src/Main.cpp | 23 ---- RoboCat/Src/MemoryBitStream.cpp | 171 +++++++++++++++++++++++++++ 8 files changed, 727 insertions(+), 24 deletions(-) create mode 100644 RoboCat/Inc/ByteSwap.h create mode 100644 RoboCat/Inc/LinkingContext.h create mode 100644 RoboCat/Inc/MemoryBitStream.h create mode 100644 RoboCat/Inc/RoboMath.h create mode 100644 RoboCat/Src/MemoryBitStream.cpp diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index 10d69fef..07598b73 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -128,7 +128,7 @@ ProgramDatabase EnableFastChecks ..\SDL\include;Inc;..\ - Create + Use RoboCatPCH.h @@ -370,7 +370,11 @@ + + + + @@ -380,6 +384,7 @@ + diff --git a/RoboCat/Inc/ByteSwap.h b/RoboCat/Inc/ByteSwap.h new file mode 100644 index 00000000..5407540c --- /dev/null +++ b/RoboCat/Inc/ByteSwap.h @@ -0,0 +1,117 @@ + +#ifndef RoboCat_ByteSwap_h +#define RoboCat_ByteSwap_h + +inline uint16_t ByteSwap2( uint16_t inData ) +{ + return ( inData >> 8 ) | ( inData << 8 ); +} + +inline uint32_t ByteSwap4( uint32_t inData ) +{ + return ( ( inData >> 24 ) & 0x000000ff ) | + ( ( inData >> 8 ) & 0x0000ff00 ) | + ( ( inData << 8 ) & 0x00ff0000 ) | + ( ( inData << 24 ) & 0xff000000 ); +} + +inline uint64_t ByteSwap8( uint64_t inData ) +{ + return ( ( inData >> 56 ) & 0x00000000000000ff ) | + ( ( inData >> 40 ) & 0x000000000000ff00 ) | + ( ( inData >> 24 ) & 0x0000000000ff0000 ) | + ( ( inData >> 8 ) & 0x00000000ff000000 ) | + ( ( inData << 8 ) & 0x000000ff00000000 ) | + ( ( inData << 24 ) & 0x0000ff0000000000 ) | + ( ( inData << 40 ) & 0x00ff000000000000 ) | + ( ( inData << 56 ) & 0xff00000000000000 ); +} + + +template < typename tFrom, typename tTo > +class TypeAliaser +{ +public: + TypeAliaser( tFrom inFromValue ) : + mAsFromType( inFromValue ) {} + tTo& Get() { return mAsToType; } + + union + { + tFrom mAsFromType; + tTo mAsToType; + }; +}; + + +template class ByteSwapper; + +//specialize for 1... +template +class ByteSwapper< T, 1 > +{ +public: + T Swap( T inData ) const + { + return inData; + } +}; + + +//specialize for 2... +template +class ByteSwapper< T, 2 > +{ +public: + T Swap( T inData ) const + { + uint16_t result = + ByteSwap2( TypeAliaser< T, uint16_t >( inData ).Get() ); + return TypeAliaser< uint16_t, T >( result ).Get(); + } +}; + +//specialize for 4... +template +class ByteSwapper< T, 4 > +{ +public: + T Swap( T inData ) const + { + uint32_t result = + ByteSwap4( TypeAliaser< T, uint32_t >( inData ).Get() ); + return TypeAliaser< uint32_t, T >( result ).Get(); + } +}; + + +//specialize for 8... +template +class ByteSwapper< T, 8 > +{ +public: + T Swap( T inData ) const + { + uint64_t result = + ByteSwap8( TypeAliaser< T, uint64_t >( inData ).Get() ); + return TypeAliaser< uint64_t, T >( result ).Get(); + } +}; + +template < typename T > +T ByteSwap( T inData ) +{ + return ByteSwapper< T, sizeof( T ) >().Swap( inData ); +} + +inline void TestByteSwap() +{ + int32_t test = 0x12345678; + float floatTest = 1.f; + + printf( "swapped 0x%x is 0x%x\n", test, ByteSwap( test ) ); + printf( "swapped %f is %f\n", floatTest, ByteSwap( floatTest ) ); + printf( "swapped 0x%x is 0x%x\n", TypeAliaser< float, uint32_t >( floatTest ).Get(), TypeAliaser< float, uint32_t >( ByteSwap( floatTest ) ).Get() ); +} + +#endif diff --git a/RoboCat/Inc/LinkingContext.h b/RoboCat/Inc/LinkingContext.h new file mode 100644 index 00000000..893e73aa --- /dev/null +++ b/RoboCat/Inc/LinkingContext.h @@ -0,0 +1,67 @@ + +#ifndef RoboCat_LinkingContext_h +#define RoboCat_LinkingContext_h + +class GameObject; + +class LinkingContext +{ +public: + + LinkingContext() : + mNextNetworkId( 1 ) + {} + + uint32_t GetNetworkId( GameObject* inGameObject, bool inShouldCreateIfNotFound ) + { + auto it = mGameObjectToNetworkIdMap.find( inGameObject ); + if( it != mGameObjectToNetworkIdMap.end() ) + { + return it->second; + } + else if( inShouldCreateIfNotFound ) + { + uint32_t newNetworkId = mNextNetworkId++; + AddGameObject( inGameObject, newNetworkId ); + return newNetworkId; + } + else + { + return 0; + } + } + + GameObject* GetGameObject( uint32_t inNetworkId ) const + { + auto it = mNetworkIdToGameObjectMap.find( inNetworkId ); + if( it != mNetworkIdToGameObjectMap.end() ) + { + return it->second; + } + else + { + return nullptr; + } + } + + void AddGameObject( GameObject* inGameObject, uint32_t inNetworkId ) + { + mNetworkIdToGameObjectMap[ inNetworkId ] = inGameObject; + mGameObjectToNetworkIdMap[ inGameObject ] = inNetworkId; + } + + void RemoveGameObject( GameObject *inGameObject ) + { + uint32_t networkId = mGameObjectToNetworkIdMap[ inGameObject ]; + mGameObjectToNetworkIdMap.erase( inGameObject ); + mNetworkIdToGameObjectMap.erase( networkId ); + } + +private: + std::unordered_map< uint32_t, GameObject* > mNetworkIdToGameObjectMap; + std::unordered_map< const GameObject*, uint32_t > mGameObjectToNetworkIdMap; + + uint32_t mNextNetworkId; +}; + +#endif diff --git a/RoboCat/Inc/MemoryBitStream.h b/RoboCat/Inc/MemoryBitStream.h new file mode 100644 index 00000000..c2138925 --- /dev/null +++ b/RoboCat/Inc/MemoryBitStream.h @@ -0,0 +1,161 @@ + +#include +#include +#include +#include + +class GameObject; + +inline uint32_t ConvertToFixed( float inNumber, float inMin, float inPrecision ) +{ + return static_cast< int > ( ( inNumber - inMin ) / inPrecision ); +} + +inline float ConvertFromFixed( uint32_t inNumber, float inMin, float inPrecision ) +{ + return static_cast< float >( inNumber ) * inPrecision + inMin; +} + + +class OutputMemoryBitStream +{ +public: + + OutputMemoryBitStream() : + mBitHead(0), + mBuffer(nullptr) + { + ReallocBuffer( 1500 * 8 ); + } + + ~OutputMemoryBitStream() { std::free(mBuffer); } + + void WriteBits( uint8_t inData, uint32_t inBitCount ); + void WriteBits( const void* inData, uint32_t inBitCount ); + + const char* GetBufferPtr() const { return mBuffer; } + uint32_t GetBitLength() const { return mBitHead; } + uint32_t GetByteLength() const { return ( mBitHead + 7 ) >> 3; } + + void WriteBytes( const void* inData, uint32_t inByteCount ) { WriteBits( inData, inByteCount << 3 ); } + + /* + void Write( uint32_t inData, uint32_t inBitCount = 32 ) { WriteBits( &inData, inBitCount ); } + void Write( int inData, uint32_t inBitCount = 32 ) { WriteBits( &inData, inBitCount ); } + void Write( float inData ) { WriteBits( &inData, 32 ); } + + void Write( uint16_t inData, uint32_t inBitCount = 16 ) { WriteBits( &inData, inBitCount ); } + void Write( int16_t inData, uint32_t inBitCount = 16 ) { WriteBits( &inData, inBitCount ); } + + void Write( uint8_t inData, uint32_t inBitCount = 8 ) { WriteBits( &inData, inBitCount ); } + */ + + template< typename T > + void Write( T inData, uint32_t inBitCount = sizeof( T ) * 8 ) + { + static_assert( std::is_arithmetic< T >::value || + std::is_enum< T >::value, + "Generic Write only supports primitive data types" ); + WriteBits( &inData, inBitCount ); + } + + void Write( bool inData ) { WriteBits( &inData, 1 ); } + + void Write( const Vector3& inVector ); + void Write( const Quaternion& inQuat ); + + void Write( const std::string& inString ) + { + uint32_t elementCount = static_cast< uint32_t >( inString.size() ); + Write( elementCount ); + for( const auto& element : inString ) + { + Write( element ); + } + } + +private: + void ReallocBuffer( uint32_t inNewBitCapacity ); + + char* mBuffer; + uint32_t mBitHead; + uint32_t mBitCapacity; +}; + +class InputMemoryBitStream +{ +public: + + InputMemoryBitStream( char* inBuffer, uint32_t inBitCount ) : + mBuffer( inBuffer ), + mBitCapacity( inBitCount ), + mBitHead( 0 ), + mIsBufferOwner( false ) {} + + InputMemoryBitStream( const InputMemoryBitStream& inOther ) : + mBitCapacity( inOther.mBitCapacity ), + mBitHead( inOther.mBitHead ), + mIsBufferOwner( true ) + { + //allocate buffer of right size + int byteCount = ( mBitCapacity + 7 ) / 8; + mBuffer = static_cast< char* >( malloc( byteCount ) ); + //copy + memcpy( mBuffer, inOther.mBuffer, byteCount ); + } + + ~InputMemoryBitStream() { if (mIsBufferOwner) { std::cout << "Freeing " << mBuffer << std::endl; free(mBuffer); }; } + + const char* GetBufferPtr() const { return mBuffer; } + uint32_t GetRemainingBitCount() const { return mBitCapacity - mBitHead; } + + void ReadBits( uint8_t& outData, uint32_t inBitCount ); + void ReadBits( void* outData, uint32_t inBitCount ); + + void ReadBytes( void* outData, uint32_t inByteCount ) { ReadBits( outData, inByteCount << 3 ); } + + template< typename T > + void Read( T& inData, uint32_t inBitCount = sizeof( T ) * 8 ) + { + static_assert( std::is_arithmetic< T >::value || + std::is_enum< T >::value, + "Generic Read only supports primitive data types" ); + ReadBits( &inData, inBitCount ); + } + + void Read( uint32_t& outData, uint32_t inBitCount = 32 ) { ReadBits( &outData, inBitCount ); } + void Read( int& outData, uint32_t inBitCount = 32 ) { ReadBits( &outData, inBitCount ); } + void Read( float& outData ) { ReadBits( &outData, 32 ); } + + void Read( uint16_t& outData, uint32_t inBitCount = 16 ) { ReadBits( &outData, inBitCount ); } + void Read( int16_t& outData, uint32_t inBitCount = 16 ) { ReadBits( &outData, inBitCount ); } + + void Read( uint8_t& outData, uint32_t inBitCount = 8 ) { ReadBits( &outData, inBitCount ); } + void Read( bool& outData ) { ReadBits( &outData, 1 ); } + + void Read( Quaternion& outQuat ); + + void ResetToCapacity( uint32_t inByteCapacity ) { mBitCapacity = inByteCapacity << 3; mBitHead = 0; } + + + void Read( std::string& inString ) + { + uint32_t elementCount; + Read( elementCount ); + inString.resize( elementCount ); + for( auto& element : inString ) + { + Read( element ); + } + } + + void Read( Vector3& inVector ); + +private: + char* mBuffer; + uint32_t mBitHead; + uint32_t mBitCapacity; + bool mIsBufferOwner; + +}; + diff --git a/RoboCat/Inc/RoboCatShared.h b/RoboCat/Inc/RoboCatShared.h index 83a3871a..bc232e1f 100644 --- a/RoboCat/Inc/RoboCatShared.h +++ b/RoboCat/Inc/RoboCatShared.h @@ -49,6 +49,12 @@ using std::unordered_set; class RoboCat; class GameObject; +#include "RoboMath.h" + +#include "LinkingContext.h" +#include "ByteSwap.h" +#include "MemoryBitStream.h" + #include "StringUtils.h" #include "SocketAddress.h" #include "SocketAddressFactory.h" diff --git a/RoboCat/Inc/RoboMath.h b/RoboCat/Inc/RoboMath.h new file mode 100644 index 00000000..718080a9 --- /dev/null +++ b/RoboCat/Inc/RoboMath.h @@ -0,0 +1,199 @@ +class Vector3 +{ +public: + + float mX, mY, mZ; + + Vector3( float x, float y, float z ) : + mX( x ), + mY( y ), + mZ( z ) + {} + + Vector3() : + mX( 0.0f ), + mY( 0.0f ), + mZ( 0.0f ) + {} + + void Set( float x, float y, float z ) + { + mX = x; + mY = y; + mZ = z; + } + + friend Vector3 operator+( const Vector3& inLeft, const Vector3& inRight ) + { + return Vector3( inLeft.mX + inRight.mX, inLeft.mY + inRight.mY, inLeft.mZ + inRight.mZ ); + } + + friend Vector3 operator-( const Vector3& inLeft, const Vector3& inRight ) + { + return Vector3( inLeft.mX - inRight.mX, inLeft.mY - inRight.mY, inLeft.mZ - inRight.mZ ); + } + + // Component-wise multiplication + friend Vector3 operator*( const Vector3& inLeft, const Vector3& inRight ) + { + return Vector3( inLeft.mX * inRight.mX, inLeft.mY * inRight.mY, inLeft.mZ * inRight.mZ ); + } + + // Scalar multiply + friend Vector3 operator*( float inScalar, const Vector3& inVec ) + { + return Vector3( inVec.mX * inScalar, inVec.mY * inScalar, inVec.mZ * inScalar ); + } + + friend Vector3 operator*( const Vector3& inVec, float inScalar ) + { + return Vector3( inVec.mX * inScalar, inVec.mY * inScalar, inVec.mZ * inScalar ); + } + + Vector3& operator*=( float inScalar ) + { + mX *= inScalar; + mY *= inScalar; + mZ *= inScalar; + return *this; + } + + Vector3& operator+=( const Vector3& inRight ) + { + mX += inRight.mX; + mY += inRight.mY; + mZ += inRight.mZ; + return *this; + } + + Vector3& operator-=( const Vector3& inRight ) + { + mX -= inRight.mX; + mY -= inRight.mY; + mZ -= inRight.mZ; + return *this; + } + + float Length() + { + return sqrtf( mX * mX + mY * mY + mZ * mZ ); + } + + float LengthSq() + { + return mX * mX + mY * mY + mZ * mZ; + } + + float Length2D() + { + return sqrtf( mX * mX + mY * mY ); + } + + float LengthSq2D() + { + return mX * mX + mY * mY; + } + + void Normalize() + { + float length = Length(); + mX /= length; + mY /= length; + mZ /= length; + } + + void Normalize2D() + { + float length = Length2D(); + mX /= length; + mY /= length; + } + + friend float Dot( const Vector3& inLeft, const Vector3& inRight ) + { + return ( inLeft.mX * inRight.mX + inLeft.mY * inRight.mY + inLeft.mZ * inRight.mZ ); + } + + friend float Dot2D( const Vector3& inLeft, const Vector3& inRight ) + { + return ( inLeft.mX * inRight.mX + inLeft.mY * inRight.mY ); + } + + friend Vector3 Cross( const Vector3& inLeft, const Vector3& inRight ) + { + Vector3 temp; + temp.mX = inLeft.mY * inRight.mZ - inLeft.mZ * inRight.mY; + temp.mY = inLeft.mZ * inRight.mX - inLeft.mX * inRight.mZ; + temp.mZ = inLeft.mX * inRight.mY - inLeft.mY * inRight.mX; + return temp; + } + + friend Vector3 Lerp( const Vector3& inA, const Vector3& inB, float t ) + { + return Vector3( inA + t * ( inB - inA ) ); + } + + static const Vector3 Zero; + static const Vector3 UnitX; + static const Vector3 UnitY; + static const Vector3 UnitZ; +}; + + +class Quaternion +{ +public: + + float mX, mY, mZ, mW; + +}; + + +template< int tValue, int tBits > +struct GetRequiredBitsHelper +{ + enum { Value = GetRequiredBitsHelper< ( tValue >> 1 ), tBits + 1 >::Value }; +}; + +template< int tBits > +struct GetRequiredBitsHelper< 0, tBits > +{ + enum { Value = tBits }; +}; + +template< int tValue > +struct GetRequiredBits +{ + enum { Value = GetRequiredBitsHelper< tValue, 0 >::Value }; +}; + +namespace RoboMath +{ + const float PI = 3.1415926535f; + float GetRandomFloat(); + + Vector3 GetRandomVector( const Vector3& inMin, const Vector3& inMax ); + + inline bool Is2DVectorEqual( const Vector3& inA, const Vector3& inB ) + { + return ( inA.mX == inB.mX && inA.mY == inB.mY ); + } + + inline float ToDegrees( float inRadians ) + { + return inRadians * 180.0f / PI; + } +} + +namespace Colors +{ + static const Vector3 Black( 0.0f, 0.0f, 0.0f ); + static const Vector3 White( 1.0f, 1.0f, 1.0f ); + static const Vector3 Red( 1.0f, 0.0f, 0.0f ); + static const Vector3 Green( 0.0f, 1.0f, 0.0f ); + static const Vector3 Blue( 0.0f, 0.0f, 1.0f ); + static const Vector3 LightYellow( 1.0f, 1.0f, 0.88f ); + static const Vector3 LightBlue( 0.68f, 0.85f, 0.9f ); + static const Vector3 LightPink( 1.0f, 0.71f, 0.76f ); + static const Vector3 LightGreen( 0.56f, 0.93f, 0.56f ); +} diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index f8c6c7d0..a5c1f9df 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -24,29 +24,6 @@ int main(int argc, const char** argv) SocketUtil::StaticInit(); - OutputWindow win; - - std::thread t([&win]() - { - int msgNo = 1; - while (true) - { - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - std::string msgIn("~~~auto message~~~"); - std::stringstream ss(msgIn); - ss << msgNo; - win.Write(ss.str()); - msgNo++; - } - }); - - while (true) - { - std::string input; - std::getline(std::cin, input); - win.WriteFromStdin(input); - } - SocketUtil::CleanUp(); return 0; diff --git a/RoboCat/Src/MemoryBitStream.cpp b/RoboCat/Src/MemoryBitStream.cpp new file mode 100644 index 00000000..39958ad7 --- /dev/null +++ b/RoboCat/Src/MemoryBitStream.cpp @@ -0,0 +1,171 @@ +#include "RoboCatPCH.h" + +void OutputMemoryBitStream::WriteBits( uint8_t inData, + uint32_t inBitCount ) +{ + uint32_t nextBitHead = mBitHead + static_cast< uint32_t >( inBitCount ); + + if( nextBitHead > mBitCapacity ) + { + ReallocBuffer( std::max( mBitCapacity * 2, nextBitHead ) ); + } + + //calculate the byteOffset into our buffer + //by dividing the head by 8 + //and the bitOffset by taking the last 3 bits + uint32_t byteOffset = mBitHead >> 3; + uint32_t bitOffset = mBitHead & 0x7; + + uint8_t currentMask = ~( 0xff << bitOffset ); + mBuffer[ byteOffset ] = ( mBuffer[ byteOffset ] & currentMask ) | ( inData << bitOffset ); + + //calculate how many bits were not yet used in + //our target byte in the buffer + uint32_t bitsFreeThisByte = 8 - bitOffset; + + //if we needed more than that, carry to the next byte + if( bitsFreeThisByte < inBitCount ) + { + //we need another byte + mBuffer[ byteOffset + 1 ] = inData >> bitsFreeThisByte; + } + + mBitHead = nextBitHead; +} + +void OutputMemoryBitStream::WriteBits( const void* inData, uint32_t inBitCount ) +{ + const char* srcByte = static_cast< const char* >( inData ); + //write all the bytes + while( inBitCount > 8 ) + { + WriteBits( *srcByte, 8 ); + ++srcByte; + inBitCount -= 8; + } + //write anything left + if( inBitCount > 0 ) + { + WriteBits( *srcByte, inBitCount ); + } +} + +void OutputMemoryBitStream::Write( const Vector3& inVector ) +{ + Write( inVector.mX ); + Write( inVector.mY ); + Write( inVector.mZ ); +} + +void InputMemoryBitStream::Read( Vector3& outVector ) +{ + Read( outVector.mX ); + Read( outVector.mY ); + Read( outVector.mZ ); +} + +void OutputMemoryBitStream::Write( const Quaternion& inQuat ) +{ + float precision = ( 2.f / 65535.f ); + Write( ConvertToFixed( inQuat.mX, -1.f, precision ), 16 ); + Write( ConvertToFixed( inQuat.mY, -1.f, precision ), 16 ); + Write( ConvertToFixed( inQuat.mZ, -1.f, precision ), 16 ); + Write( inQuat.mW < 0 ); +} + + + +void OutputMemoryBitStream::ReallocBuffer( uint32_t inNewBitLength ) +{ + if( mBuffer == nullptr ) + { + //just need to memset on first allocation + mBuffer = static_cast( std::malloc( inNewBitLength >> 3 ) ); + memset( mBuffer, 0, inNewBitLength >> 3 ); + } + else + { + //need to memset, then copy the buffer + char* tempBuffer = static_cast( std::malloc( inNewBitLength >> 3 ) ); + memset( tempBuffer, 0, inNewBitLength >> 3 ); + memcpy( tempBuffer, mBuffer, mBitCapacity >> 3 ); + std::free( mBuffer ); + mBuffer = tempBuffer; + } + + //handle realloc failure + //... + mBitCapacity = inNewBitLength; +} + + +void test1() +{ + OutputMemoryBitStream mbs; + + mbs.WriteBits( 11, 5 ); + mbs.WriteBits( 52, 6 ); +} + +void InputMemoryBitStream::ReadBits( uint8_t& outData, uint32_t inBitCount ) +{ + uint32_t byteOffset = mBitHead >> 3; + uint32_t bitOffset = mBitHead & 0x7; + + outData = static_cast< uint8_t >( mBuffer[ byteOffset ] ) >> bitOffset; + + uint32_t bitsFreeThisByte = 8 - bitOffset; + if( bitsFreeThisByte < inBitCount ) + { + //we need another byte + outData |= static_cast< uint8_t >( mBuffer[ byteOffset + 1 ] ) << bitsFreeThisByte; + } + + //don't forget a mask so that we only read the bit we wanted... + outData &= ( ~( 0x00ff << inBitCount ) ); + + mBitHead += inBitCount; +} + +void InputMemoryBitStream::ReadBits( void* outData, uint32_t inBitCount ) +{ + uint8_t* destByte = reinterpret_cast< uint8_t* >( outData ); + //write all the bytes + while( inBitCount > 8 ) + { + ReadBits( *destByte, 8 ); + ++destByte; + inBitCount -= 8; + } + //write anything left + if( inBitCount > 0 ) + { + ReadBits( *destByte, inBitCount ); + } +} + +void InputMemoryBitStream::Read( Quaternion& outQuat ) +{ + float precision = ( 2.f / 65535.f ); + + uint32_t f = 0; + + Read( f, 16 ); + outQuat.mX = ConvertFromFixed( f, -1.f, precision ); + Read( f, 16 ); + outQuat.mY = ConvertFromFixed( f, -1.f, precision ); + Read( f, 16 ); + outQuat.mZ = ConvertFromFixed( f, -1.f, precision ); + + outQuat.mW = sqrtf( 1.f - + (outQuat.mX * outQuat.mX + + outQuat.mY * outQuat.mY + + outQuat.mZ * outQuat.mZ)); + bool isNegative; + Read( isNegative ); + + if( isNegative ) + { + outQuat.mW *= -1; + } +} From 75a1eced8ffd133a1527912b7ca7a7ea52690f61 Mon Sep 17 00:00:00 2001 From: Scott Barrett Date: Fri, 25 Feb 2022 00:54:08 -0500 Subject: [PATCH 02/29] add allegro package, update gitignore --- .gitignore | 1 + RoboCat/Chapter3.vcxproj | 15 ++++++++++++++- RoboCat/Src/Main.cpp | 4 ++++ RoboCat/packages.config | 5 +++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 RoboCat/packages.config diff --git a/.gitignore b/.gitignore index bea91a67..37c9fe57 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ *.pdb Debug/ +packages/ diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index 07598b73..c2d193be 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -399,6 +399,19 @@ + + + - + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index a5c1f9df..56756563 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -6,6 +6,8 @@ #include #include +#include + #if _WIN32 @@ -24,6 +26,8 @@ int main(int argc, const char** argv) SocketUtil::StaticInit(); + al_init(); + SocketUtil::CleanUp(); return 0; diff --git a/RoboCat/packages.config b/RoboCat/packages.config new file mode 100644 index 00000000..9ff6486d --- /dev/null +++ b/RoboCat/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From 3359377049a7cc511ceff428c30d1ff3d629dc52 Mon Sep 17 00:00:00 2001 From: Scott Barrett Date: Fri, 25 Feb 2022 01:04:46 -0500 Subject: [PATCH 03/29] remove unused code --- RoboCat/Src/Main.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 56756563..3b0ac9de 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -1,13 +1,6 @@ #include "RoboCatPCH.h" -#include -#include -#include -#include - -#include - #if _WIN32 @@ -26,8 +19,6 @@ int main(int argc, const char** argv) SocketUtil::StaticInit(); - al_init(); - SocketUtil::CleanUp(); return 0; From 0b1c4a5a9bc7287b457a46d8925e45c5bdc14398 Mon Sep 17 00:00:00 2001 From: Bradley Chamberlain Date: Sun, 27 Mar 2022 16:20:24 -0400 Subject: [PATCH 04/29] Adding allegro linking --- RoboCat/Chapter3.vcxproj | 5 +++-- RoboCat/Src/Main.cpp | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index c2d193be..7e73cebf 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -127,12 +127,12 @@ WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) ProgramDatabase EnableFastChecks - ..\SDL\include;Inc;..\ + ..\SDL\include;Inc;..\;$(SolutionDir)packages\Allegro.5.2.7.1\build\native\include\allegro5 Use RoboCatPCH.h - d3d11.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies);Ws2_32.lib + allegro.lib;d3d11.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies);Ws2_32.lib true true true @@ -141,6 +141,7 @@ AsInvoker %(DelayLoadDLLs) Console + $(SolutionDir)packages/Allegro.5.2.7.1\build\native\v143\win32\lib true diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 3b0ac9de..0e755d6b 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -1,6 +1,6 @@ #include "RoboCatPCH.h" - +#include "allegro.h" #if _WIN32 @@ -17,9 +17,24 @@ int main(int argc, const char** argv) __argv = argv; #endif - SocketUtil::StaticInit(); + + + ALLEGRO_DISPLAY* display; + if (!al_init()) + { + printf("fuck"); + } + display = al_create_display(800, 600); + + system("pause"); + + //socket stuff here + SocketUtil::StaticInit(); // socket initialization + + //create a server + UDPSocketPtr serverSocket; - SocketUtil::CleanUp(); + SocketUtil::CleanUp(); // socket cleanup return 0; } From b02fb1f15e8175b1dcc63beeb82bf466d6b33150 Mon Sep 17 00:00:00 2001 From: Bradley Chamberlain Date: Sun, 27 Mar 2022 18:03:47 -0400 Subject: [PATCH 05/29] Dem Sockets tho --- RoboCat/Chapter3.vcxproj | 2 +- RoboCat/Src/Main.cpp | 255 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 250 insertions(+), 7 deletions(-) diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index 7e73cebf..9a024d79 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -132,7 +132,7 @@ RoboCatPCH.h - allegro.lib;d3d11.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies);Ws2_32.lib + allegro_color.lib;allegro_primitives.lib;allegro.lib;d3d11.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies);Ws2_32.lib true true true diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 0e755d6b..1dcc9886 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -1,8 +1,217 @@ #include "RoboCatPCH.h" -#include "allegro.h" +#include "allegro5.h" +#include "allegro_primitives.h" +#include "allegro_color.h" + +#include +#include +#include +#include + +using namespace std; + #if _WIN32 +void ThrowSocketError(std::string errorMsg) +{ + SocketUtil::ReportError(errorMsg.c_str()); + ExitProcess(1); // kill +} + +void BradsTotallyOriginalServer() +{ + // create a socket to listen for input data + //Create a SERVER + + // listening socket to take in new clients + TCPSocketPtr listeningSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (listeningSocket == nullptr) + ThrowSocketError("Could not create socket: NullPtr"); + + //create a ptr for the port + SocketAddressPtr addressPtr = SocketAddressFactory::CreateIPv4FromString("0.0.0.0:8080"); // a hard-coded port to bind to + if (addressPtr == nullptr) + ThrowSocketError("Could not create server address"); + + // Bind listening socket to an address + bool bindError = listeningSocket->Bind(*addressPtr) != NO_ERROR; // bind the socket and check if there is an error + if (bindError) + ThrowSocketError("Could not bind to address"); + + // Listen on listeningSocket + bool listenError = listeningSocket->Listen() != NO_ERROR; + if (listenError) + ThrowSocketError("Listen Error"); + + // accept is a blocking function so it will halt the program execution until it recieves a incoming connection + + LOG("%s", "Waiting to accept connections..."); + + SocketAddress incomingAddress; + TCPSocketPtr incomingSocket = listeningSocket->Accept(incomingAddress); + while (incomingSocket == nullptr) // if it didnt work the first time, try again + { + incomingSocket = listeningSocket->Accept(incomingAddress); + } + + // CONECTION ACCEPTED WE HAVE CONTACT ============================== + LOG("Request accepted from: %s", incomingAddress.ToString().c_str()); + + // input username + std::string username; + std::cout << "Please Input Your Username: "; + std::getline(std::cin, username); + std::cout << "Waiting for other user to enter their username..." << std::endl; + //send username + incomingSocket->Send(username.c_str(), username.length()); + + //receive username + char buffer[4096]; + int32_t bytesReceived = incomingSocket->Receive(buffer, 4096); // get username + while (bytesReceived < 0) + { + bytesReceived = incomingSocket->Receive(buffer, 4096); + } + + std::string otherUsername(buffer, bytesReceived); + std::cout << "Other user " << otherUsername.c_str() << " has joined the chatroom" << std::endl; + + bool exit = false; + //send data + std::thread SendThread([&incomingSocket, &exit]() + { + //send message + std::string msg; + while (!exit) + { + std::getline(std::cin, msg); //BLOCKS + incomingSocket->Send(msg.c_str(), msg.length()); + + if (msg == "/exit") + { + //incomingSocket->~TCPSocket(); + exit = true; + std::cout << "connection terminated" << std::endl; + break; + } + } + }); + + //receive data + while (bytesReceived < 4096 && !exit) + { + bytesReceived = incomingSocket->Receive(buffer, 4096); + if (bytesReceived <= 0) + { + exit = true; + break; + } + std::string receivedMsg(buffer, bytesReceived); + std::cout << otherUsername.c_str() << ": " << receivedMsg.c_str() << std::endl; + if (receivedMsg == "/exit") + { + //incomingSocket->~TCPSocket(); + exit = true; + std::cout << "connection terminated" << std::endl; + } + } + incomingSocket->~TCPSocket(); +} + +void BradsLessOriginalClient() +{ + TCPSocketPtr clientSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (clientSocket == nullptr) + ThrowSocketError("Could not create client socket"); + + std::string port; + port = StringUtils::GetCommandLineArg(2); + std::string address = StringUtils::Sprintf("127.0.0.1:%s", port.c_str()); + //std::string address = StringUtils::Sprintf("127.0.0.1:8081"); + SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); + if (clientAddress == nullptr) + ThrowSocketError("Creating client address"); + + if (clientSocket->Bind(*clientAddress) != NO_ERROR) + ThrowSocketError("Binding Client Socket"); + + // Connect() -> Connect socket to remote host + + SocketAddressPtr serverAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:8080"); + if (serverAddress == nullptr) + ThrowSocketError("Creating server address"); + + if (clientSocket->Connect(*serverAddress) != NO_ERROR) + ThrowSocketError("Connecting to server"); + + //LOG("%s", "Connected to server!"); + + // input username + std::string username; + std::cout << "Please Input Your Username: "; + std::getline(std::cin, username); + std::cout << "Waiting for other user to enter their username..." << std::endl; + // send username + clientSocket->Send(username.c_str(), username.length()); + + + // receive other username + char otherUsernameBuffer[40]; + int32_t otherUsernameBytes = clientSocket->Receive(otherUsernameBuffer, 40); + while (otherUsernameBytes < 0) + { + otherUsernameBytes = clientSocket->Receive(otherUsernameBuffer, 40); + } + std::string otherUsername(otherUsernameBuffer, otherUsernameBytes); + std::cout << "Other user " << otherUsername.c_str() << " has joined the chatroom" << std::endl; + + bool exit = false; + + std::thread SendThread([&clientSocket, &exit]() + { + //Fulfill username request + std::string msg; + std::getline(std::cin, msg); //BLOCKS + clientSocket->Send(msg.c_str(), msg.length()); + while (!exit) + { + std::getline(std::cin, msg);//BLOCKS + clientSocket->Send(msg.c_str(), msg.length()); + + if (msg == "/exit") + { + //clientSocket->~TCPSocket(); + exit = true; + std::cout << "connection terminated" << std::endl; + break; + } + } + }); + + char buffer[4096]; + int32_t bytesReceived = int32_t(); + //bool exit = false; + while (bytesReceived < 4096 && !exit) + { + + bytesReceived = clientSocket->Receive(buffer, 4096); + if (bytesReceived <= 0) + { + exit = true; + break; + } + std::string receivedMsg(buffer, bytesReceived); + std::cout << otherUsername.c_str() << ": " << receivedMsg.c_str() << std::endl; + if (receivedMsg == "/exit") + { + //clientSocket->~TCPSocket(); + exit = true; + std::cout << "connection terminated" << std::endl; + } + } + clientSocket->~TCPSocket(); +} int main(int argc, const char** argv) { @@ -17,24 +226,58 @@ int main(int argc, const char** argv) __argv = argv; #endif - - ALLEGRO_DISPLAY* display; if (!al_init()) { printf("fuck"); + return -1; } + + al_init_primitives_addon(); + al_install_keyboard(); + display = al_create_display(800, 600); - system("pause"); + ALLEGRO_COLOR color; + color = al_map_rgb(255, 0, 0); + + al_draw_rectangle(10, 10, 100, 100, al_map_rgb(255, 0, 0), 2); + al_flip_display(); + + //system("pause"); //socket stuff here SocketUtil::StaticInit(); // socket initialization - //create a server - UDPSocketPtr serverSocket; + /* + + */ + //accept thread + bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' + if (isServer) // if it is the server + { + BradsTotallyOriginalServer(); + /* + bool exit = false; + thread AcceptThread([&exit, &listeningSocket]() + { + while (!exit) + { + SocketAddress clientAddress; + TCPSocketPtr clientSocket = listeningSocket->Accept(clientAddress); // accept blocks + } + + }); + AcceptThread.join(); + */ + } + else + { + BradsLessOriginalClient(); + } SocketUtil::CleanUp(); // socket cleanup return 0; } + From 69daf6e7a9fc1687cd3363ea3214be10ee8f733d Mon Sep 17 00:00:00 2001 From: Bradley Chamberlain Date: Sun, 27 Mar 2022 18:44:39 -0400 Subject: [PATCH 06/29] small main changes --- RoboCat/Src/Main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 1dcc9886..105ecee9 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -146,7 +146,7 @@ void BradsLessOriginalClient() ThrowSocketError("Connecting to server"); //LOG("%s", "Connected to server!"); - + /* // input username std::string username; std::cout << "Please Input Your Username: "; @@ -154,8 +154,9 @@ void BradsLessOriginalClient() std::cout << "Waiting for other user to enter their username..." << std::endl; // send username clientSocket->Send(username.c_str(), username.length()); + */ - + /* // receive other username char otherUsernameBuffer[40]; int32_t otherUsernameBytes = clientSocket->Receive(otherUsernameBuffer, 40); @@ -165,7 +166,7 @@ void BradsLessOriginalClient() } std::string otherUsername(otherUsernameBuffer, otherUsernameBytes); std::cout << "Other user " << otherUsername.c_str() << " has joined the chatroom" << std::endl; - + */ bool exit = false; std::thread SendThread([&clientSocket, &exit]() @@ -191,7 +192,6 @@ void BradsLessOriginalClient() char buffer[4096]; int32_t bytesReceived = int32_t(); - //bool exit = false; while (bytesReceived < 4096 && !exit) { @@ -202,7 +202,7 @@ void BradsLessOriginalClient() break; } std::string receivedMsg(buffer, bytesReceived); - std::cout << otherUsername.c_str() << ": " << receivedMsg.c_str() << std::endl; + //std::cout << otherUsername.c_str() << ": " << receivedMsg.c_str() << std::endl; if (receivedMsg == "/exit") { //clientSocket->~TCPSocket(); From 545e4f52271eecd124d809b9dfc41a334e29cfbc Mon Sep 17 00:00:00 2001 From: bradley Date: Mon, 28 Mar 2022 21:42:41 -0400 Subject: [PATCH 07/29] some preference changes --- RoboCat/Chapter3.vcxproj | 6 +++- RoboCat/Src/Main.cpp | 62 ++++++++++++++-------------------------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index 9a024d79..91efd693 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -92,6 +92,10 @@ true true Bin\$(Configuration)\ + true + true + true + true true @@ -128,7 +132,7 @@ ProgramDatabase EnableFastChecks ..\SDL\include;Inc;..\;$(SolutionDir)packages\Allegro.5.2.7.1\build\native\include\allegro5 - Use + NotUsing RoboCatPCH.h diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 105ecee9..95d386fb 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -3,6 +3,7 @@ #include "allegro5.h" #include "allegro_primitives.h" #include "allegro_color.h" +#include "MemoryBitStream.h" #include #include @@ -10,7 +11,18 @@ #include using namespace std; - +/* +class GameObject +{ +public: + void Read(InputMemoryStream& stream); + void Write(OutputMemoryStream& stream) const; +private: + float x; + float y; + int health; +}; +*/ #if _WIN32 void ThrowSocketError(std::string errorMsg) @@ -145,28 +157,6 @@ void BradsLessOriginalClient() if (clientSocket->Connect(*serverAddress) != NO_ERROR) ThrowSocketError("Connecting to server"); - //LOG("%s", "Connected to server!"); - /* - // input username - std::string username; - std::cout << "Please Input Your Username: "; - std::getline(std::cin, username); - std::cout << "Waiting for other user to enter their username..." << std::endl; - // send username - clientSocket->Send(username.c_str(), username.length()); - */ - - /* - // receive other username - char otherUsernameBuffer[40]; - int32_t otherUsernameBytes = clientSocket->Receive(otherUsernameBuffer, 40); - while (otherUsernameBytes < 0) - { - otherUsernameBytes = clientSocket->Receive(otherUsernameBuffer, 40); - } - std::string otherUsername(otherUsernameBuffer, otherUsernameBytes); - std::cout << "Other user " << otherUsername.c_str() << " has joined the chatroom" << std::endl; - */ bool exit = false; std::thread SendThread([&clientSocket, &exit]() @@ -213,6 +203,8 @@ void BradsLessOriginalClient() clientSocket->~TCPSocket(); } + + int main(int argc, const char** argv) { UNREFERENCED_PARAMETER(argc); @@ -226,6 +218,8 @@ int main(int argc, const char** argv) __argv = argv; #endif + bool exit = false; + ALLEGRO_DISPLAY* display; if (!al_init()) { @@ -248,34 +242,22 @@ int main(int argc, const char** argv) //socket stuff here SocketUtil::StaticInit(); // socket initialization - - /* - - */ //accept thread bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' if (isServer) // if it is the server { BradsTotallyOriginalServer(); - /* - bool exit = false; - thread AcceptThread([&exit, &listeningSocket]() - { - while (!exit) - { - SocketAddress clientAddress; - TCPSocketPtr clientSocket = listeningSocket->Accept(clientAddress); // accept blocks - } - - }); - AcceptThread.join(); - */ } else { BradsLessOriginalClient(); } + while (!exit) + { + + } + SocketUtil::CleanUp(); // socket cleanup return 0; From c5d2dcdae445536384a20e7171982b6954ad671b Mon Sep 17 00:00:00 2001 From: bradley Date: Tue, 29 Mar 2022 03:35:05 -0400 Subject: [PATCH 08/29] Banannas --- RoboCat/Src/Main.cpp | 494 +++++++++++++++++++++++++++++++++---------- 1 file changed, 387 insertions(+), 107 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 95d386fb..b378f2da 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -3,7 +3,6 @@ #include "allegro5.h" #include "allegro_primitives.h" #include "allegro_color.h" -#include "MemoryBitStream.h" #include #include @@ -11,19 +10,97 @@ #include using namespace std; -/* +int windowWidth = 800; +int windowHeight = 600; +int FPS = 30; + +#if _WIN32 + class GameObject { public: - void Read(InputMemoryStream& stream); - void Write(OutputMemoryStream& stream) const; + + void Read(InputMemoryBitStream& stream); + void Write(OutputMemoryBitStream& stream) const; + GameObject::GameObject(int newWidth, int newHeight, int startPosX, int startPosY); + GameObject::GameObject(); + void UpdatePos(int xChange, int yChange); + void Draw(); private: - float x; - float y; - int health; + int width; + int height; + int xPos; + int yPos; }; -*/ -#if _WIN32 + + +void GameObject::Read(InputMemoryBitStream& stream) +{ + stream.Read(width); + stream.Read(height); + stream.Read(xPos); + stream.Read(yPos); +} + +void GameObject::Write(OutputMemoryBitStream& stream) const +{ + stream.Write(width); + stream.Write(height); + stream.Write(xPos); + stream.Write(yPos); +} + +GameObject::GameObject(int newWidth, int newHeight, int startPosX, int startPosY) +{ + width = newWidth; + height = newHeight; + xPos = startPosX; + yPos = startPosY; +} +GameObject::GameObject() +{ + width = 10; + height = 10; + xPos = rand() % 100 + 1; + yPos = rand() % 100 + 1; +} + +void GameObject::UpdatePos(int xChange, int yChange) +{ + //Update blockPosition + /* + int xStep = rand() % 2 + 1; + //int xStep = 1; + int yStep = rand() % 2 + 1; + //int yStep = 1; + int randNum = rand() % (2 - 1 + 1) + 1; + if (randNum == 1) + { + xPos += xStep; + yPos += yStep; + } + if (randNum == 2) + { + xPos -= xStep; + yPos -= yStep; + } + if (xPos > windowWidth) xPos = 0; + if (yPos > windowHeight) yPos = 0; + if (xPos < 0) xPos = windowWidth; + if (yPos < 0) yPos = windowHeight; + */ + xPos += xChange; + yPos += yChange; + if (xPos > windowWidth) xPos = 0; + if (yPos > windowHeight) yPos = 0; + if (xPos < 0) xPos = windowWidth; + if (yPos < 0) yPos = windowHeight; +} + +void GameObject::Draw() +{ + al_draw_rectangle(xPos, yPos, xPos + width, yPos + height, al_map_rgb(255, 0, 0), 2); +} void ThrowSocketError(std::string errorMsg) { @@ -31,10 +108,94 @@ void ThrowSocketError(std::string errorMsg) ExitProcess(1); // kill } +void RunGameLoop(GameObject objects[], int numObjects) +{ + bool exit = false; + + std::thread UpdateThread([&objects, &numObjects, &exit]() + { + ALLEGRO_DISPLAY* display; + display = al_create_display(windowWidth, windowHeight); + + ALLEGRO_KEYBOARD_STATE keyState; + ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); + al_register_event_source(eventQueue, al_get_keyboard_event_source()); + + int xAxis = 0; + int yAxis = 0; + + bool xMove = true; + bool yMove = true; + + while (!exit) //GameLoop + { + //Get keyboardInput + ALLEGRO_EVENT events; + + al_get_next_event(eventQueue, &events); + if (events.type == ALLEGRO_EVENT_KEY_UP) + { + switch (events.keyboard.keycode) + { + case ALLEGRO_KEY_ESCAPE: + exit = true; + case ALLEGRO_KEY_UP: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_DOWN: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_RIGHT: + xAxis = 0; + xMove = false; + case ALLEGRO_KEY_LEFT: + xAxis = 0; + xMove = false; + } + } + if (events.type == ALLEGRO_EVENT_KEY_DOWN) + { + al_get_keyboard_state(&keyState); + if (al_key_down(&keyState, ALLEGRO_KEY_UP)) + { + yMove = true; + yAxis = -1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + { + yMove = true; + yAxis = 1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + { + xAxis = 1; + xMove = true; + } + + else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + { + xAxis = -1; + xMove = true; + } + } + + for (int i = 0; i < numObjects; i++) + { + if (xMove || yMove) + { + objects[i].UpdatePos(xAxis, yAxis); + } + objects[i].Draw(); + } + al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + }); + UpdateThread.join(); +} + void BradsTotallyOriginalServer() { - // create a socket to listen for input data - //Create a SERVER // listening socket to take in new clients TCPSocketPtr listeningSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); @@ -56,8 +217,6 @@ void BradsTotallyOriginalServer() if (listenError) ThrowSocketError("Listen Error"); - // accept is a blocking function so it will halt the program execution until it recieves a incoming connection - LOG("%s", "Waiting to accept connections..."); SocketAddress incomingAddress; @@ -68,65 +227,132 @@ void BradsTotallyOriginalServer() } // CONECTION ACCEPTED WE HAVE CONTACT ============================== - LOG("Request accepted from: %s", incomingAddress.ToString().c_str()); + LOG("Request accepted from: %s", incomingAddress.ToString().c_str()); - // input username - std::string username; - std::cout << "Please Input Your Username: "; - std::getline(std::cin, username); - std::cout << "Waiting for other user to enter their username..." << std::endl; - //send username - incomingSocket->Send(username.c_str(), username.length()); + //GAMELOOP + bool exit = false; + const int numObjects = 1; - //receive username - char buffer[4096]; - int32_t bytesReceived = incomingSocket->Receive(buffer, 4096); // get username - while (bytesReceived < 0) + GameObject objects[numObjects]; + for (int j = 0; j < numObjects; j++) { - bytesReceived = incomingSocket->Receive(buffer, 4096); + objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); } - - std::string otherUsername(buffer, bytesReceived); - std::cout << "Other user " << otherUsername.c_str() << " has joined the chatroom" << std::endl; - - bool exit = false; //send data - std::thread SendThread([&incomingSocket, &exit]() + std::thread SendThread([&incomingSocket, &exit, &objects, &numObjects]() { //send message - std::string msg; + OutputMemoryBitStream oStream = OutputMemoryBitStream(); + for (int i = 0; i < numObjects; i++) + { + objects[i].Write(oStream); + } while (!exit) { - std::getline(std::cin, msg); //BLOCKS - incomingSocket->Send(msg.c_str(), msg.length()); - - if (msg == "/exit") + for (int i = 0; i < numObjects; i++) { - //incomingSocket->~TCPSocket(); - exit = true; - std::cout << "connection terminated" << std::endl; - break; + objects[i].Write(oStream); } + incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } }); + //SendThread.join(); + + + + std::thread UpdateThread([&objects, &numObjects, &exit]() + { + ALLEGRO_DISPLAY* display; + display = al_create_display(windowWidth, windowHeight); + + ALLEGRO_KEYBOARD_STATE keyState; + ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); + al_register_event_source(eventQueue, al_get_keyboard_event_source()); + int xAxis = 0; + int yAxis = 0; + + bool xMove = true; + bool yMove = true; + + while (!exit) //GameLoop + { + //Get keyboardInput + ALLEGRO_EVENT events; + + al_get_next_event(eventQueue, &events); + if (events.type == ALLEGRO_EVENT_KEY_UP) + { + switch (events.keyboard.keycode) + { + case ALLEGRO_KEY_ESCAPE: + exit = true; + case ALLEGRO_KEY_UP: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_DOWN: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_RIGHT: + xAxis = 0; + xMove = false; + case ALLEGRO_KEY_LEFT: + xAxis = 0; + xMove = false; + } + } + if (events.type == ALLEGRO_EVENT_KEY_DOWN) + { + al_get_keyboard_state(&keyState); + if (al_key_down(&keyState, ALLEGRO_KEY_UP)) + { + yMove = true; + yAxis = -1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + { + yMove = true; + yAxis = 1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + { + xAxis = 1; + xMove = true; + } + + else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + { + xAxis = -1; + xMove = true; + } + } + + for (int i = 0; i < numObjects; i++) + { + if (xMove || yMove) + { + objects[i].UpdatePos(xAxis, yAxis); + } + objects[i].Draw(); + } + al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + }); + UpdateThread.join(); //receive data - while (bytesReceived < 4096 && !exit) + char buffer[4096]; + int32_t bytesReceived = int32_t(); // get username + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + while (!exit) { + LOG("%s","server game loop"); bytesReceived = incomingSocket->Receive(buffer, 4096); - if (bytesReceived <= 0) - { - exit = true; - break; - } - std::string receivedMsg(buffer, bytesReceived); - std::cout << otherUsername.c_str() << ": " << receivedMsg.c_str() << std::endl; - if (receivedMsg == "/exit") - { - //incomingSocket->~TCPSocket(); - exit = true; - std::cout << "connection terminated" << std::endl; - } + + GameObject inObj = GameObject(); + iStream.Read(inObj); + + al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos+inObj.width, inObj.yPos+inObj.height, al_map_rgb(255, 0, 0), 2); } incomingSocket->~TCPSocket(); } @@ -137,10 +363,10 @@ void BradsLessOriginalClient() if (clientSocket == nullptr) ThrowSocketError("Could not create client socket"); - std::string port; - port = StringUtils::GetCommandLineArg(2); - std::string address = StringUtils::Sprintf("127.0.0.1:%s", port.c_str()); - //std::string address = StringUtils::Sprintf("127.0.0.1:8081"); + //std::string port; + //port = StringUtils::GetCommandLineArg(2); + //std::string address = StringUtils::Sprintf("127.0.0.1:%s", port.c_str()); + std::string address = StringUtils::Sprintf("127.0.0.1:8081"); SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); if (clientAddress == nullptr) ThrowSocketError("Creating client address"); @@ -148,8 +374,6 @@ void BradsLessOriginalClient() if (clientSocket->Bind(*clientAddress) != NO_ERROR) ThrowSocketError("Binding Client Socket"); - // Connect() -> Connect socket to remote host - SocketAddressPtr serverAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:8080"); if (serverAddress == nullptr) ThrowSocketError("Creating server address"); @@ -157,14 +381,19 @@ void BradsLessOriginalClient() if (clientSocket->Connect(*serverAddress) != NO_ERROR) ThrowSocketError("Connecting to server"); + //GameLoop bool exit = false; + const int numObjects = 1; + + GameObject objects[numObjects]; + for (int j = 0; j < numObjects; j++) + { + objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); + } std::thread SendThread([&clientSocket, &exit]() { - //Fulfill username request std::string msg; - std::getline(std::cin, msg); //BLOCKS - clientSocket->Send(msg.c_str(), msg.length()); while (!exit) { std::getline(std::cin, msg);//BLOCKS @@ -178,33 +407,109 @@ void BradsLessOriginalClient() break; } } + }); + + + std::thread UpdateThread([&objects, &numObjects, &exit]() + { + ALLEGRO_DISPLAY* display; + display = al_create_display(windowWidth, windowHeight); + + ALLEGRO_KEYBOARD_STATE keyState; + ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); + al_register_event_source(eventQueue, al_get_keyboard_event_source()); + + int xAxis = 0; + int yAxis = 0; + + bool xMove = true; + bool yMove = true; + + while (!exit) //GameLoop + { + //Get keyboardInput + ALLEGRO_EVENT events; + + al_get_next_event(eventQueue, &events); + if (events.type == ALLEGRO_EVENT_KEY_UP) + { + switch (events.keyboard.keycode) + { + case ALLEGRO_KEY_ESCAPE: + exit = true; + case ALLEGRO_KEY_UP: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_DOWN: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_RIGHT: + xAxis = 0; + xMove = false; + case ALLEGRO_KEY_LEFT: + xAxis = 0; + xMove = false; + } + } + if (events.type == ALLEGRO_EVENT_KEY_DOWN) + { + al_get_keyboard_state(&keyState); + if (al_key_down(&keyState, ALLEGRO_KEY_UP)) + { + yMove = true; + yAxis = -1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + { + yMove = true; + yAxis = 1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + { + xAxis = 1; + xMove = true; + } + + else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + { + xAxis = -1; + xMove = true; + } + } + + for (int i = 0; i < numObjects; i++) + { + if (xMove || yMove) + { + objects[i].UpdatePos(xAxis, yAxis); + } + objects[i].Draw(); + } + al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + }); + UpdateThread.join(); + //receive data char buffer[4096]; + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); - while (bytesReceived < 4096 && !exit) + while (!exit) { - + LOG("%s", "server game loop"); bytesReceived = clientSocket->Receive(buffer, 4096); - if (bytesReceived <= 0) - { - exit = true; - break; - } - std::string receivedMsg(buffer, bytesReceived); - //std::cout << otherUsername.c_str() << ": " << receivedMsg.c_str() << std::endl; - if (receivedMsg == "/exit") - { - //clientSocket->~TCPSocket(); - exit = true; - std::cout << "connection terminated" << std::endl; - } + + GameObject inObj = GameObject(); + iStream.Read(inObj); + + al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos + inObj.width, inObj.yPos + inObj.height, al_map_rgb(255, 0, 0), 2); } clientSocket->~TCPSocket(); } - int main(int argc, const char** argv) { UNREFERENCED_PARAMETER(argc); @@ -218,30 +523,11 @@ int main(int argc, const char** argv) __argv = argv; #endif - bool exit = false; - - ALLEGRO_DISPLAY* display; - if (!al_init()) - { - printf("fuck"); - return -1; - } + SocketUtil::StaticInit(); // socket initialization + if (!al_init()) return -1; al_init_primitives_addon(); al_install_keyboard(); - - display = al_create_display(800, 600); - - ALLEGRO_COLOR color; - color = al_map_rgb(255, 0, 0); - - al_draw_rectangle(10, 10, 100, 100, al_map_rgb(255, 0, 0), 2); - al_flip_display(); - - //system("pause"); - - //socket stuff here - SocketUtil::StaticInit(); // socket initialization //accept thread bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' if (isServer) // if it is the server @@ -253,13 +539,7 @@ int main(int argc, const char** argv) BradsLessOriginalClient(); } - while (!exit) - { - - } - SocketUtil::CleanUp(); // socket cleanup - return 0; } From af23fde39f3742728f78874e975045645bb669bc Mon Sep 17 00:00:00 2001 From: bradley Date: Tue, 29 Mar 2022 03:35:30 -0400 Subject: [PATCH 09/29] banannas --- RoboCat/Src/Main.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index b378f2da..918c5e94 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -19,18 +19,16 @@ int FPS = 30; class GameObject { public: - + int width; + int height; + int xPos; + int yPos; void Read(InputMemoryBitStream& stream); void Write(OutputMemoryBitStream& stream) const; GameObject::GameObject(int newWidth, int newHeight, int startPosX, int startPosY); GameObject::GameObject(); void UpdatePos(int xChange, int yChange); void Draw(); -private: - int width; - int height; - int xPos; - int yPos; }; From 5cdfc323c2f5cf58d46ff82c351e290291703245 Mon Sep 17 00:00:00 2001 From: Bradley Date: Tue, 29 Mar 2022 04:20:03 -0400 Subject: [PATCH 10/29] input --- RoboCat/Src/Main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 918c5e94..2094a212 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -348,7 +348,7 @@ void BradsTotallyOriginalServer() bytesReceived = incomingSocket->Receive(buffer, 4096); GameObject inObj = GameObject(); - iStream.Read(inObj); + //iStream.Read(inObj); al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos+inObj.width, inObj.yPos+inObj.height, al_map_rgb(255, 0, 0), 2); } @@ -459,18 +459,18 @@ void BradsLessOriginalClient() yMove = true; yAxis = -1; } - else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) { yMove = true; yAxis = 1; } - else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) { xAxis = 1; xMove = true; } - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) { xAxis = -1; xMove = true; @@ -500,7 +500,7 @@ void BradsLessOriginalClient() bytesReceived = clientSocket->Receive(buffer, 4096); GameObject inObj = GameObject(); - iStream.Read(inObj); + //iStream.Read(inObj); al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos + inObj.width, inObj.yPos + inObj.height, al_map_rgb(255, 0, 0), 2); } From 7058582a69ba7058ed952fdff05529e3d250d763 Mon Sep 17 00:00:00 2001 From: Bradley Chamberlain Date: Tue, 29 Mar 2022 14:18:41 -0400 Subject: [PATCH 11/29] oof --- RoboCat/Src/Main.cpp | 205 ++++++++++++++----------------------------- 1 file changed, 68 insertions(+), 137 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 2094a212..e6864ffe 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -38,6 +38,7 @@ void GameObject::Read(InputMemoryBitStream& stream) stream.Read(height); stream.Read(xPos); stream.Read(yPos); + } void GameObject::Write(OutputMemoryBitStream& stream) const @@ -106,91 +107,7 @@ void ThrowSocketError(std::string errorMsg) ExitProcess(1); // kill } -void RunGameLoop(GameObject objects[], int numObjects) -{ - bool exit = false; - - std::thread UpdateThread([&objects, &numObjects, &exit]() - { - ALLEGRO_DISPLAY* display; - display = al_create_display(windowWidth, windowHeight); - - ALLEGRO_KEYBOARD_STATE keyState; - ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); - al_register_event_source(eventQueue, al_get_keyboard_event_source()); - - int xAxis = 0; - int yAxis = 0; - - bool xMove = true; - bool yMove = true; - - while (!exit) //GameLoop - { - //Get keyboardInput - ALLEGRO_EVENT events; - - al_get_next_event(eventQueue, &events); - if (events.type == ALLEGRO_EVENT_KEY_UP) - { - switch (events.keyboard.keycode) - { - case ALLEGRO_KEY_ESCAPE: - exit = true; - case ALLEGRO_KEY_UP: - yMove = false; - yAxis = 0; - case ALLEGRO_KEY_DOWN: - yMove = false; - yAxis = 0; - case ALLEGRO_KEY_RIGHT: - xAxis = 0; - xMove = false; - case ALLEGRO_KEY_LEFT: - xAxis = 0; - xMove = false; - } - } - if (events.type == ALLEGRO_EVENT_KEY_DOWN) - { - al_get_keyboard_state(&keyState); - if (al_key_down(&keyState, ALLEGRO_KEY_UP)) - { - yMove = true; - yAxis = -1; - } - else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) - { - yMove = true; - yAxis = 1; - } - else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) - { - xAxis = 1; - xMove = true; - } - - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) - { - xAxis = -1; - xMove = true; - } - } - for (int i = 0; i < numObjects; i++) - { - if (xMove || yMove) - { - objects[i].UpdatePos(xAxis, yAxis); - } - objects[i].Draw(); - } - al_flip_display(); - al_clear_to_color(al_map_rgb(0, 0, 0)); - } - }); - UpdateThread.join(); -} void BradsTotallyOriginalServer() { @@ -240,13 +157,10 @@ void BradsTotallyOriginalServer() std::thread SendThread([&incomingSocket, &exit, &objects, &numObjects]() { //send message - OutputMemoryBitStream oStream = OutputMemoryBitStream(); - for (int i = 0; i < numObjects; i++) - { - objects[i].Write(oStream); - } - while (!exit) + while (1) { + OutputMemoryBitStream oStream = OutputMemoryBitStream(); + for (int i = 0; i < numObjects; i++) { objects[i].Write(oStream); @@ -255,10 +169,28 @@ void BradsTotallyOriginalServer() } }); //SendThread.join(); - - - std::thread UpdateThread([&objects, &numObjects, &exit]() + GameObject inObj = GameObject(); + thread RecieveThread([&exit, &incomingSocket, &inObj]() + { + char buffer[4096]; + int32_t bytesReceived = int32_t(); // get username + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + while (1) + { + LOG("%s %s", "server game loop", exit); + bytesReceived = incomingSocket->Receive(buffer, 4096); + + inObj.Read(iStream); + + } + incomingSocket->~TCPSocket(); + }); + //SendThread.join(); + //UpdateThread.join(); + //RecieveThread.join(); + + std::thread ServerUpdateThread([&objects, &numObjects, &exit, &inObj]() { ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -332,27 +264,18 @@ void BradsTotallyOriginalServer() objects[i].UpdatePos(xAxis, yAxis); } objects[i].Draw(); + inObj.Draw(); } al_flip_display(); al_clear_to_color(al_map_rgb(0, 0, 0)); } + //al_destroy_display(display); + }); - UpdateThread.join(); + //ServerUpdateThread.join(); //receive data - char buffer[4096]; - int32_t bytesReceived = int32_t(); // get username - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - while (!exit) - { - LOG("%s","server game loop"); - bytesReceived = incomingSocket->Receive(buffer, 4096); - - GameObject inObj = GameObject(); - //iStream.Read(inObj); + - al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos+inObj.width, inObj.yPos+inObj.height, al_map_rgb(255, 0, 0), 2); - } - incomingSocket->~TCPSocket(); } void BradsLessOriginalClient() @@ -389,28 +312,46 @@ void BradsLessOriginalClient() objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); } - std::thread SendThread([&clientSocket, &exit]() + std::thread ClientSendThread([&clientSocket, &exit, &objects, &numObjects]() { - std::string msg; - while (!exit) + //send message + while (1) { - std::getline(std::cin, msg);//BLOCKS - clientSocket->Send(msg.c_str(), msg.length()); + OutputMemoryBitStream oStream = OutputMemoryBitStream(); - if (msg == "/exit") + for (int i = 0; i < numObjects; i++) { - //clientSocket->~TCPSocket(); - exit = true; - std::cout << "connection terminated" << std::endl; - break; + objects[i].Write(oStream); } + clientSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } }); + //ClientSendThread.join(); + GameObject inObj = GameObject(); + thread ClientRecieveThread([&exit, &clientSocket, &numObjects,&inObj]() + { + char buffer[4096]; + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + int32_t bytesReceived = int32_t(); + while (1) + { + LOG("%s", "server game loop"); + bytesReceived = clientSocket->Receive(buffer, 4096); + + inObj.Read(iStream); + + //al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos + inObj.width, inObj.yPos + inObj.height, al_map_rgb(255, 0, 0), 2); + + } + clientSocket->~TCPSocket(); + }); + //SendThread.join(); + //UpdateThread.join(); + //ClientRecieveThread.join(); - - std::thread UpdateThread([&objects, &numObjects, &exit]() + std::thread ClientUpdateThread([&objects, &numObjects, &exit, &inObj]() { ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -459,18 +400,18 @@ void BradsLessOriginalClient() yMove = true; yAxis = -1; } - if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) { yMove = true; yAxis = 1; } - if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) { xAxis = 1; xMove = true; } - if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) { xAxis = -1; xMove = true; @@ -484,27 +425,17 @@ void BradsLessOriginalClient() objects[i].UpdatePos(xAxis, yAxis); } objects[i].Draw(); + inObj.Draw(); } al_flip_display(); al_clear_to_color(al_map_rgb(0, 0, 0)); } + //al_destroy_display(display); + //al_destroy_display(display); }); - UpdateThread.join(); + //ClientUpdateThread.join(); //receive data - char buffer[4096]; - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - int32_t bytesReceived = int32_t(); - while (!exit) - { - LOG("%s", "server game loop"); - bytesReceived = clientSocket->Receive(buffer, 4096); - - GameObject inObj = GameObject(); - //iStream.Read(inObj); - - al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos + inObj.width, inObj.yPos + inObj.height, al_map_rgb(255, 0, 0), 2); - } - clientSocket->~TCPSocket(); + } From 353c6fa29442a43dc2105dfdbcd3175545b1efbc Mon Sep 17 00:00:00 2001 From: Bradley Date: Tue, 29 Mar 2022 17:19:08 -0400 Subject: [PATCH 12/29] serialization! --- RoboCat/Src/Main.cpp | 357 +++++++++++++++++++++---------------------- 1 file changed, 177 insertions(+), 180 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index e6864ffe..44174106 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -107,11 +107,8 @@ void ThrowSocketError(std::string errorMsg) ExitProcess(1); // kill } - - -void BradsTotallyOriginalServer() +TCPSocketPtr StartServer() { - // listening socket to take in new clients TCPSocketPtr listeningSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); if (listeningSocket == nullptr) @@ -140,11 +137,17 @@ void BradsTotallyOriginalServer() { incomingSocket = listeningSocket->Accept(incomingAddress); } + LOG("Request accepted from: %s", incomingAddress.ToString().c_str()); + + return incomingSocket; +} - // CONECTION ACCEPTED WE HAVE CONTACT ============================== - LOG("Request accepted from: %s", incomingAddress.ToString().c_str()); +void BradsTotallyOriginalServer() +{ - //GAMELOOP + TCPSocketPtr incomingSocket = StartServer(); + + //Greate GameObjects bool exit = false; const int numObjects = 1; @@ -153,8 +156,10 @@ void BradsTotallyOriginalServer() { objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); } + GameObject inObj = GameObject(); + //send data - std::thread SendThread([&incomingSocket, &exit, &objects, &numObjects]() + std::thread ServerSendThread([&incomingSocket, &exit, &objects, &numObjects]() { //send message while (1) @@ -168,17 +173,17 @@ void BradsTotallyOriginalServer() incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } }); - //SendThread.join(); + //ServerSendThread.join(); - GameObject inObj = GameObject(); - thread RecieveThread([&exit, &incomingSocket, &inObj]() - { - char buffer[4096]; - int32_t bytesReceived = int32_t(); // get username - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + thread ServerRecieveThread([&exit, &incomingSocket, &inObj]() + { while (1) { + char buffer[4096]; + int32_t bytesReceived = int32_t(); // get username + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); LOG("%s %s", "server game loop", exit); + bytesReceived = incomingSocket->Receive(buffer, 4096); inObj.Read(iStream); @@ -186,99 +191,90 @@ void BradsTotallyOriginalServer() } incomingSocket->~TCPSocket(); }); - //SendThread.join(); - //UpdateThread.join(); - //RecieveThread.join(); + //ServerRecieveThread.join(); + + ALLEGRO_DISPLAY* display; + display = al_create_display(windowWidth, windowHeight); - std::thread ServerUpdateThread([&objects, &numObjects, &exit, &inObj]() - { - ALLEGRO_DISPLAY* display; - display = al_create_display(windowWidth, windowHeight); + ALLEGRO_KEYBOARD_STATE keyState; + ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); + al_register_event_source(eventQueue, al_get_keyboard_event_source()); - ALLEGRO_KEYBOARD_STATE keyState; - ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); - al_register_event_source(eventQueue, al_get_keyboard_event_source()); + int xAxis = 0; + int yAxis = 0; - int xAxis = 0; - int yAxis = 0; + bool xMove = true; + bool yMove = true; - bool xMove = true; - bool yMove = true; + while (!exit) //GameLoop + { + //Get keyboardInput + ALLEGRO_EVENT events; - while (!exit) //GameLoop + al_get_next_event(eventQueue, &events); + if (events.type == ALLEGRO_EVENT_KEY_UP) + { + switch (events.keyboard.keycode) { - //Get keyboardInput - ALLEGRO_EVENT events; - - al_get_next_event(eventQueue, &events); - if (events.type == ALLEGRO_EVENT_KEY_UP) - { - switch (events.keyboard.keycode) - { - case ALLEGRO_KEY_ESCAPE: - exit = true; - case ALLEGRO_KEY_UP: - yMove = false; - yAxis = 0; - case ALLEGRO_KEY_DOWN: - yMove = false; - yAxis = 0; - case ALLEGRO_KEY_RIGHT: - xAxis = 0; - xMove = false; - case ALLEGRO_KEY_LEFT: - xAxis = 0; - xMove = false; - } - } - if (events.type == ALLEGRO_EVENT_KEY_DOWN) - { - al_get_keyboard_state(&keyState); - if (al_key_down(&keyState, ALLEGRO_KEY_UP)) - { - yMove = true; - yAxis = -1; - } - else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) - { - yMove = true; - yAxis = 1; - } - else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) - { - xAxis = 1; - xMove = true; - } - - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) - { - xAxis = -1; - xMove = true; - } - } + case ALLEGRO_KEY_ESCAPE: + exit = true; + case ALLEGRO_KEY_UP: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_DOWN: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_RIGHT: + xAxis = 0; + xMove = false; + case ALLEGRO_KEY_LEFT: + xAxis = 0; + xMove = false; + } + } + if (events.type == ALLEGRO_EVENT_KEY_DOWN) + { + al_get_keyboard_state(&keyState); + if (al_key_down(&keyState, ALLEGRO_KEY_UP)) + { + yMove = true; + yAxis = -1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + { + yMove = true; + yAxis = 1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + { + xAxis = 1; + xMove = true; + } - for (int i = 0; i < numObjects; i++) - { - if (xMove || yMove) - { - objects[i].UpdatePos(xAxis, yAxis); - } - objects[i].Draw(); - inObj.Draw(); - } - al_flip_display(); - al_clear_to_color(al_map_rgb(0, 0, 0)); + else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + { + xAxis = -1; + xMove = true; } - //al_destroy_display(display); + } - }); - //ServerUpdateThread.join(); - //receive data - + for (int i = 0; i < numObjects; i++) + { + if (xMove || yMove) + { + objects[i].UpdatePos(xAxis, yAxis); + } + objects[i].Draw(); + inObj.Draw(); + } + al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + al_destroy_display(display); } -void BradsLessOriginalClient() +TCPSocketPtr StartClientConnection() { TCPSocketPtr clientSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); if (clientSocket == nullptr) @@ -302,7 +298,14 @@ void BradsLessOriginalClient() if (clientSocket->Connect(*serverAddress) != NO_ERROR) ThrowSocketError("Connecting to server"); - //GameLoop + return clientSocket; +} +void BradsLessOriginalClient() +{ + + TCPSocketPtr clientSocket = StartClientConnection(); + + //create Game Objects bool exit = false; const int numObjects = 1; @@ -311,6 +314,7 @@ void BradsLessOriginalClient() { objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); } + GameObject inObj = GameObject(); std::thread ClientSendThread([&clientSocket, &exit, &objects, &numObjects]() { @@ -329,14 +333,14 @@ void BradsLessOriginalClient() }); //ClientSendThread.join(); - GameObject inObj = GameObject(); thread ClientRecieveThread([&exit, &clientSocket, &numObjects,&inObj]() { - char buffer[4096]; - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - int32_t bytesReceived = int32_t(); + while (1) { + char buffer[4096]; + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + int32_t bytesReceived = int32_t(); LOG("%s", "server game loop"); bytesReceived = clientSocket->Receive(buffer, 4096); @@ -347,95 +351,88 @@ void BradsLessOriginalClient() } clientSocket->~TCPSocket(); }); - //SendThread.join(); - //UpdateThread.join(); //ClientRecieveThread.join(); - - std::thread ClientUpdateThread([&objects, &numObjects, &exit, &inObj]() - { - ALLEGRO_DISPLAY* display; - display = al_create_display(windowWidth, windowHeight); - ALLEGRO_KEYBOARD_STATE keyState; - ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); - al_register_event_source(eventQueue, al_get_keyboard_event_source()); + // Main Game Loop + ALLEGRO_DISPLAY* display; + display = al_create_display(windowWidth, windowHeight); + + ALLEGRO_KEYBOARD_STATE keyState; + ALLEGRO_EVENT_QUEUE* eventQueue = al_create_event_queue(); + al_register_event_source(eventQueue, al_get_keyboard_event_source()); + + int xAxis = 0; + int yAxis = 0; - int xAxis = 0; - int yAxis = 0; + bool xMove = true; + bool yMove = true; - bool xMove = true; - bool yMove = true; + while (!exit) //GameLoop + { + //Get keyboardInput + ALLEGRO_EVENT events; - while (!exit) //GameLoop + al_get_next_event(eventQueue, &events); + if (events.type == ALLEGRO_EVENT_KEY_UP) + { + switch (events.keyboard.keycode) + { + case ALLEGRO_KEY_ESCAPE: + exit = true; + case ALLEGRO_KEY_UP: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_DOWN: + yMove = false; + yAxis = 0; + case ALLEGRO_KEY_RIGHT: + xAxis = 0; + xMove = false; + case ALLEGRO_KEY_LEFT: + xAxis = 0; + xMove = false; + } + } + if (events.type == ALLEGRO_EVENT_KEY_DOWN) + { + al_get_keyboard_state(&keyState); + if (al_key_down(&keyState, ALLEGRO_KEY_UP)) { - //Get keyboardInput - ALLEGRO_EVENT events; + yMove = true; + yAxis = -1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + { + yMove = true; + yAxis = 1; + } + else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + { + xAxis = 1; + xMove = true; + } - al_get_next_event(eventQueue, &events); - if (events.type == ALLEGRO_EVENT_KEY_UP) - { - switch (events.keyboard.keycode) - { - case ALLEGRO_KEY_ESCAPE: - exit = true; - case ALLEGRO_KEY_UP: - yMove = false; - yAxis = 0; - case ALLEGRO_KEY_DOWN: - yMove = false; - yAxis = 0; - case ALLEGRO_KEY_RIGHT: - xAxis = 0; - xMove = false; - case ALLEGRO_KEY_LEFT: - xAxis = 0; - xMove = false; - } - } - if (events.type == ALLEGRO_EVENT_KEY_DOWN) - { - al_get_keyboard_state(&keyState); - if (al_key_down(&keyState, ALLEGRO_KEY_UP)) - { - yMove = true; - yAxis = -1; - } - else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) - { - yMove = true; - yAxis = 1; - } - else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) - { - xAxis = 1; - xMove = true; - } - - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) - { - xAxis = -1; - xMove = true; - } - } + else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + { + xAxis = -1; + xMove = true; + } + } - for (int i = 0; i < numObjects; i++) - { - if (xMove || yMove) - { - objects[i].UpdatePos(xAxis, yAxis); - } - objects[i].Draw(); - inObj.Draw(); - } - al_flip_display(); - al_clear_to_color(al_map_rgb(0, 0, 0)); + for (int i = 0; i < numObjects; i++) + { + if (xMove || yMove) + { + objects[i].UpdatePos(xAxis, yAxis); } - //al_destroy_display(display); - //al_destroy_display(display); - }); - //ClientUpdateThread.join(); + objects[i].Draw(); + inObj.Draw(); + } + al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + al_destroy_display(display); //receive data - } From cb759c17b0e81cbf7f9368c85c7b619e6457a4ab Mon Sep 17 00:00:00 2001 From: bradley Date: Tue, 29 Mar 2022 18:59:32 -0400 Subject: [PATCH 13/29] circles --- RoboCat/Src/Main.cpp | 174 ++++++++++++++++++++++++++----------------- 1 file changed, 107 insertions(+), 67 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 44174106..ce899f0d 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -15,8 +15,64 @@ int windowHeight = 600; int FPS = 30; #if _WIN32 +class CircleClass +{ +public: + CircleClass(int xStart, int yStart, float newRadius); + CircleClass(); + void Read(InputMemoryBitStream& iStream); + void Write(OutputMemoryBitStream& oStream) const; + void Draw(); + void UpdatePos(int xChange, int yChange); -class GameObject + vector position; + float radius; + +}; +void CircleClass::Read(InputMemoryBitStream& iStream) +{ + iStream.Read(position[0]); + iStream.Read(position[1]); + iStream.Read(radius); +} +void CircleClass::Write(OutputMemoryBitStream& oStream) const +{ + oStream.Write(position[0]); + oStream.Write(position[1]); + oStream.Write(radius); +} + +void CircleClass::Draw() +{ + al_draw_circle(position[0], position[1], radius, al_map_rgb(0, 0, 255), 2); +} +CircleClass::CircleClass(int xStart, int yStart, float newRadius) +{ + position.push_back(xStart); + position.push_back(yStart); + radius = newRadius; +} + +CircleClass::CircleClass() +{ + int xTemp = 0; + int yTemp = 0; + position.push_back(xTemp); + position.push_back(yTemp); + radius = 10; +} +void CircleClass::UpdatePos(int xChange, int yChange) +{ + + position[0] += xChange; + position[1] += yChange; + if (position[0] > windowWidth) position[0] = 0; + if (position[1] > windowHeight) position[1] = 0; + if (position[0] < 0) position[0] = windowWidth; + if (position[1] < 0) position[1] = windowHeight; +} + +class RectangleObject { public: int width; @@ -25,23 +81,24 @@ class GameObject int yPos; void Read(InputMemoryBitStream& stream); void Write(OutputMemoryBitStream& stream) const; - GameObject::GameObject(int newWidth, int newHeight, int startPosX, int startPosY); - GameObject::GameObject(); + RectangleObject(int newWidth, int newHeight, int startPosX, int startPosY); + RectangleObject(); void UpdatePos(int xChange, int yChange); void Draw(); + }; -void GameObject::Read(InputMemoryBitStream& stream) +void RectangleObject::Read(InputMemoryBitStream& stream) { stream.Read(width); stream.Read(height); stream.Read(xPos); stream.Read(yPos); - + } -void GameObject::Write(OutputMemoryBitStream& stream) const +void RectangleObject::Write(OutputMemoryBitStream& stream) const { stream.Write(width); stream.Write(height); @@ -49,14 +106,14 @@ void GameObject::Write(OutputMemoryBitStream& stream) const stream.Write(yPos); } -GameObject::GameObject(int newWidth, int newHeight, int startPosX, int startPosY) +RectangleObject::RectangleObject(int newWidth, int newHeight, int startPosX, int startPosY) { width = newWidth; height = newHeight; xPos = startPosX; yPos = startPosY; } -GameObject::GameObject() +RectangleObject::RectangleObject() { width = 10; height = 10; @@ -64,30 +121,9 @@ GameObject::GameObject() yPos = rand() % 100 + 1; } -void GameObject::UpdatePos(int xChange, int yChange) +void RectangleObject::UpdatePos(int xChange, int yChange) { - //Update blockPosition - /* - int xStep = rand() % 2 + 1; - //int xStep = 1; - int yStep = rand() % 2 + 1; - //int yStep = 1; - int randNum = rand() % (2 - 1 + 1) + 1; - if (randNum == 1) - { - xPos += xStep; - yPos += yStep; - } - if (randNum == 2) - { - xPos -= xStep; - yPos -= yStep; - } - if (xPos > windowWidth) xPos = 0; - if (yPos > windowHeight) yPos = 0; - if (xPos < 0) xPos = windowWidth; - if (yPos < 0) yPos = windowHeight; - */ + xPos += xChange; yPos += yChange; if (xPos > windowWidth) xPos = 0; @@ -96,7 +132,7 @@ void GameObject::UpdatePos(int xChange, int yChange) if (yPos < 0) yPos = windowHeight; } -void GameObject::Draw() +void RectangleObject::Draw() { al_draw_rectangle(xPos, yPos, xPos + width, yPos + height, al_map_rgb(255, 0, 0), 2); } @@ -107,6 +143,7 @@ void ThrowSocketError(std::string errorMsg) ExitProcess(1); // kill } + TCPSocketPtr StartServer() { // listening socket to take in new clients @@ -147,19 +184,19 @@ void BradsTotallyOriginalServer() TCPSocketPtr incomingSocket = StartServer(); - //Greate GameObjects + // Game Loop Variables bool exit = false; const int numObjects = 1; - GameObject objects[numObjects]; + //Greate GameObjects + CircleClass outObjects[numObjects]; for (int j = 0; j < numObjects; j++) { - objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); + outObjects[j] = CircleClass(100, 100, 20); } - GameObject inObj = GameObject(); //send data - std::thread ServerSendThread([&incomingSocket, &exit, &objects, &numObjects]() + std::thread ServerSendThread([&incomingSocket, &exit, &outObjects, &numObjects]() { //send message while (1) @@ -168,14 +205,16 @@ void BradsTotallyOriginalServer() for (int i = 0; i < numObjects; i++) { - objects[i].Write(oStream); + outObjects[i].Write(oStream); } + incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } }); //ServerSendThread.join(); - thread ServerRecieveThread([&exit, &incomingSocket, &inObj]() + RectangleObject inObjects[numObjects]; + thread ServerRecieveThread([&exit, &incomingSocket, &inObjects, &numObjects]() { while (1) { @@ -185,9 +224,10 @@ void BradsTotallyOriginalServer() LOG("%s %s", "server game loop", exit); bytesReceived = incomingSocket->Receive(buffer, 4096); - - inObj.Read(iStream); - + for (int i = 0; i < numObjects; i++) + { + inObjects[i].Read(iStream); + } } incomingSocket->~TCPSocket(); }); @@ -258,17 +298,17 @@ void BradsTotallyOriginalServer() } } + al_clear_to_color(al_map_rgb(0, 0, 0)); for (int i = 0; i < numObjects; i++) { if (xMove || yMove) { - objects[i].UpdatePos(xAxis, yAxis); + outObjects[i].UpdatePos(xAxis, yAxis); } - objects[i].Draw(); - inObj.Draw(); + inObjects[i].Draw(); + outObjects[i].Draw(); } al_flip_display(); - al_clear_to_color(al_map_rgb(0, 0, 0)); } al_destroy_display(display); @@ -280,9 +320,6 @@ TCPSocketPtr StartClientConnection() if (clientSocket == nullptr) ThrowSocketError("Could not create client socket"); - //std::string port; - //port = StringUtils::GetCommandLineArg(2); - //std::string address = StringUtils::Sprintf("127.0.0.1:%s", port.c_str()); std::string address = StringUtils::Sprintf("127.0.0.1:8081"); SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); if (clientAddress == nullptr) @@ -305,18 +342,19 @@ void BradsLessOriginalClient() TCPSocketPtr clientSocket = StartClientConnection(); - //create Game Objects + bool exit = false; const int numObjects = 1; - GameObject objects[numObjects]; + //create Game Objects + RectangleObject outRectangles[numObjects]; + //Sleep(1000); for (int j = 0; j < numObjects; j++) { - objects[j] = GameObject(rand() % 100 + 1, rand() % 100 + 1, rand() % windowWidth + 1, rand() % windowHeight + 1); + outRectangles[j] = RectangleObject(20, 20, rand() % windowWidth + 1, rand() % windowHeight + 1); } - GameObject inObj = GameObject(); - std::thread ClientSendThread([&clientSocket, &exit, &objects, &numObjects]() + thread ClientSendThread([&clientSocket, &exit, &outRectangles, &numObjects]() { //send message while (1) @@ -325,7 +363,7 @@ void BradsLessOriginalClient() for (int i = 0; i < numObjects; i++) { - objects[i].Write(oStream); + outRectangles[i].Write(oStream); } clientSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } @@ -333,7 +371,10 @@ void BradsLessOriginalClient() }); //ClientSendThread.join(); - thread ClientRecieveThread([&exit, &clientSocket, &numObjects,&inObj]() + // Read In Objects + CircleClass inObjects[numObjects]; + + thread ClientRecieveThread([&exit, &clientSocket, &inObjects, &numObjects]() { while (1) @@ -341,13 +382,13 @@ void BradsLessOriginalClient() char buffer[4096]; InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); - LOG("%s", "server game loop"); + LOG("%s", "Client game loop"); bytesReceived = clientSocket->Receive(buffer, 4096); - inObj.Read(iStream); - - //al_draw_rectangle(inObj.xPos, inObj.yPos, inObj.xPos + inObj.width, inObj.yPos + inObj.height, al_map_rgb(255, 0, 0), 2); - + for (int i = 0; i < numObjects; i++) + { + inObjects[i].Read(iStream); + } } clientSocket->~TCPSocket(); }); @@ -419,20 +460,19 @@ void BradsLessOriginalClient() } } + al_clear_to_color(al_map_rgb(0, 0, 0)); for (int i = 0; i < numObjects; i++) { if (xMove || yMove) { - objects[i].UpdatePos(xAxis, yAxis); + outRectangles[i].UpdatePos(xAxis, yAxis); } - objects[i].Draw(); - inObj.Draw(); + outRectangles[i].Draw(); + inObjects[i].Draw(); } al_flip_display(); - al_clear_to_color(al_map_rgb(0, 0, 0)); } al_destroy_display(display); - //receive data } @@ -454,7 +494,7 @@ int main(int argc, const char** argv) al_init_primitives_addon(); al_install_keyboard(); - //accept thread + bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' if (isServer) // if it is the server { From 38d9496b70fee585fbdc76d3415b45e3ccdc645d Mon Sep 17 00:00:00 2001 From: Bradley Date: Tue, 29 Mar 2022 22:50:27 -0400 Subject: [PATCH 14/29] Almost there --- RoboCat/Src/Main.cpp | 167 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 153 insertions(+), 14 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index ce899f0d..3b40aeda 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -15,6 +15,92 @@ int windowHeight = 600; int FPS = 30; #if _WIN32 + +class RainParticle +{ +public: + RainParticle(int xStart, int yStart, float newRadius, float newR, float newG, float newB, float newA); + RainParticle(); + void Read(InputMemoryBitStream& iStream); + void Write(OutputMemoryBitStream& oStream) const; + void Draw(); + void UpdatePos(int xChange, int yChange); + + vector color; + vector position; + float radius; + +}; + +RainParticle::RainParticle(int xStart, int yStart, float newRadius, float newR, float newG, float newB, float newA) +{ + color.push_back(newR); + color.push_back(newG); + color.push_back(newB); + color.push_back(newA); + + position.push_back(xStart); + position.push_back(yStart); + + radius = newRadius; +} + +RainParticle::RainParticle() +{ + float tempR, tempG, tempB, tempA; + int tempX, tempY; + color.push_back(tempR); + color.push_back(tempG); + color.push_back(tempB); + color.push_back(tempA); + + position.push_back(tempX); + position.push_back(tempY); + + radius = float(); +} + +void RainParticle::Read(InputMemoryBitStream& iStream) +{ + iStream.Read(color[0]); + iStream.Read(color[1]); + iStream.Read(color[2]); + iStream.Read(color[3]); + + iStream.Read(position[0]); + iStream.Read(position[1]); + + iStream.Read(radius); +} + +void RainParticle::Write(OutputMemoryBitStream& oStream) const +{ + oStream.Write(color[0]); + oStream.Write(color[1]); + oStream.Write(color[2]); + oStream.Write(color[3]); + + oStream.Write(position[0]); + oStream.Write(position[1]); + + oStream.Write(radius); +} + +void RainParticle::Draw() +{ + al_draw_filled_circle(position[0], position[1], radius, al_map_rgba(color[0], color[1], color[2], color[3])); +} + +void RainParticle::UpdatePos(int xChange, int yChange) +{ + position[0] += xChange; + position[1] += yChange; + if (position[0] > windowWidth) position[0] = 0; + if (position[1] > windowHeight) position[1] = 0; + if (position[0] < 0) position[0] = windowWidth; + if (position[1] < 0) position[1] = windowHeight; +} + class CircleClass { public: @@ -44,7 +130,7 @@ void CircleClass::Write(OutputMemoryBitStream& oStream) const void CircleClass::Draw() { - al_draw_circle(position[0], position[1], radius, al_map_rgb(0, 0, 255), 2); + al_draw_filled_circle(position[0], position[1], radius, al_map_rgb(0, 255, 0)); } CircleClass::CircleClass(int xStart, int yStart, float newRadius) { @@ -95,7 +181,6 @@ void RectangleObject::Read(InputMemoryBitStream& stream) stream.Read(height); stream.Read(xPos); stream.Read(yPos); - } void RectangleObject::Write(OutputMemoryBitStream& stream) const @@ -134,7 +219,7 @@ void RectangleObject::UpdatePos(int xChange, int yChange) void RectangleObject::Draw() { - al_draw_rectangle(xPos, yPos, xPos + width, yPos + height, al_map_rgb(255, 0, 0), 2); + al_draw_filled_rectangle(xPos, yPos, xPos + width, yPos + height, al_map_rgb(255, 0, 0)); } void ThrowSocketError(std::string errorMsg) @@ -195,11 +280,18 @@ void BradsTotallyOriginalServer() outObjects[j] = CircleClass(100, 100, 20); } + const int numDroplets = 10; + RainParticle rain[numDroplets]; + for (int k = 0; k < numDroplets; k++) + { + rain[k] = RainParticle(rand() % windowWidth + 1, rand() % windowHeight + 1, rand() % 5 + 5, 0, 0, rand() % 254 + 1, rand() % 254 + 1); + } + //send data - std::thread ServerSendThread([&incomingSocket, &exit, &outObjects, &numObjects]() + std::thread ServerSendThread([&incomingSocket, &exit, &outObjects, &numObjects, &rain, &numDroplets]() { //send message - while (1) + while (!exit) { OutputMemoryBitStream oStream = OutputMemoryBitStream(); @@ -208,6 +300,11 @@ void BradsTotallyOriginalServer() outObjects[i].Write(oStream); } + for (int j = 0; j < numDroplets; j++) + { + rain[j].Write(oStream); + } + //LOG("%s", oStream.GetBitLength()) incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } }); @@ -216,12 +313,12 @@ void BradsTotallyOriginalServer() RectangleObject inObjects[numObjects]; thread ServerRecieveThread([&exit, &incomingSocket, &inObjects, &numObjects]() { - while (1) + while (!exit) { char buffer[4096]; int32_t bytesReceived = int32_t(); // get username InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - LOG("%s %s", "server game loop", exit); + //LOG("%s %s", "server game loop", exit); bytesReceived = incomingSocket->Receive(buffer, 4096); for (int i = 0; i < numObjects; i++) @@ -254,6 +351,30 @@ void BradsTotallyOriginalServer() al_get_next_event(eventQueue, &events); if (events.type == ALLEGRO_EVENT_KEY_UP) { + /* + if (events.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + exit = true; + if (events.keyboard.keycode == ALLEGRO_KEY_UP) + { + yMove = false; + yAxis = 0; + } + if (events.keyboard.keycode == ALLEGRO_KEY_DOWN) + { + yMove = false; + yAxis = 0; + } + if (events.keyboard.keycode == ALLEGRO_KEY_RIGHT) + { + xAxis = 0; + xMove = false; + } + if (events.keyboard.keycode == ALLEGRO_KEY_LEFT) + { + xAxis = 0; + xMove = false; + } + */ switch (events.keyboard.keycode) { case ALLEGRO_KEY_ESCAPE: @@ -271,6 +392,7 @@ void BradsTotallyOriginalServer() xAxis = 0; xMove = false; } + } if (events.type == ALLEGRO_EVENT_KEY_DOWN) { @@ -298,7 +420,6 @@ void BradsTotallyOriginalServer() } } - al_clear_to_color(al_map_rgb(0, 0, 0)); for (int i = 0; i < numObjects; i++) { if (xMove || yMove) @@ -308,7 +429,13 @@ void BradsTotallyOriginalServer() inObjects[i].Draw(); outObjects[i].Draw(); } + for (int j = 0; j < numDroplets; j++) + { + rain[j].UpdatePos(1, 3); + rain[j].Draw(); + } al_flip_display(); + al_clear_to_color(al_map_rgb(0,0,0)); } al_destroy_display(display); @@ -348,7 +475,7 @@ void BradsLessOriginalClient() //create Game Objects RectangleObject outRectangles[numObjects]; - //Sleep(1000); + for (int j = 0; j < numObjects; j++) { outRectangles[j] = RectangleObject(20, 20, rand() % windowWidth + 1, rand() % windowHeight + 1); @@ -357,7 +484,7 @@ void BradsLessOriginalClient() thread ClientSendThread([&clientSocket, &exit, &outRectangles, &numObjects]() { //send message - while (1) + while (!exit) { OutputMemoryBitStream oStream = OutputMemoryBitStream(); @@ -373,22 +500,29 @@ void BradsLessOriginalClient() // Read In Objects CircleClass inObjects[numObjects]; + const int numDroplets = 10; + RainParticle rain[numDroplets]; - thread ClientRecieveThread([&exit, &clientSocket, &inObjects, &numObjects]() + + thread ClientRecieveThread([&exit, &clientSocket, &inObjects, &numObjects, &rain, &numDroplets]() { - while (1) + while (!exit) { char buffer[4096]; InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); - LOG("%s", "Client game loop"); + //LOG("%s", "Client game loop"); bytesReceived = clientSocket->Receive(buffer, 4096); for (int i = 0; i < numObjects; i++) { inObjects[i].Read(iStream); } + for (int j = 0; j < numDroplets; j++) + { + rain[j].Read(iStream); + } } clientSocket->~TCPSocket(); }); @@ -460,7 +594,6 @@ void BradsLessOriginalClient() } } - al_clear_to_color(al_map_rgb(0, 0, 0)); for (int i = 0; i < numObjects; i++) { if (xMove || yMove) @@ -470,9 +603,15 @@ void BradsLessOriginalClient() outRectangles[i].Draw(); inObjects[i].Draw(); } + for (int j = 0; j < numDroplets; j++) + { + rain[j].Draw(); + } al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); } al_destroy_display(display); + } From a58c9e8a6a9d07150eb9887db764155aad8d88e0 Mon Sep 17 00:00:00 2001 From: Bradley Date: Tue, 29 Mar 2022 23:02:48 -0400 Subject: [PATCH 15/29] A simple Networked 'game' --- RoboCat/Src/Main.cpp | 66 ++++++-------------------------------------- 1 file changed, 9 insertions(+), 57 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 3b40aeda..f74fe89b 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -29,7 +29,6 @@ class RainParticle vector color; vector position; float radius; - }; RainParticle::RainParticle(int xStart, int yStart, float newRadius, float newR, float newG, float newB, float newA) @@ -113,14 +112,15 @@ class CircleClass vector position; float radius; - }; + void CircleClass::Read(InputMemoryBitStream& iStream) { iStream.Read(position[0]); iStream.Read(position[1]); iStream.Read(radius); } + void CircleClass::Write(OutputMemoryBitStream& oStream) const { oStream.Write(position[0]); @@ -132,6 +132,7 @@ void CircleClass::Draw() { al_draw_filled_circle(position[0], position[1], radius, al_map_rgb(0, 255, 0)); } + CircleClass::CircleClass(int xStart, int yStart, float newRadius) { position.push_back(xStart); @@ -147,9 +148,9 @@ CircleClass::CircleClass() position.push_back(yTemp); radius = 10; } + void CircleClass::UpdatePos(int xChange, int yChange) { - position[0] += xChange; position[1] += yChange; if (position[0] > windowWidth) position[0] = 0; @@ -174,7 +175,6 @@ class RectangleObject }; - void RectangleObject::Read(InputMemoryBitStream& stream) { stream.Read(width); @@ -208,7 +208,6 @@ RectangleObject::RectangleObject() void RectangleObject::UpdatePos(int xChange, int yChange) { - xPos += xChange; yPos += yChange; if (xPos > windowWidth) xPos = 0; @@ -231,22 +230,18 @@ void ThrowSocketError(std::string errorMsg) TCPSocketPtr StartServer() { - // listening socket to take in new clients TCPSocketPtr listeningSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); if (listeningSocket == nullptr) ThrowSocketError("Could not create socket: NullPtr"); - //create a ptr for the port SocketAddressPtr addressPtr = SocketAddressFactory::CreateIPv4FromString("0.0.0.0:8080"); // a hard-coded port to bind to if (addressPtr == nullptr) ThrowSocketError("Could not create server address"); - // Bind listening socket to an address bool bindError = listeningSocket->Bind(*addressPtr) != NO_ERROR; // bind the socket and check if there is an error if (bindError) ThrowSocketError("Could not bind to address"); - // Listen on listeningSocket bool listenError = listeningSocket->Listen() != NO_ERROR; if (listenError) ThrowSocketError("Listen Error"); @@ -266,7 +261,6 @@ TCPSocketPtr StartServer() void BradsTotallyOriginalServer() { - TCPSocketPtr incomingSocket = StartServer(); // Game Loop Variables @@ -287,10 +281,8 @@ void BradsTotallyOriginalServer() rain[k] = RainParticle(rand() % windowWidth + 1, rand() % windowHeight + 1, rand() % 5 + 5, 0, 0, rand() % 254 + 1, rand() % 254 + 1); } - //send data std::thread ServerSendThread([&incomingSocket, &exit, &outObjects, &numObjects, &rain, &numDroplets]() { - //send message while (!exit) { OutputMemoryBitStream oStream = OutputMemoryBitStream(); @@ -304,11 +296,9 @@ void BradsTotallyOriginalServer() { rain[j].Write(oStream); } - //LOG("%s", oStream.GetBitLength()) incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); } }); - //ServerSendThread.join(); RectangleObject inObjects[numObjects]; thread ServerRecieveThread([&exit, &incomingSocket, &inObjects, &numObjects]() @@ -318,7 +308,6 @@ void BradsTotallyOriginalServer() char buffer[4096]; int32_t bytesReceived = int32_t(); // get username InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - //LOG("%s %s", "server game loop", exit); bytesReceived = incomingSocket->Receive(buffer, 4096); for (int i = 0; i < numObjects; i++) @@ -328,7 +317,6 @@ void BradsTotallyOriginalServer() } incomingSocket->~TCPSocket(); }); - //ServerRecieveThread.join(); ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -345,36 +333,11 @@ void BradsTotallyOriginalServer() while (!exit) //GameLoop { - //Get keyboardInput ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); if (events.type == ALLEGRO_EVENT_KEY_UP) { - /* - if (events.keyboard.keycode == ALLEGRO_KEY_ESCAPE) - exit = true; - if (events.keyboard.keycode == ALLEGRO_KEY_UP) - { - yMove = false; - yAxis = 0; - } - if (events.keyboard.keycode == ALLEGRO_KEY_DOWN) - { - yMove = false; - yAxis = 0; - } - if (events.keyboard.keycode == ALLEGRO_KEY_RIGHT) - { - xAxis = 0; - xMove = false; - } - if (events.keyboard.keycode == ALLEGRO_KEY_LEFT) - { - xAxis = 0; - xMove = false; - } - */ switch (events.keyboard.keycode) { case ALLEGRO_KEY_ESCAPE: @@ -391,8 +354,7 @@ void BradsTotallyOriginalServer() case ALLEGRO_KEY_LEFT: xAxis = 0; xMove = false; - } - + } } if (events.type == ALLEGRO_EVENT_KEY_DOWN) { @@ -412,7 +374,6 @@ void BradsTotallyOriginalServer() xAxis = 1; xMove = true; } - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) { xAxis = -1; @@ -438,7 +399,6 @@ void BradsTotallyOriginalServer() al_clear_to_color(al_map_rgb(0,0,0)); } al_destroy_display(display); - } TCPSocketPtr StartClientConnection() @@ -466,10 +426,8 @@ TCPSocketPtr StartClientConnection() } void BradsLessOriginalClient() { - TCPSocketPtr clientSocket = StartClientConnection(); - bool exit = false; const int numObjects = 1; @@ -483,7 +441,6 @@ void BradsLessOriginalClient() thread ClientSendThread([&clientSocket, &exit, &outRectangles, &numObjects]() { - //send message while (!exit) { OutputMemoryBitStream oStream = OutputMemoryBitStream(); @@ -496,17 +453,14 @@ void BradsLessOriginalClient() } }); - //ClientSendThread.join(); // Read In Objects CircleClass inObjects[numObjects]; const int numDroplets = 10; RainParticle rain[numDroplets]; - thread ClientRecieveThread([&exit, &clientSocket, &inObjects, &numObjects, &rain, &numDroplets]() { - while (!exit) { char buffer[4096]; @@ -526,7 +480,6 @@ void BradsLessOriginalClient() } clientSocket->~TCPSocket(); }); - //ClientRecieveThread.join(); // Main Game Loop ALLEGRO_DISPLAY* display; @@ -544,10 +497,10 @@ void BradsLessOriginalClient() while (!exit) //GameLoop { - //Get keyboardInput ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); + if (events.type == ALLEGRO_EVENT_KEY_UP) { switch (events.keyboard.keycode) @@ -568,6 +521,7 @@ void BradsLessOriginalClient() xMove = false; } } + if (events.type == ALLEGRO_EVENT_KEY_DOWN) { al_get_keyboard_state(&keyState); @@ -611,10 +565,8 @@ void BradsLessOriginalClient() al_clear_to_color(al_map_rgb(0, 0, 0)); } al_destroy_display(display); - } - int main(int argc, const char** argv) { UNREFERENCED_PARAMETER(argc); @@ -628,14 +580,14 @@ int main(int argc, const char** argv) __argv = argv; #endif - SocketUtil::StaticInit(); // socket initialization + SocketUtil::StaticInit(); if (!al_init()) return -1; al_init_primitives_addon(); al_install_keyboard(); bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' - if (isServer) // if it is the server + if (isServer) { BradsTotallyOriginalServer(); } From 6f5a5ecc4f5556080abe94dc67f156221c07825d Mon Sep 17 00:00:00 2001 From: Bradley Date: Tue, 29 Mar 2022 23:08:47 -0400 Subject: [PATCH 16/29] ReadMe --- Assignment2README.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Assignment2README.txt diff --git a/Assignment2README.txt b/Assignment2README.txt new file mode 100644 index 00000000..2b3f4806 --- /dev/null +++ b/Assignment2README.txt @@ -0,0 +1,13 @@ +run the server FIRST via command line: SocketDemo.exe server +run the client via command line: SocketDemo.exe + +press the escape key to end the Allegro Display + +server is a green circle +client is a red square + +movement on both apps is just Up Down Left Right + +the rain is the third object + +it is jittery as hell but whatever, I am proud of it... From 1057a3714494d3e6d38f3695fb32d73c04ae7aa4 Mon Sep 17 00:00:00 2001 From: Scott Barrett Date: Fri, 1 Apr 2022 11:33:45 -0400 Subject: [PATCH 17/29] initial state for assignment 3 --- RoboCat/Chapter3.vcxproj | 9 + RoboCat/Inc/AckRange.h | 35 ++++ RoboCat/Inc/DeliveryNotificationManager.h | 72 +++++++ RoboCat/Inc/InFlightPacket.h | 33 ++++ RoboCat/Inc/RoboCatShared.h | 6 + RoboCat/Inc/Timing.h | 31 +++ RoboCat/Inc/TransmissionData.h | 9 + RoboCat/Src/AckRange.cpp | 33 ++++ RoboCat/Src/DeliveryNotificationManager.cpp | 209 ++++++++++++++++++++ RoboCat/Src/InFlightPacket.cpp | 25 +++ RoboCat/Src/Timing.cpp | 62 ++++++ 11 files changed, 524 insertions(+) create mode 100644 RoboCat/Inc/AckRange.h create mode 100644 RoboCat/Inc/DeliveryNotificationManager.h create mode 100644 RoboCat/Inc/InFlightPacket.h create mode 100644 RoboCat/Inc/Timing.h create mode 100644 RoboCat/Inc/TransmissionData.h create mode 100644 RoboCat/Src/AckRange.cpp create mode 100644 RoboCat/Src/DeliveryNotificationManager.cpp create mode 100644 RoboCat/Src/InFlightPacket.cpp create mode 100644 RoboCat/Src/Timing.cpp diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index c2d193be..8c859a81 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -370,7 +370,10 @@ + + + @@ -382,7 +385,12 @@ + + + + + @@ -397,6 +405,7 @@ Create RoboCatPCH.h + diff --git a/RoboCat/Inc/AckRange.h b/RoboCat/Inc/AckRange.h new file mode 100644 index 00000000..004d14c9 --- /dev/null +++ b/RoboCat/Inc/AckRange.h @@ -0,0 +1,35 @@ +//typedef PacketSequenceNumber uint16_t; + +class AckRange +{ +public: + AckRange() : mStart( 0 ), mCount( 0 ) {} + + AckRange( PacketSequenceNumber inStart ) : mStart( inStart ), mCount( 1 ) {} + + //if this is the next in sequence, just extend the range + inline bool ExtendIfShould( PacketSequenceNumber inSequenceNumber ); + + PacketSequenceNumber GetStart() const { return mStart; } + uint32_t GetCount() const { return mCount; } + + void Write( OutputMemoryBitStream& inOutputStream ) const; + void Read( InputMemoryBitStream& inInputStream ); + +private: + PacketSequenceNumber mStart; + uint32_t mCount; +}; + +inline bool AckRange::ExtendIfShould( PacketSequenceNumber inSequenceNumber ) +{ + if( inSequenceNumber == mStart + mCount ) + { + ++mCount; + return true; + } + else + { + return false; + } +} \ No newline at end of file diff --git a/RoboCat/Inc/DeliveryNotificationManager.h b/RoboCat/Inc/DeliveryNotificationManager.h new file mode 100644 index 00000000..b6a795a4 --- /dev/null +++ b/RoboCat/Inc/DeliveryNotificationManager.h @@ -0,0 +1,72 @@ + +class DeliveryNotificationManager +{ +public: + + + DeliveryNotificationManager( bool inShouldSendAcks, bool inShouldProcessAcks ); + ~DeliveryNotificationManager(); + + inline InFlightPacket* WriteState( OutputMemoryBitStream& inOutputStream ); + inline bool ReadAndProcessState( InputMemoryBitStream& inInputStream ); + + void ProcessTimedOutPackets(); + + uint32_t GetDroppedPacketCount() const { return mDroppedPacketCount; } + uint32_t GetDeliveredPacketCount() const { return mDeliveredPacketCount; } + uint32_t GetDispatchedPacketCount() const { return mDispatchedPacketCount; } + + const deque< InFlightPacket >& GetInFlightPackets() const { return mInFlightPackets; } + +private: + + + + InFlightPacket* WriteSequenceNumber( OutputMemoryBitStream& inOutputStream ); + void WriteAckData( OutputMemoryBitStream& inOutputStream ); + + //returns wether to drop the packet- if sequence number is too low! + bool ProcessSequenceNumber( InputMemoryBitStream& inInputStream ); + void ProcessAcks( InputMemoryBitStream& inInputStream ); + + + void AddPendingAck( PacketSequenceNumber inSequenceNumber ); + void HandlePacketDeliveryFailure( const InFlightPacket& inFlightPacket ); + void HandlePacketDeliverySuccess( const InFlightPacket& inFlightPacket ); + + PacketSequenceNumber mNextOutgoingSequenceNumber; + PacketSequenceNumber mNextExpectedSequenceNumber; + + deque< InFlightPacket > mInFlightPackets; + deque< AckRange > mPendingAcks; + + bool mShouldSendAcks; + bool mShouldProcessAcks; + + uint32_t mDeliveredPacketCount; + uint32_t mDroppedPacketCount; + uint32_t mDispatchedPacketCount; + +}; + + + +inline InFlightPacket* DeliveryNotificationManager::WriteState( OutputMemoryBitStream& inOutputStream ) +{ + InFlightPacket* toRet = WriteSequenceNumber( inOutputStream ); + if( mShouldSendAcks ) + { + WriteAckData( inOutputStream ); + } + return toRet; +} + +inline bool DeliveryNotificationManager::ReadAndProcessState( InputMemoryBitStream& inInputStream ) +{ + bool toRet = ProcessSequenceNumber( inInputStream ); + if( mShouldProcessAcks ) + { + ProcessAcks( inInputStream ); + } + return toRet; +} \ No newline at end of file diff --git a/RoboCat/Inc/InFlightPacket.h b/RoboCat/Inc/InFlightPacket.h new file mode 100644 index 00000000..494e097e --- /dev/null +++ b/RoboCat/Inc/InFlightPacket.h @@ -0,0 +1,33 @@ +class DeliveryNotificationManager; + +//in case we decide to change the type of the sequence number to use fewer or more bits +typedef uint16_t PacketSequenceNumber; + +class InFlightPacket +{ +public: + + InFlightPacket( PacketSequenceNumber inSequenceNumber ); + + PacketSequenceNumber GetSequenceNumber() const { return mSequenceNumber; } + float GetTimeDispatched() const { return mTimeDispatched; } + + void SetTransmissionData( int inKey, TransmissionDataPtr inTransmissionData ) + { + mTransmissionDataMap[ inKey ] = inTransmissionData; + } + const TransmissionDataPtr GetTransmissionData( int inKey ) const + { + auto it = mTransmissionDataMap.find( inKey ); + return ( it != mTransmissionDataMap.end() ) ? it->second : nullptr; + } + + void HandleDeliveryFailure( DeliveryNotificationManager* inDeliveryNotificationManager ) const; + void HandleDeliverySuccess( DeliveryNotificationManager* inDeliveryNotificationManager ) const; + +private: + PacketSequenceNumber mSequenceNumber; + float mTimeDispatched; + + unordered_map< int, TransmissionDataPtr > mTransmissionDataMap; +}; \ No newline at end of file diff --git a/RoboCat/Inc/RoboCatShared.h b/RoboCat/Inc/RoboCatShared.h index bc232e1f..d7eac1bc 100644 --- a/RoboCat/Inc/RoboCatShared.h +++ b/RoboCat/Inc/RoboCatShared.h @@ -51,10 +51,15 @@ class GameObject; #include "RoboMath.h" +#include "TransmissionData.h" +#include "InFlightPacket.h" + #include "LinkingContext.h" #include "ByteSwap.h" #include "MemoryBitStream.h" +#include "AckRange.h" +#include "Timing.h" #include "StringUtils.h" #include "SocketAddress.h" #include "SocketAddressFactory.h" @@ -62,3 +67,4 @@ class GameObject; #include "TCPSocket.h" #include "SocketUtil.h" #include "OutputWindow.h" +#include "DeliveryNotificationManager.h" diff --git a/RoboCat/Inc/Timing.h b/RoboCat/Inc/Timing.h new file mode 100644 index 00000000..b5af28d8 --- /dev/null +++ b/RoboCat/Inc/Timing.h @@ -0,0 +1,31 @@ +class Timing +{ +public: + + Timing(); + + void Update(); + + float GetDeltaTime() const { return mDeltaTime; } + + double GetTime() const; + + float GetTimef() const + { + return static_cast< float >( GetTime() ); + } + + float GetFrameStartTime() const { return mFrameStartTimef; } + + + static Timing sInstance; + +private: + float mDeltaTime; + uint64_t mDeltaTick; + + double mLastFrameStartTime; + float mFrameStartTimef; + double mPerfCountDuration; + +}; \ No newline at end of file diff --git a/RoboCat/Inc/TransmissionData.h b/RoboCat/Inc/TransmissionData.h new file mode 100644 index 00000000..cc599ec0 --- /dev/null +++ b/RoboCat/Inc/TransmissionData.h @@ -0,0 +1,9 @@ +class DeliveryNotificationManager; + +class TransmissionData +{ +public: + virtual void HandleDeliveryFailure( DeliveryNotificationManager* inDeliveryNotificationManager ) const = 0; + virtual void HandleDeliverySuccess( DeliveryNotificationManager* inDeliveryNotificationManager ) const = 0; +}; +typedef shared_ptr< TransmissionData > TransmissionDataPtr; \ No newline at end of file diff --git a/RoboCat/Src/AckRange.cpp b/RoboCat/Src/AckRange.cpp new file mode 100644 index 00000000..99bed803 --- /dev/null +++ b/RoboCat/Src/AckRange.cpp @@ -0,0 +1,33 @@ +#include "RoboCatPCH.h" + +void AckRange::Write( OutputMemoryBitStream& inOutputStream ) const +{ + inOutputStream.Write( mStart ); + bool hasCount = mCount > 1; + inOutputStream.Write( hasCount ); + if( hasCount ) + { + //most you can ack is 255... + uint32_t countMinusOne = mCount - 1; + uint8_t countToAck = countMinusOne > 255 ? 255 : static_cast< uint8_t >( countMinusOne ); + inOutputStream.Write( countToAck ); + } +} + +void AckRange::Read( InputMemoryBitStream& inInputStream ) +{ + inInputStream.Read( mStart ); + bool hasCount; + inInputStream.Read( hasCount ); + if( hasCount ) + { + uint8_t countMinusOne; + inInputStream.Read( countMinusOne ); + mCount = countMinusOne + 1; + } + else + { + //default! + mCount = 1; + } +} \ No newline at end of file diff --git a/RoboCat/Src/DeliveryNotificationManager.cpp b/RoboCat/Src/DeliveryNotificationManager.cpp new file mode 100644 index 00000000..ea85baa9 --- /dev/null +++ b/RoboCat/Src/DeliveryNotificationManager.cpp @@ -0,0 +1,209 @@ +#include "RoboCatPCH.h" + +namespace +{ + const float kDelayBeforeAckTimeout = 0.5f; +} + +DeliveryNotificationManager::DeliveryNotificationManager( bool inShouldSendAcks, bool inShouldProcessAcks ) : +mNextOutgoingSequenceNumber( 0 ), +mNextExpectedSequenceNumber( 0 ), +//everybody starts at 0... +mShouldSendAcks( inShouldSendAcks ), +mShouldProcessAcks( inShouldProcessAcks ), +mDeliveredPacketCount( 0 ), +mDroppedPacketCount( 0 ), +mDispatchedPacketCount( 0 ) +{ +} + + +//we're going away- log how well we did... +DeliveryNotificationManager::~DeliveryNotificationManager() +{ + LOG( "DNM destructor. Delivery rate %d%%, Drop rate %d%%", + ( 100 * mDeliveredPacketCount ) / mDispatchedPacketCount, + ( 100 * mDroppedPacketCount ) / mDispatchedPacketCount ); +} + + + +InFlightPacket* DeliveryNotificationManager::WriteSequenceNumber( OutputMemoryBitStream& inOutputStream ) +{ + //write the sequence number, but also create an inflight packet for this... + PacketSequenceNumber sequenceNumber = mNextOutgoingSequenceNumber++; + inOutputStream.Write( sequenceNumber ); + + ++mDispatchedPacketCount; + + if( mShouldProcessAcks ) + { + mInFlightPackets.emplace_back( sequenceNumber ); + + return &mInFlightPackets.back(); + } + else + { + return nullptr; + } +} + +void DeliveryNotificationManager::WriteAckData( OutputMemoryBitStream& inOutputStream ) +{ + //we usually will only have one packet to ack + //so we'll follow that with a 0 bit if that's the case + //however, if we have more than 1, we'll make that 1 bit a 1 and then write 8 bits of how many packets + //we could do some statistical analysis to determine if this is the best strategy but we'll use it for now + + //do we have any pending acks? + //if so, write a 1 bit and write the first range + //otherwise, write 0 bit + bool hasAcks = ( mPendingAcks.size() > 0 ); + + inOutputStream.Write( hasAcks ); + if( hasAcks ) + { + //note, we could write all the acks + mPendingAcks.front().Write( inOutputStream ); + mPendingAcks.pop_front(); + } +} + + + +//returns wether to drop the packet- if sequence number is too low! +bool DeliveryNotificationManager::ProcessSequenceNumber( InputMemoryBitStream& inInputStream ) +{ + PacketSequenceNumber sequenceNumber; + + inInputStream.Read( sequenceNumber ); + if( sequenceNumber == mNextExpectedSequenceNumber ) + { + mNextExpectedSequenceNumber = sequenceNumber + 1; + //is this what we expect? great, let's add an ack to our pending list + if( mShouldSendAcks ) + { + AddPendingAck( sequenceNumber ); + } + //and let's continue processing this packet... + return true; + } + //is the sequence number less than our current expected sequence? silently drop it. + //if this is due to wrapping around, we might fail to ack some packets that we should ack, but they'll get resent, so it's not a big deal + //note that we don't have to re-ack it because our system doesn't reuse sequence numbers + else if( sequenceNumber < mNextExpectedSequenceNumber ) + { + return false; + } + else if( sequenceNumber > mNextExpectedSequenceNumber ) + { + //we missed a lot of packets! + //so our next expected packet comes after this one... + mNextExpectedSequenceNumber = sequenceNumber + 1; + //we should nack the missing packets..this will happen automatically inside AddPendingAck because + //we're adding an unconsequitive ack + //and then we can ack this and process it + if( mShouldSendAcks ) + { + AddPendingAck( sequenceNumber ); + } + return true; + } + + //drop packet if we couldn't even read sequence number! + return false; +} + + +//in each packet we can ack a range +//anything in flight before the range will be considered nackd by the other side immediately +void DeliveryNotificationManager::ProcessAcks( InputMemoryBitStream& inInputStream ) +{ + + bool hasAcks; + inInputStream.Read( hasAcks ); + if( hasAcks ) + { + AckRange ackRange; + ackRange.Read( inInputStream ); + + //for each InfilghtPacket with a sequence number less than the start, handle delivery failure... + PacketSequenceNumber nextAckdSequenceNumber = ackRange.GetStart(); + uint32_t onePastAckdSequenceNumber = nextAckdSequenceNumber + ackRange.GetCount(); + while( nextAckdSequenceNumber < onePastAckdSequenceNumber && !mInFlightPackets.empty() ) + { + const auto& nextInFlightPacket = mInFlightPackets.front(); + //if the packet has a lower sequence number, we didn't get an ack for it, so it probably wasn't delivered + PacketSequenceNumber nextInFlightPacketSequenceNumber = nextInFlightPacket.GetSequenceNumber(); + if( nextInFlightPacketSequenceNumber < nextAckdSequenceNumber ) + { + //copy this so we can remove it before handling the failure- we don't want to find it when checking for state + auto copyOfInFlightPacket = nextInFlightPacket; + mInFlightPackets.pop_front(); + HandlePacketDeliveryFailure( copyOfInFlightPacket ); + } + else if( nextInFlightPacketSequenceNumber == nextAckdSequenceNumber ) + { + HandlePacketDeliverySuccess( nextInFlightPacket ); + //received! + mInFlightPackets.pop_front(); + //decrement count, advance nextAckdSequenceNumber + ++nextAckdSequenceNumber; + } + else if( nextInFlightPacketSequenceNumber > nextAckdSequenceNumber ) + { + //we've already ackd some packets in here. + //keep this packet in flight, but keep going through the ack... + ++nextAckdSequenceNumber; + } + } + } +} + +void DeliveryNotificationManager::ProcessTimedOutPackets() +{ + float timeoutTime = Timing::sInstance.GetTimef() - kDelayBeforeAckTimeout; + + while( !mInFlightPackets.empty() ) + { + const auto& nextInFlightPacket = mInFlightPackets.front(); + + //was this packet dispatched before the current time minus the timeout duration? + if( nextInFlightPacket.GetTimeDispatched() < timeoutTime ) + { + //it failed! let us know about that + HandlePacketDeliveryFailure( nextInFlightPacket ); + mInFlightPackets.pop_front(); + } + else + { + //it wasn't, and packets are all in order by time here, so we know we don't have to check farther + break; + } + } +} + +void DeliveryNotificationManager::AddPendingAck( PacketSequenceNumber inSequenceNumber ) +{ + //if you don't have a range yet, or you can't correctly extend the final range with the sequence number, + //start a new range + if( mPendingAcks.size() == 0 || !mPendingAcks.back().ExtendIfShould( inSequenceNumber ) ) + { + mPendingAcks.emplace_back( inSequenceNumber ); + } +} + + +void DeliveryNotificationManager::HandlePacketDeliveryFailure( const InFlightPacket& inFlightPacket ) +{ + ++mDroppedPacketCount; + inFlightPacket.HandleDeliveryFailure( this ); + +} + + +void DeliveryNotificationManager::HandlePacketDeliverySuccess( const InFlightPacket& inFlightPacket ) +{ + ++mDeliveredPacketCount; + inFlightPacket.HandleDeliverySuccess( this ); +} diff --git a/RoboCat/Src/InFlightPacket.cpp b/RoboCat/Src/InFlightPacket.cpp new file mode 100644 index 00000000..251abe36 --- /dev/null +++ b/RoboCat/Src/InFlightPacket.cpp @@ -0,0 +1,25 @@ +#include "RoboCatPCH.h" + +InFlightPacket::InFlightPacket( PacketSequenceNumber inSequenceNumber ) : +mSequenceNumber( inSequenceNumber ), +mTimeDispatched( Timing::sInstance.GetTimef() ) +{ + //null out other transmision data params... +} + + +void InFlightPacket::HandleDeliveryFailure( DeliveryNotificationManager* inDeliveryNotificationManager ) const +{ + for( const auto& pair : mTransmissionDataMap ) + { + pair.second->HandleDeliveryFailure( inDeliveryNotificationManager ); + } +} + +void InFlightPacket::HandleDeliverySuccess( DeliveryNotificationManager* inDeliveryNotificationManager ) const +{ + for( const auto& pair : mTransmissionDataMap ) + { + pair.second->HandleDeliverySuccess( inDeliveryNotificationManager ); + } +} \ No newline at end of file diff --git a/RoboCat/Src/Timing.cpp b/RoboCat/Src/Timing.cpp new file mode 100644 index 00000000..9a8be86c --- /dev/null +++ b/RoboCat/Src/Timing.cpp @@ -0,0 +1,62 @@ +#include "RoboCatPCH.h" + + +#if !_WIN32 + #include + using namespace std::chrono; +#endif + +Timing Timing::sInstance; + +namespace +{ +#if _WIN32 + LARGE_INTEGER sStartTime = { 0 }; +#else + high_resolution_clock::time_point sStartTime; +#endif +} + +Timing::Timing() +{ +#if _WIN32 + LARGE_INTEGER perfFreq; + QueryPerformanceFrequency( &perfFreq ); + mPerfCountDuration = 1.0 / perfFreq.QuadPart; + + QueryPerformanceCounter( &sStartTime ); + + mLastFrameStartTime = GetTime(); +#else + sStartTime = high_resolution_clock::now(); +#endif +} + +void Timing::Update() +{ + + double currentTime = GetTime(); + + mDeltaTime = ( float ) ( currentTime - mLastFrameStartTime ); + + mLastFrameStartTime = currentTime; + mFrameStartTimef = static_cast< float > ( mLastFrameStartTime ); + +} + +double Timing::GetTime() const +{ +#if _WIN32 + LARGE_INTEGER curTime, timeSinceStart; + QueryPerformanceCounter( &curTime ); + + timeSinceStart.QuadPart = curTime.QuadPart - sStartTime.QuadPart; + + return timeSinceStart.QuadPart * mPerfCountDuration; +#else + auto now = high_resolution_clock::now(); + auto ms = duration_cast< milliseconds >( now - sStartTime ).count(); + //a little uncool to then convert into a double just to go back, but oh well. + return static_cast< double >( ms ) / 1000; +#endif +} \ No newline at end of file From 768778b2d062f0f9c101f8ec79effe4d324fdcb2 Mon Sep 17 00:00:00 2001 From: Bradley Chamberlain Date: Fri, 1 Apr 2022 14:07:28 -0400 Subject: [PATCH 18/29] created more stability --- RoboCat/Src/Main.cpp | 159 ++++++++++++++++++-------------------- RoboCat/Src/TCPSocket.cpp | 8 +- 2 files changed, 81 insertions(+), 86 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index f74fe89b..5b41ade5 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -19,19 +19,19 @@ int FPS = 30; class RainParticle { public: - RainParticle(int xStart, int yStart, float newRadius, float newR, float newG, float newB, float newA); + RainParticle(float xStart, float yStart, float newRadius, float newR, float newG, float newB, float newA); RainParticle(); void Read(InputMemoryBitStream& iStream); void Write(OutputMemoryBitStream& oStream) const; void Draw(); - void UpdatePos(int xChange, int yChange); + void UpdatePos(float xChange, float yChange); vector color; - vector position; + vector position; float radius; }; -RainParticle::RainParticle(int xStart, int yStart, float newRadius, float newR, float newG, float newB, float newA) +RainParticle::RainParticle(float xStart, float yStart, float newRadius, float newR, float newG, float newB, float newA) { color.push_back(newR); color.push_back(newG); @@ -46,8 +46,8 @@ RainParticle::RainParticle(int xStart, int yStart, float newRadius, float newR, RainParticle::RainParticle() { - float tempR, tempG, tempB, tempA; - int tempX, tempY; + float tempR, tempG, tempB, tempA, tempX, tempY; + color.push_back(tempR); color.push_back(tempG); color.push_back(tempB); @@ -90,7 +90,7 @@ void RainParticle::Draw() al_draw_filled_circle(position[0], position[1], radius, al_map_rgba(color[0], color[1], color[2], color[3])); } -void RainParticle::UpdatePos(int xChange, int yChange) +void RainParticle::UpdatePos(float xChange, float yChange) { position[0] += xChange; position[1] += yChange; @@ -262,16 +262,17 @@ TCPSocketPtr StartServer() void BradsTotallyOriginalServer() { TCPSocketPtr incomingSocket = StartServer(); + incomingSocket->SetNonBlockingMode(true); // Game Loop Variables bool exit = false; const int numObjects = 1; //Greate GameObjects - CircleClass outObjects[numObjects]; + CircleClass greenCircle[numObjects]; for (int j = 0; j < numObjects; j++) { - outObjects[j] = CircleClass(100, 100, 20); + greenCircle[j] = CircleClass(100, 100, 20); } const int numDroplets = 10; @@ -281,42 +282,7 @@ void BradsTotallyOriginalServer() rain[k] = RainParticle(rand() % windowWidth + 1, rand() % windowHeight + 1, rand() % 5 + 5, 0, 0, rand() % 254 + 1, rand() % 254 + 1); } - std::thread ServerSendThread([&incomingSocket, &exit, &outObjects, &numObjects, &rain, &numDroplets]() - { - while (!exit) - { - OutputMemoryBitStream oStream = OutputMemoryBitStream(); - - for (int i = 0; i < numObjects; i++) - { - outObjects[i].Write(oStream); - } - - for (int j = 0; j < numDroplets; j++) - { - rain[j].Write(oStream); - } - incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); - } - }); - RectangleObject inObjects[numObjects]; - thread ServerRecieveThread([&exit, &incomingSocket, &inObjects, &numObjects]() - { - while (!exit) - { - char buffer[4096]; - int32_t bytesReceived = int32_t(); // get username - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - - bytesReceived = incomingSocket->Receive(buffer, 4096); - for (int i = 0; i < numObjects; i++) - { - inObjects[i].Read(iStream); - } - } - incomingSocket->~TCPSocket(); - }); ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -333,6 +299,37 @@ void BradsTotallyOriginalServer() while (!exit) //GameLoop { + + //send Data + OutputMemoryBitStream oStream = OutputMemoryBitStream(); + + for (int i = 0; i < numObjects; i++) + { + greenCircle[i].Write(oStream); + } + + for (int j = 0; j < numDroplets; j++) + { + rain[j].Write(oStream); + } + incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); + + //recieve Data + char buffer[4096]; + int32_t bytesReceived = int32_t(); // get username + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + + bytesReceived = incomingSocket->Receive(buffer, 4096); + if (bytesReceived != -10035) + { + for (int i = 0; i < numObjects; i++) + { + inObjects[i].Read(iStream); + } + } + + + ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); @@ -385,14 +382,14 @@ void BradsTotallyOriginalServer() { if (xMove || yMove) { - outObjects[i].UpdatePos(xAxis, yAxis); + greenCircle[i].UpdatePos(xAxis, yAxis); } inObjects[i].Draw(); - outObjects[i].Draw(); + greenCircle[i].Draw(); } for (int j = 0; j < numDroplets; j++) { - rain[j].UpdatePos(1, 3); + rain[j].UpdatePos(0.1, 0.3); rain[j].Draw(); } al_flip_display(); @@ -427,6 +424,7 @@ TCPSocketPtr StartClientConnection() void BradsLessOriginalClient() { TCPSocketPtr clientSocket = StartClientConnection(); + clientSocket->SetNonBlockingMode(true); bool exit = false; const int numObjects = 1; @@ -439,48 +437,12 @@ void BradsLessOriginalClient() outRectangles[j] = RectangleObject(20, 20, rand() % windowWidth + 1, rand() % windowHeight + 1); } - thread ClientSendThread([&clientSocket, &exit, &outRectangles, &numObjects]() - { - while (!exit) - { - OutputMemoryBitStream oStream = OutputMemoryBitStream(); - - for (int i = 0; i < numObjects; i++) - { - outRectangles[i].Write(oStream); - } - clientSocket->Send(oStream.GetBufferPtr(), oStream.GetBitLength()); - } - - }); - // Read In Objects CircleClass inObjects[numObjects]; + const int numDroplets = 10; RainParticle rain[numDroplets]; - thread ClientRecieveThread([&exit, &clientSocket, &inObjects, &numObjects, &rain, &numDroplets]() - { - while (!exit) - { - char buffer[4096]; - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); - int32_t bytesReceived = int32_t(); - //LOG("%s", "Client game loop"); - bytesReceived = clientSocket->Receive(buffer, 4096); - - for (int i = 0; i < numObjects; i++) - { - inObjects[i].Read(iStream); - } - for (int j = 0; j < numDroplets; j++) - { - rain[j].Read(iStream); - } - } - clientSocket->~TCPSocket(); - }); - // Main Game Loop ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -497,6 +459,35 @@ void BradsLessOriginalClient() while (!exit) //GameLoop { + // Recieve data + char buffer[4096]; + InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + int32_t bytesReceived = int32_t(); + //LOG("%s", "Client game loop"); + bytesReceived = clientSocket->Receive(buffer, 4096); + if (bytesReceived != -10035) + { + for (int i = 0; i < numObjects; i++) + { + inObjects[i].Read(iStream); + } + for (int j = 0; j < numDroplets; j++) + { + rain[j].Read(iStream); + } + } + + + //send Data + OutputMemoryBitStream oStream = OutputMemoryBitStream(); + + for (int i = 0; i < numObjects; i++) + { + outRectangles[i].Write(oStream); + } + clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); + + ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); diff --git a/RoboCat/Src/TCPSocket.cpp b/RoboCat/Src/TCPSocket.cpp index 494f776c..0cfe2b20 100644 --- a/RoboCat/Src/TCPSocket.cpp +++ b/RoboCat/Src/TCPSocket.cpp @@ -55,8 +55,12 @@ int32_t TCPSocket::Receive( void* inData, size_t inLen ) int bytesReceivedCount = recv( mSocket, static_cast< char* >( inData ), inLen, 0 ); if( bytesReceivedCount < 0 ) { - SocketUtil::ReportError( "TCPSocket::Receive" ); - return -SocketUtil::GetLastError(); + int error = -SocketUtil::GetLastError(); + if (error != -10035) + { + SocketUtil::ReportError("TCPSocket::Receive"); + } + return error; } return bytesReceivedCount; } From 2d6aed6e80d72a89d92836732e78cece4109e0e8 Mon Sep 17 00:00:00 2001 From: Bradley Chamberlain Date: Tue, 5 Apr 2022 14:19:23 -0400 Subject: [PATCH 19/29] Timers Baby! --- RoboCat/Src/Main.cpp | 81 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 5b41ade5..577cbfa5 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -12,7 +12,7 @@ using namespace std; int windowWidth = 800; int windowHeight = 600; -int FPS = 30; +int FRAMERATE = 16; #if _WIN32 @@ -227,6 +227,16 @@ void ThrowSocketError(std::string errorMsg) ExitProcess(1); // kill } +ALLEGRO_TIMER* GiveMeATimer(float incr) +{ + ALLEGRO_TIMER* timer = al_create_timer(incr); + if (timer == nullptr) + { + ERROR; + } + al_start_timer(timer); + return timer; +} TCPSocketPtr StartServer() { @@ -264,6 +274,12 @@ void BradsTotallyOriginalServer() TCPSocketPtr incomingSocket = StartServer(); incomingSocket->SetNonBlockingMode(true); + //Timer + ALLEGRO_TIMER* timer = GiveMeATimer(0.001); + int currentTime = al_get_timer_count(timer); + int lastTime = 0; + float deltaTime = 0; + // Game Loop Variables bool exit = false; const int numObjects = 1; @@ -300,6 +316,11 @@ void BradsTotallyOriginalServer() while (!exit) //GameLoop { + //Timer + currentTime = al_get_timer_count(timer); + deltaTime = currentTime - lastTime; + lastTime = currentTime; + //send Data OutputMemoryBitStream oStream = OutputMemoryBitStream(); @@ -328,8 +349,6 @@ void BradsTotallyOriginalServer() } } - - ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); @@ -394,8 +413,17 @@ void BradsTotallyOriginalServer() } al_flip_display(); al_clear_to_color(al_map_rgb(0,0,0)); + + //wait for the frame to end + int currentPeriod = al_get_timer_count(timer) - currentTime; + while (currentPeriod < FRAMERATE) + { + currentPeriod = al_get_timer_count(timer) - currentTime; + } + if (currentTime < 5000) + al_set_timer_count(timer, 0); } - al_destroy_display(display); + al_destroy_display(display); } TCPSocketPtr StartClientConnection() @@ -426,6 +454,12 @@ void BradsLessOriginalClient() TCPSocketPtr clientSocket = StartClientConnection(); clientSocket->SetNonBlockingMode(true); + //timer + ALLEGRO_TIMER* timer = GiveMeATimer(0.001); + int currentTime = al_get_timer_count(timer); + int lastTime = 0; + float deltaTime = 0; + bool exit = false; const int numObjects = 1; @@ -459,6 +493,20 @@ void BradsLessOriginalClient() while (!exit) //GameLoop { + //Timer + currentTime = al_get_timer_count(timer); + deltaTime = currentTime - lastTime; + lastTime = currentTime; + + //send Data + OutputMemoryBitStream oStream = OutputMemoryBitStream(); + + for (int i = 0; i < numObjects; i++) + { + outRectangles[i].Write(oStream); + } + clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); + // Recieve data char buffer[4096]; InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); @@ -475,18 +523,7 @@ void BradsLessOriginalClient() { rain[j].Read(iStream); } - } - - - //send Data - OutputMemoryBitStream oStream = OutputMemoryBitStream(); - - for (int i = 0; i < numObjects; i++) - { - outRectangles[i].Write(oStream); - } - clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); - + } ALLEGRO_EVENT events; @@ -554,8 +591,19 @@ void BradsLessOriginalClient() } al_flip_display(); al_clear_to_color(al_map_rgb(0, 0, 0)); + + //wait for the frame to end + int currentPeriod = al_get_timer_count(timer) - currentTime; + while (currentPeriod < FRAMERATE) + { + currentPeriod = al_get_timer_count(timer) - currentTime; + } + if (currentTime < 5000) + al_set_timer_count(timer, 0); } al_destroy_display(display); + + } int main(int argc, const char** argv) @@ -575,6 +623,7 @@ int main(int argc, const char** argv) if (!al_init()) return -1; al_init_primitives_addon(); + al_install_keyboard(); bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' From 2852e619119b492de95af272ec65f0ec442b0e99 Mon Sep 17 00:00:00 2001 From: bradley Date: Sun, 10 Apr 2022 18:47:37 -0400 Subject: [PATCH 20/29] da --- RoboCat/Src/Main.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 577cbfa5..e6ac779d 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include using namespace std; int windowWidth = 800; @@ -238,6 +239,21 @@ ALLEGRO_TIMER* GiveMeATimer(float incr) return timer; } +//class ClientInPacket +//{ +//public: +// ClientPacket(); +// //~ClientPacket(); +// CircleClass inCircle; +// RainParticle inRain[10]; +//}; +// +//ClientPacket::ClientPacket() +//{ +// +//} + + TCPSocketPtr StartServer() { TCPSocketPtr listeningSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); @@ -299,7 +315,7 @@ void BradsTotallyOriginalServer() } RectangleObject inObjects[numObjects]; - + ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -315,7 +331,6 @@ void BradsTotallyOriginalServer() while (!exit) //GameLoop { - //Timer currentTime = al_get_timer_count(timer); deltaTime = currentTime - lastTime; @@ -523,6 +538,7 @@ void BradsLessOriginalClient() { rain[j].Read(iStream); } + } ALLEGRO_EVENT events; @@ -568,7 +584,6 @@ void BradsLessOriginalClient() xAxis = 1; xMove = true; } - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) { xAxis = -1; @@ -602,8 +617,6 @@ void BradsLessOriginalClient() al_set_timer_count(timer, 0); } al_destroy_display(display); - - } int main(int argc, const char** argv) From 4b84d9ad02861cff47273d0c37be1ece022697f8 Mon Sep 17 00:00:00 2001 From: bradley chamberlain Date: Tue, 12 Apr 2022 02:07:18 -0400 Subject: [PATCH 21/29] Ouch My head I really should make an effort to have less ridiculous commit messages. --- RoboCat/Chapter3.vcxproj | 3 + RoboCat/Inc/CircleClass.h | 69 ++++++++ RoboCat/Inc/RainParticle.h | 95 +++++++++++ RoboCat/Inc/RectangleObject.h | 78 +++++++++ RoboCat/Src/Main.cpp | 289 ++++++---------------------------- 5 files changed, 289 insertions(+), 245 deletions(-) create mode 100644 RoboCat/Inc/CircleClass.h create mode 100644 RoboCat/Inc/RainParticle.h create mode 100644 RoboCat/Inc/RectangleObject.h diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index 97edb686..6fd098a7 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -375,6 +375,9 @@ + + + diff --git a/RoboCat/Inc/CircleClass.h b/RoboCat/Inc/CircleClass.h new file mode 100644 index 00000000..1d784f51 --- /dev/null +++ b/RoboCat/Inc/CircleClass.h @@ -0,0 +1,69 @@ +#pragma once + +#include "allegro.h" +#include "allegro_primitives.h" +#include +#include + +class CircleClass +{ +public: + CircleClass(int windowWidth, int windowHeight, int xStart, int yStart, float newRadius); + CircleClass(); + void Read(InputMemoryBitStream& iStream); + void Write(OutputMemoryBitStream& oStream) const; + void Draw(); + void UpdatePos(int xChange, int yChange); + + int mWindowWidth; + int mWindowHeight; + std::vector position; + float radius; +}; + +void CircleClass::Read(InputMemoryBitStream& iStream) +{ + iStream.Read(position[0]); + iStream.Read(position[1]); + iStream.Read(radius); +} + +void CircleClass::Write(OutputMemoryBitStream& oStream) const +{ + oStream.Write(position[0]); + oStream.Write(position[1]); + oStream.Write(radius); +} + +void CircleClass::Draw() +{ + al_draw_filled_circle(position[0], position[1], radius, al_map_rgb(0, 255, 0)); +} + +CircleClass::CircleClass(int windowWidth, int windowHeight, int xStart, int yStart, float newRadius) +{ + mWindowWidth = windowWidth; + mWindowHeight = windowHeight; + position.push_back(xStart); + position.push_back(yStart); + radius = newRadius; +} + +CircleClass::CircleClass() +{ + int xTemp = 0; + int yTemp = 0; + position.push_back(xTemp); + position.push_back(yTemp); + radius = 10; +} + +void CircleClass::UpdatePos(int xChange, int yChange) +{ + position[0] += xChange; + position[1] += yChange; + if (position[0] > mWindowWidth) position[0] = 0; + if (position[1] > mWindowHeight) position[1] = 0; + if (position[0] < 0) position[0] = mWindowWidth; + if (position[1] < 0) position[1] = mWindowHeight; +} \ No newline at end of file diff --git a/RoboCat/Inc/RainParticle.h b/RoboCat/Inc/RainParticle.h new file mode 100644 index 00000000..19c3c82c --- /dev/null +++ b/RoboCat/Inc/RainParticle.h @@ -0,0 +1,95 @@ +#pragma once + +#include "allegro.h" +#include "allegro_primitives.h" +#include "vector" + +#include + +class RainParticle +{ +public: + RainParticle(int windowWidth, int windowHeight, float xStart, float yStart, float newRadius, float newR, float newG, float newB, float newA); + RainParticle(); + void Read(InputMemoryBitStream& iStream); + void Write(OutputMemoryBitStream& oStream) const; + void Draw(); + void UpdatePos(float xChange, float yChange); + + int mWindowWidth; + int mWindowHeight; + std::vector color; + std::vector position; + float radius; +}; + +RainParticle::RainParticle(int windowWidth, int windowHeight, float xStart, float yStart, float newRadius, float newR, float newG, float newB, float newA) +{ + mWindowWidth = windowWidth; + mWindowHeight = windowHeight; + color.push_back(newR); + color.push_back(newG); + color.push_back(newB); + color.push_back(newA); + + position.push_back(xStart); + position.push_back(yStart); + + radius = newRadius; +} + +RainParticle::RainParticle() +{ + float tempR, tempG, tempB, tempA, tempX, tempY; + + color.push_back(tempR); + color.push_back(tempG); + color.push_back(tempB); + color.push_back(tempA); + + position.push_back(tempX); + position.push_back(tempY); + + radius = float(); +} + +void RainParticle::Read(InputMemoryBitStream& iStream) +{ + iStream.Read(color[0]); + iStream.Read(color[1]); + iStream.Read(color[2]); + iStream.Read(color[3]); + + iStream.Read(position[0]); + iStream.Read(position[1]); + + iStream.Read(radius); +} + +void RainParticle::Write(OutputMemoryBitStream& oStream) const +{ + oStream.Write(color[0]); + oStream.Write(color[1]); + oStream.Write(color[2]); + oStream.Write(color[3]); + + oStream.Write(position[0]); + oStream.Write(position[1]); + + oStream.Write(radius); +} + +void RainParticle::Draw() +{ + al_draw_filled_circle(position[0], position[1], radius, al_map_rgba(color[0], color[1], color[2], color[3])); +} + +void RainParticle::UpdatePos(float xChange, float yChange) +{ + position[0] += xChange; + position[1] += yChange; + if (position[0] > mWindowWidth) position[0] = 0; + if (position[1] > mWindowHeight) position[1] = 0; + if (position[0] < 0) position[0] = mWindowWidth; + if (position[1] < 0) position[1] = mWindowHeight; +} \ No newline at end of file diff --git a/RoboCat/Inc/RectangleObject.h b/RoboCat/Inc/RectangleObject.h new file mode 100644 index 00000000..fb8586c2 --- /dev/null +++ b/RoboCat/Inc/RectangleObject.h @@ -0,0 +1,78 @@ +#pragma once + +#include "allegro.h" +#include "allegro_primitives.h" +#include + +class RectangleObject +{ +public: + string mName; + int mWindowWidth; + int mWindowHeight; + int width; + int height; + int xPos; + int yPos; + void Read(InputMemoryBitStream& stream); + void Write(OutputMemoryBitStream& stream) const; + RectangleObject(string name, int windowWidth, int windowHeight, int newWidth, int newHeight, int startPosX, int startPosY); + RectangleObject(); + void UpdatePos(int xChange, int yChange); + void Draw(); + +}; + +void RectangleObject::Read(InputMemoryBitStream& stream) +{ + stream.Read(mName); + stream.Read(width); + stream.Read(height); + stream.Read(xPos); + stream.Read(yPos); +} + +void RectangleObject::Write(OutputMemoryBitStream& stream) const +{ + stream.Write(mName); + stream.Write(width); + stream.Write(height); + stream.Write(xPos); + stream.Write(yPos); +} + +RectangleObject::RectangleObject(string name, int windowWidth, int windowHeight, int newWidth, int newHeight, int startPosX, int startPosY) +{ + mName = name; + mWindowWidth = windowWidth; + mWindowHeight = windowHeight; + width = newWidth; + height = newHeight; + xPos = startPosX; + yPos = startPosY; +} +RectangleObject::RectangleObject() +{ + mName = ""; + mWindowWidth = 100; + mWindowHeight = 100; + width = 10; + height = 10; + xPos = rand() % 100 + 1; + yPos = rand() % 100 + 1; +} + +void RectangleObject::UpdatePos(int xChange, int yChange) +{ + xPos += xChange; + yPos += yChange; + if (xPos > mWindowWidth) xPos = 0; + if (yPos > mWindowHeight) yPos = 0; + if (xPos < 0) xPos = mWindowWidth; + if (yPos < 0) yPos = mWindowHeight; +} + +void RectangleObject::Draw() +{ + al_draw_filled_rectangle(xPos, yPos, xPos + width, yPos + height, al_map_rgb(255, 0, 0)); +} \ No newline at end of file diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index e6ac779d..89482c3a 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -3,6 +3,9 @@ #include "allegro5.h" #include "allegro_primitives.h" #include "allegro_color.h" +#include "RectangleObject.h" +#include "RainParticle.h" +#include "CircleClass.h" #include #include @@ -17,210 +20,11 @@ int FRAMERATE = 16; #if _WIN32 -class RainParticle -{ -public: - RainParticle(float xStart, float yStart, float newRadius, float newR, float newG, float newB, float newA); - RainParticle(); - void Read(InputMemoryBitStream& iStream); - void Write(OutputMemoryBitStream& oStream) const; - void Draw(); - void UpdatePos(float xChange, float yChange); - - vector color; - vector position; - float radius; -}; - -RainParticle::RainParticle(float xStart, float yStart, float newRadius, float newR, float newG, float newB, float newA) -{ - color.push_back(newR); - color.push_back(newG); - color.push_back(newB); - color.push_back(newA); - - position.push_back(xStart); - position.push_back(yStart); - - radius = newRadius; -} - -RainParticle::RainParticle() -{ - float tempR, tempG, tempB, tempA, tempX, tempY; - - color.push_back(tempR); - color.push_back(tempG); - color.push_back(tempB); - color.push_back(tempA); - - position.push_back(tempX); - position.push_back(tempY); - - radius = float(); -} - -void RainParticle::Read(InputMemoryBitStream& iStream) -{ - iStream.Read(color[0]); - iStream.Read(color[1]); - iStream.Read(color[2]); - iStream.Read(color[3]); - - iStream.Read(position[0]); - iStream.Read(position[1]); - - iStream.Read(radius); -} - -void RainParticle::Write(OutputMemoryBitStream& oStream) const -{ - oStream.Write(color[0]); - oStream.Write(color[1]); - oStream.Write(color[2]); - oStream.Write(color[3]); - - oStream.Write(position[0]); - oStream.Write(position[1]); - - oStream.Write(radius); -} - -void RainParticle::Draw() -{ - al_draw_filled_circle(position[0], position[1], radius, al_map_rgba(color[0], color[1], color[2], color[3])); -} - -void RainParticle::UpdatePos(float xChange, float yChange) -{ - position[0] += xChange; - position[1] += yChange; - if (position[0] > windowWidth) position[0] = 0; - if (position[1] > windowHeight) position[1] = 0; - if (position[0] < 0) position[0] = windowWidth; - if (position[1] < 0) position[1] = windowHeight; -} - -class CircleClass -{ -public: - CircleClass(int xStart, int yStart, float newRadius); - CircleClass(); - void Read(InputMemoryBitStream& iStream); - void Write(OutputMemoryBitStream& oStream) const; - void Draw(); - void UpdatePos(int xChange, int yChange); - - vector position; - float radius; -}; - -void CircleClass::Read(InputMemoryBitStream& iStream) -{ - iStream.Read(position[0]); - iStream.Read(position[1]); - iStream.Read(radius); -} -void CircleClass::Write(OutputMemoryBitStream& oStream) const -{ - oStream.Write(position[0]); - oStream.Write(position[1]); - oStream.Write(radius); -} -void CircleClass::Draw() -{ - al_draw_filled_circle(position[0], position[1], radius, al_map_rgb(0, 255, 0)); -} -CircleClass::CircleClass(int xStart, int yStart, float newRadius) -{ - position.push_back(xStart); - position.push_back(yStart); - radius = newRadius; -} -CircleClass::CircleClass() -{ - int xTemp = 0; - int yTemp = 0; - position.push_back(xTemp); - position.push_back(yTemp); - radius = 10; -} -void CircleClass::UpdatePos(int xChange, int yChange) -{ - position[0] += xChange; - position[1] += yChange; - if (position[0] > windowWidth) position[0] = 0; - if (position[1] > windowHeight) position[1] = 0; - if (position[0] < 0) position[0] = windowWidth; - if (position[1] < 0) position[1] = windowHeight; -} - -class RectangleObject -{ -public: - int width; - int height; - int xPos; - int yPos; - void Read(InputMemoryBitStream& stream); - void Write(OutputMemoryBitStream& stream) const; - RectangleObject(int newWidth, int newHeight, int startPosX, int startPosY); - RectangleObject(); - void UpdatePos(int xChange, int yChange); - void Draw(); - -}; - -void RectangleObject::Read(InputMemoryBitStream& stream) -{ - stream.Read(width); - stream.Read(height); - stream.Read(xPos); - stream.Read(yPos); -} - -void RectangleObject::Write(OutputMemoryBitStream& stream) const -{ - stream.Write(width); - stream.Write(height); - stream.Write(xPos); - stream.Write(yPos); -} - -RectangleObject::RectangleObject(int newWidth, int newHeight, int startPosX, int startPosY) -{ - width = newWidth; - height = newHeight; - xPos = startPosX; - yPos = startPosY; -} -RectangleObject::RectangleObject() -{ - width = 10; - height = 10; - xPos = rand() % 100 + 1; - yPos = rand() % 100 + 1; -} - -void RectangleObject::UpdatePos(int xChange, int yChange) -{ - xPos += xChange; - yPos += yChange; - if (xPos > windowWidth) xPos = 0; - if (yPos > windowHeight) yPos = 0; - if (xPos < 0) xPos = windowWidth; - if (yPos < 0) yPos = windowHeight; -} - -void RectangleObject::Draw() -{ - al_draw_filled_rectangle(xPos, yPos, xPos + width, yPos + height, al_map_rgb(255, 0, 0)); -} void ThrowSocketError(std::string errorMsg) { @@ -239,20 +43,6 @@ ALLEGRO_TIMER* GiveMeATimer(float incr) return timer; } -//class ClientInPacket -//{ -//public: -// ClientPacket(); -// //~ClientPacket(); -// CircleClass inCircle; -// RainParticle inRain[10]; -//}; -// -//ClientPacket::ClientPacket() -//{ -// -//} - TCPSocketPtr StartServer() { @@ -285,6 +75,30 @@ TCPSocketPtr StartServer() return incomingSocket; } +TCPSocketPtr StartClientConnection() +{ + TCPSocketPtr clientSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (clientSocket == nullptr) + ThrowSocketError("Could not create client socket"); + + std::string address = StringUtils::Sprintf("127.0.0.1:8081"); + SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); + if (clientAddress == nullptr) + ThrowSocketError("Creating client address"); + + if (clientSocket->Bind(*clientAddress) != NO_ERROR) + ThrowSocketError("Binding Client Socket"); + + SocketAddressPtr serverAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:8080"); + if (serverAddress == nullptr) + ThrowSocketError("Creating server address"); + + if (clientSocket->Connect(*serverAddress) != NO_ERROR) + ThrowSocketError("Connecting to server"); + + return clientSocket; +} + void BradsTotallyOriginalServer() { TCPSocketPtr incomingSocket = StartServer(); @@ -292,8 +106,8 @@ void BradsTotallyOriginalServer() //Timer ALLEGRO_TIMER* timer = GiveMeATimer(0.001); - int currentTime = al_get_timer_count(timer); - int lastTime = 0; + double currentTime = al_get_timer_count(timer); + float lastTime = 0; float deltaTime = 0; // Game Loop Variables @@ -304,17 +118,20 @@ void BradsTotallyOriginalServer() CircleClass greenCircle[numObjects]; for (int j = 0; j < numObjects; j++) { - greenCircle[j] = CircleClass(100, 100, 20); + greenCircle[j] = CircleClass(windowWidth, windowHeight, 100, 100, 20); } const int numDroplets = 10; RainParticle rain[numDroplets]; for (int k = 0; k < numDroplets; k++) { - rain[k] = RainParticle(rand() % windowWidth + 1, rand() % windowHeight + 1, rand() % 5 + 5, 0, 0, rand() % 254 + 1, rand() % 254 + 1); + rain[k] = RainParticle(windowWidth, windowHeight, rand() % windowWidth + 1, rand() % windowHeight + 1, rand() % 5 + 5, 0, 0, rand() % 254 + 1, rand() % 254 + 1); } RectangleObject inObjects[numObjects]; + list < RectangleObject > clientProjectiles; + list < RectangleObject > serverProjectiles; + ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -441,29 +258,7 @@ void BradsTotallyOriginalServer() al_destroy_display(display); } -TCPSocketPtr StartClientConnection() -{ - TCPSocketPtr clientSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); - if (clientSocket == nullptr) - ThrowSocketError("Could not create client socket"); - - std::string address = StringUtils::Sprintf("127.0.0.1:8081"); - SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); - if (clientAddress == nullptr) - ThrowSocketError("Creating client address"); - - if (clientSocket->Bind(*clientAddress) != NO_ERROR) - ThrowSocketError("Binding Client Socket"); - - SocketAddressPtr serverAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:8080"); - if (serverAddress == nullptr) - ThrowSocketError("Creating server address"); - if (clientSocket->Connect(*serverAddress) != NO_ERROR) - ThrowSocketError("Connecting to server"); - - return clientSocket; -} void BradsLessOriginalClient() { TCPSocketPtr clientSocket = StartClientConnection(); @@ -471,8 +266,8 @@ void BradsLessOriginalClient() //timer ALLEGRO_TIMER* timer = GiveMeATimer(0.001); - int currentTime = al_get_timer_count(timer); - int lastTime = 0; + double currentTime = al_get_timer_count(timer); + float lastTime = 0; float deltaTime = 0; bool exit = false; @@ -480,18 +275,22 @@ void BradsLessOriginalClient() //create Game Objects RectangleObject outRectangles[numObjects]; + list < RectangleObject > projectiles; for (int j = 0; j < numObjects; j++) { - outRectangles[j] = RectangleObject(20, 20, rand() % windowWidth + 1, rand() % windowHeight + 1); + outRectangles[j] = RectangleObject("clientPlayer", windowWidth, windowHeight, 20, 20, rand() % windowWidth + 1, rand() % windowHeight + 1); } // Read In Objects CircleClass inObjects[numObjects]; + list < RectangleObject > clientProjectiles; + list < RectangleObject > serverProjectiles; + const int numDroplets = 10; RainParticle rain[numDroplets]; - + // Main Game Loop ALLEGRO_DISPLAY* display; display = al_create_display(windowWidth, windowHeight); @@ -537,8 +336,7 @@ void BradsLessOriginalClient() for (int j = 0; j < numDroplets; j++) { rain[j].Read(iStream); - } - + } } ALLEGRO_EVENT events; @@ -600,6 +398,7 @@ void BradsLessOriginalClient() outRectangles[i].Draw(); inObjects[i].Draw(); } + for (int j = 0; j < numDroplets; j++) { rain[j].Draw(); From 32ff9436639a9c98d07d10d4128b3bb0f38d8ca4 Mon Sep 17 00:00:00 2001 From: bradley chamberlain Date: Tue, 12 Apr 2022 03:24:40 -0400 Subject: [PATCH 22/29] Projectiles kinda I hope this was worth the effort --- RoboCat/Inc/CircleClass.h | 11 +++- RoboCat/Inc/RainParticle.h | 2 + RoboCat/RectangleObject.h | 0 RoboCat/Src/Main.cpp | 102 +++++++++++++++++++++++++++++-------- 4 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 RoboCat/RectangleObject.h diff --git a/RoboCat/Inc/CircleClass.h b/RoboCat/Inc/CircleClass.h index 1d784f51..e4674b16 100644 --- a/RoboCat/Inc/CircleClass.h +++ b/RoboCat/Inc/CircleClass.h @@ -8,13 +8,14 @@ class CircleClass { public: - CircleClass(int windowWidth, int windowHeight, int xStart, int yStart, float newRadius); + CircleClass(string name, int windowWidth, int windowHeight, int xStart, int yStart, float newRadius); CircleClass(); void Read(InputMemoryBitStream& iStream); void Write(OutputMemoryBitStream& oStream) const; void Draw(); void UpdatePos(int xChange, int yChange); + string mName; int mWindowWidth; int mWindowHeight; std::vector position; @@ -23,6 +24,7 @@ class CircleClass void CircleClass::Read(InputMemoryBitStream& iStream) { + iStream.Read(mName); iStream.Read(position[0]); iStream.Read(position[1]); iStream.Read(radius); @@ -30,6 +32,7 @@ void CircleClass::Read(InputMemoryBitStream& iStream) void CircleClass::Write(OutputMemoryBitStream& oStream) const { + oStream.Write(mName); oStream.Write(position[0]); oStream.Write(position[1]); oStream.Write(radius); @@ -40,8 +43,9 @@ void CircleClass::Draw() al_draw_filled_circle(position[0], position[1], radius, al_map_rgb(0, 255, 0)); } -CircleClass::CircleClass(int windowWidth, int windowHeight, int xStart, int yStart, float newRadius) +CircleClass::CircleClass(string name, int windowWidth, int windowHeight, int xStart, int yStart, float newRadius) { + mName = name; mWindowWidth = windowWidth; mWindowHeight = windowHeight; position.push_back(xStart); @@ -51,6 +55,9 @@ CircleClass::CircleClass(int windowWidth, int windowHeight, int xStart, int ySta CircleClass::CircleClass() { + mName = ""; + mWindowWidth = 100; + mWindowHeight = 100; int xTemp = 0; int yTemp = 0; position.push_back(xTemp); diff --git a/RoboCat/Inc/RainParticle.h b/RoboCat/Inc/RainParticle.h index 19c3c82c..c018305f 100644 --- a/RoboCat/Inc/RainParticle.h +++ b/RoboCat/Inc/RainParticle.h @@ -42,6 +42,8 @@ RainParticle::RainParticle() { float tempR, tempG, tempB, tempA, tempX, tempY; + mWindowWidth = 100; + mWindowHeight = 100; color.push_back(tempR); color.push_back(tempG); color.push_back(tempB); diff --git a/RoboCat/RectangleObject.h b/RoboCat/RectangleObject.h new file mode 100644 index 00000000..e69de29b diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 89482c3a..31ac5015 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -20,12 +20,6 @@ int FRAMERATE = 16; #if _WIN32 - - - - - - void ThrowSocketError(std::string errorMsg) { SocketUtil::ReportError(errorMsg.c_str()); @@ -118,7 +112,7 @@ void BradsTotallyOriginalServer() CircleClass greenCircle[numObjects]; for (int j = 0; j < numObjects; j++) { - greenCircle[j] = CircleClass(windowWidth, windowHeight, 100, 100, 20); + greenCircle[j] = CircleClass("serverPlayer", windowWidth, windowHeight, 100, 100, 20); } const int numDroplets = 10; @@ -129,8 +123,8 @@ void BradsTotallyOriginalServer() } RectangleObject inObjects[numObjects]; - list < RectangleObject > clientProjectiles; - list < RectangleObject > serverProjectiles; + list < RectangleObject* > clientProjectiles; + list < CircleClass* > serverProjectiles; ALLEGRO_DISPLAY* display; @@ -146,6 +140,8 @@ void BradsTotallyOriginalServer() bool xMove = true; bool yMove = true; + int projShot = 0; + while (!exit) //GameLoop { //Timer @@ -165,6 +161,13 @@ void BradsTotallyOriginalServer() { rain[j].Write(oStream); } + + int projectileCount = serverProjectiles.size(); + oStream.Write(projectileCount); + for each (CircleClass * projectile in serverProjectiles) + { + projectile->Write(oStream); + } incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); //recieve Data @@ -179,6 +182,15 @@ void BradsTotallyOriginalServer() { inObjects[i].Read(iStream); } + int clientProjectilesCount; + iStream.Read(clientProjectilesCount); + clientProjectiles.clear(); + for (int i = 0; i < clientProjectilesCount; i++) + { + RectangleObject* temp = new RectangleObject(); + temp->Read(iStream); + clientProjectiles.emplace_back(temp); + } } ALLEGRO_EVENT events; @@ -212,21 +224,27 @@ void BradsTotallyOriginalServer() yMove = true; yAxis = -1; } - else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) { yMove = true; yAxis = 1; } - else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) { xAxis = 1; xMove = true; } - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) { xAxis = -1; xMove = true; } + if (al_key_down(&keyState, ALLEGRO_KEY_SPACE)) + { + ++projShot; + CircleClass* proj = new CircleClass(to_string(projShot), windowWidth, windowHeight, greenCircle[0].position[0], greenCircle[0].position[1], 10); + serverProjectiles.emplace_back(proj); + } } for (int i = 0; i < numObjects; i++) @@ -238,9 +256,18 @@ void BradsTotallyOriginalServer() inObjects[i].Draw(); greenCircle[i].Draw(); } + for each (CircleClass * projectile in serverProjectiles) + { + projectile->UpdatePos(0, -1); + projectile->Draw(); + } + for each (RectangleObject * projectile in clientProjectiles) + { + projectile->Draw(); + } for (int j = 0; j < numDroplets; j++) { - rain[j].UpdatePos(0.1, 0.3); + rain[j].UpdatePos(1, 3); rain[j].Draw(); } al_flip_display(); @@ -252,7 +279,7 @@ void BradsTotallyOriginalServer() { currentPeriod = al_get_timer_count(timer) - currentTime; } - if (currentTime < 5000) + if (currentTime < 600000) al_set_timer_count(timer, 0); } al_destroy_display(display); @@ -261,6 +288,7 @@ void BradsTotallyOriginalServer() void BradsLessOriginalClient() { + TCPSocketPtr clientSocket = StartClientConnection(); clientSocket->SetNonBlockingMode(true); @@ -275,7 +303,6 @@ void BradsLessOriginalClient() //create Game Objects RectangleObject outRectangles[numObjects]; - list < RectangleObject > projectiles; for (int j = 0; j < numObjects; j++) { @@ -285,8 +312,8 @@ void BradsLessOriginalClient() // Read In Objects CircleClass inObjects[numObjects]; - list < RectangleObject > clientProjectiles; - list < RectangleObject > serverProjectiles; + list < RectangleObject* > clientProjectiles; + list < CircleClass* > serverProjectiles; const int numDroplets = 10; RainParticle rain[numDroplets]; @@ -305,6 +332,8 @@ void BradsLessOriginalClient() bool xMove = true; bool yMove = true; + int projShot = 0; + while (!exit) //GameLoop { //Timer @@ -319,6 +348,12 @@ void BradsLessOriginalClient() { outRectangles[i].Write(oStream); } + int projectileCount = clientProjectiles.size(); + oStream.Write(projectileCount); + for each (RectangleObject* projectile in clientProjectiles) + { + projectile->Write(oStream); + } clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); // Recieve data @@ -337,6 +372,15 @@ void BradsLessOriginalClient() { rain[j].Read(iStream); } + int serverProjectilesCount; + iStream.Read(serverProjectilesCount); + serverProjectiles.clear(); + for (int i = 0; i < serverProjectilesCount; i++) + { + CircleClass* temp = new CircleClass(); + temp->Read(iStream); + serverProjectiles.emplace_back(temp); + } } ALLEGRO_EVENT events; @@ -363,7 +407,6 @@ void BradsLessOriginalClient() xMove = false; } } - if (events.type == ALLEGRO_EVENT_KEY_DOWN) { al_get_keyboard_state(&keyState); @@ -372,21 +415,27 @@ void BradsLessOriginalClient() yMove = true; yAxis = -1; } - else if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) + if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) { yMove = true; yAxis = 1; } - else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) + if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) { xAxis = 1; xMove = true; } - else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) + if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) { xAxis = -1; xMove = true; } + if (al_key_down(&keyState, ALLEGRO_KEY_SPACE)) + { + ++projShot; + RectangleObject* proj = new RectangleObject(to_string(projShot), windowWidth, windowHeight, 10, 10, outRectangles[0].xPos, outRectangles[0].yPos); + clientProjectiles.emplace_back(proj); + } } for (int i = 0; i < numObjects; i++) @@ -398,6 +447,15 @@ void BradsLessOriginalClient() outRectangles[i].Draw(); inObjects[i].Draw(); } + for each (CircleClass * projectile in serverProjectiles) + { + projectile->Draw(); + } + for each (RectangleObject* projectile in clientProjectiles) + { + projectile->UpdatePos(0, 1); + projectile->Draw(); + } for (int j = 0; j < numDroplets; j++) { @@ -412,7 +470,7 @@ void BradsLessOriginalClient() { currentPeriod = al_get_timer_count(timer) - currentTime; } - if (currentTime < 5000) + if (currentTime < 600000) al_set_timer_count(timer, 0); } al_destroy_display(display); From c424996007b1ede7633485bbfe472041f8faba09 Mon Sep 17 00:00:00 2001 From: bradley chamberlain Date: Tue, 12 Apr 2022 03:42:01 -0400 Subject: [PATCH 23/29] I am struggle --- RoboCat/Src/Main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 31ac5015..65b0536a 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -356,12 +356,14 @@ void BradsLessOriginalClient() } clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); + list packets; // Recieve data char buffer[4096]; InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); //LOG("%s", "Client game loop"); bytesReceived = clientSocket->Receive(buffer, 4096); + if (bytesReceived != -10035) { for (int i = 0; i < numObjects; i++) From 50de4665ee77a39d282e71edfffab478c9961c0d Mon Sep 17 00:00:00 2001 From: Bradley Date: Tue, 12 Apr 2022 11:20:24 -0400 Subject: [PATCH 24/29] oof --- RoboCat/Src/Main.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 65b0536a..3a6bc630 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -6,6 +6,7 @@ #include "RectangleObject.h" #include "RainParticle.h" #include "CircleClass.h" +#include "math.h" #include #include @@ -256,15 +257,28 @@ void BradsTotallyOriginalServer() inObjects[i].Draw(); greenCircle[i].Draw(); } - for each (CircleClass * projectile in serverProjectiles) + for each (RectangleObject * projectile in clientProjectiles) { - projectile->UpdatePos(0, -1); projectile->Draw(); } - for each (RectangleObject * projectile in clientProjectiles) + for each (CircleClass * projectile in serverProjectiles) { + projectile->UpdatePos(0, -1); projectile->Draw(); - } + for each (RectangleObject* rects in clientProjectiles) + { + int xDist = rects->xPos - projectile->position[0]; + int yDist = rects->yPos - projectile->position[1]; + float dist = sqrt(exp2(xDist) + exp2(yDist)); + if (dist < 10) + { + /*clientProjectiles.remove(rects); + delete(rects); + serverProjectiles.remove(projectile); + delete(projectile);*/ + } + } + } for (int j = 0; j < numDroplets; j++) { rain[j].UpdatePos(1, 3); From 05070b941302070ba024bf38bbf0e99ded38dde1 Mon Sep 17 00:00:00 2001 From: Bradley Date: Thu, 14 Apr 2022 09:48:22 -0400 Subject: [PATCH 25/29] oh god --- RoboCat/Src/Main.cpp | 95 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 3a6bc630..af597c4b 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -21,6 +21,35 @@ int FRAMERATE = 16; #if _WIN32 + +class Packet +{ +public: + Packet(); + Packet(double stamp, InputMemoryBitStream bitstream); + ~Packet(); + double timeStamp; + InputMemoryBitStream* bitStream; +private: + +}; +Packet::Packet(double stamp, InputMemoryBitStream bitstream) { + timeStamp = stamp; + bitStream = &bitstream; +}; +Packet::Packet() +{ + timeStamp = 0; + char buffer[4096]; + bitStream = new InputMemoryBitStream(buffer, 4096); +} + +Packet::~Packet() +{ + delete(bitStream); +} + + void ThrowSocketError(std::string errorMsg) { SocketUtil::ReportError(errorMsg.c_str()); @@ -169,6 +198,7 @@ void BradsTotallyOriginalServer() { projectile->Write(oStream); } + //write ack incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); //recieve Data @@ -308,7 +338,7 @@ void BradsLessOriginalClient() //timer ALLEGRO_TIMER* timer = GiveMeATimer(0.001); - double currentTime = al_get_timer_count(timer); + double cTime = al_get_timer_count(timer); float lastTime = 0; float deltaTime = 0; @@ -348,12 +378,14 @@ void BradsLessOriginalClient() int projShot = 0; + list packets; + while (!exit) //GameLoop { //Timer - currentTime = al_get_timer_count(timer); - deltaTime = currentTime - lastTime; - lastTime = currentTime; + cTime = al_get_timer_count(timer); + deltaTime = cTime - lastTime; + lastTime = cTime; //send Data OutputMemoryBitStream oStream = OutputMemoryBitStream(); @@ -368,9 +400,11 @@ void BradsLessOriginalClient() { projectile->Write(oStream); } + //Write ack onto packet clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); - list packets; + + // Recieve data char buffer[4096]; InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); @@ -380,24 +414,55 @@ void BradsLessOriginalClient() if (bytesReceived != -10035) { + double currentTime = al_get_timer_count(timer); + int randomSin = rand() % 2; + if (randomSin == 0) + { + currentTime += rand() % 100 + 1; // jitter + } + else + { + currentTime -= rand() % 100 + 1; // jitter + } + currentTime += 100; //latency + Packet pack(currentTime, iStream); + packets.push_back(pack); + packets.sort([](const Packet& a, const Packet& b) { return a.timeStamp < b.timeStamp; }); + } + bool processOrNot; + processOrNot = packets.begin()->timeStamp < al_get_timer_count(timer); + //char buffer[4096]; + //packStream = packets.begin()->bitStream; + if (processOrNot) // maybe while + { + Packet operateOn = *packets.begin(); + InputMemoryBitStream packStream = *operateOn.bitStream; + for (int i = 0; i < numObjects; i++) { - inObjects[i].Read(iStream); + inObjects[i].Read(packStream); } for (int j = 0; j < numDroplets; j++) { - rain[j].Read(iStream); - } + rain[j].Read(packStream); + } int serverProjectilesCount; - iStream.Read(serverProjectilesCount); + packStream.Read(serverProjectilesCount); serverProjectiles.clear(); for (int i = 0; i < serverProjectilesCount; i++) { CircleClass* temp = new CircleClass(); - temp->Read(iStream); + temp->Read(packStream); serverProjectiles.emplace_back(temp); } - } + + list::iterator it1 = packets.begin(); + packets.erase(it1); + packets.front(); + + //readack + } + ALLEGRO_EVENT events; @@ -481,12 +546,12 @@ void BradsLessOriginalClient() al_clear_to_color(al_map_rgb(0, 0, 0)); //wait for the frame to end - int currentPeriod = al_get_timer_count(timer) - currentTime; + int currentPeriod = al_get_timer_count(timer) - cTime; while (currentPeriod < FRAMERATE) { - currentPeriod = al_get_timer_count(timer) - currentTime; + currentPeriod = al_get_timer_count(timer) - cTime; } - if (currentTime < 600000) + if (cTime < 600000) al_set_timer_count(timer, 0); } al_destroy_display(display); @@ -512,6 +577,8 @@ int main(int argc, const char** argv) al_install_keyboard(); + srand(time(NULL)); + bool isServer = StringUtils::GetCommandLineArg(1) == "server"; // check if the command on the executable is 'server' if (isServer) { From f8606d575217e32ba1115417d3c19a461e378eee Mon Sep 17 00:00:00 2001 From: bradley Date: Thu, 14 Apr 2022 22:44:43 -0400 Subject: [PATCH 26/29] The pain. --- RoboCat/Inc/MemoryBitStream.h | 2 +- RoboCat/Src/Main.cpp | 106 +++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/RoboCat/Inc/MemoryBitStream.h b/RoboCat/Inc/MemoryBitStream.h index c2138925..0bfd1874 100644 --- a/RoboCat/Inc/MemoryBitStream.h +++ b/RoboCat/Inc/MemoryBitStream.h @@ -104,7 +104,7 @@ class InputMemoryBitStream memcpy( mBuffer, inOther.mBuffer, byteCount ); } - ~InputMemoryBitStream() { if (mIsBufferOwner) { std::cout << "Freeing " << mBuffer << std::endl; free(mBuffer); }; } + ~InputMemoryBitStream() { if (mIsBufferOwner) { /*std::cout << "Freeing " << mBuffer << std::endl;*/ free(mBuffer); }; } const char* GetBufferPtr() const { return mBuffer; } uint32_t GetRemainingBitCount() const { return mBitCapacity - mBitHead; } diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index af597c4b..0e80eb19 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -26,27 +26,33 @@ class Packet { public: Packet(); - Packet(double stamp, InputMemoryBitStream bitstream); + Packet(double stamp, char* buffer, int byteCount); ~Packet(); double timeStamp; - InputMemoryBitStream* bitStream; + char* mBufferPtr; + int mByteCount; private: }; -Packet::Packet(double stamp, InputMemoryBitStream bitstream) { +Packet::Packet(double stamp, char* buffer, int byteCount) { timeStamp = stamp; - bitStream = &bitstream; + mBufferPtr = buffer; + mByteCount = byteCount; }; +//Packet::Packet(double stamp, InputMemoryBitStream bitstream) { +// timeStamp = stamp; +// bitStream = &bitstream; +//}; Packet::Packet() { timeStamp = 0; - char buffer[4096]; - bitStream = new InputMemoryBitStream(buffer, 4096); + mBufferPtr = new char[4096]; + mByteCount = 4096; + //bitStream = new InputMemoryBitStream(buffer, 4096); } Packet::~Packet() { - delete(bitStream); } @@ -323,7 +329,7 @@ void BradsTotallyOriginalServer() { currentPeriod = al_get_timer_count(timer) - currentTime; } - if (currentTime < 600000) + if (currentTime > 600000) al_set_timer_count(timer, 0); } al_destroy_display(display); @@ -378,7 +384,7 @@ void BradsLessOriginalClient() int projShot = 0; - list packets; + list packets; while (!exit) //GameLoop { @@ -403,67 +409,71 @@ void BradsLessOriginalClient() //Write ack onto packet clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); - - // Recieve data char buffer[4096]; - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); + //PLEASGOD//InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); - //LOG("%s", "Client game loop"); bytesReceived = clientSocket->Receive(buffer, 4096); if (bytesReceived != -10035) { + //LOG("%s", "Bytes were recieved"); // this worked + double currentTime = al_get_timer_count(timer); int randomSin = rand() % 2; if (randomSin == 0) { - currentTime += rand() % 100 + 1; // jitter + //LOG("%s", "positive jitter") + currentTime += rand() % 400 + 1; // jitter } else { - currentTime -= rand() % 100 + 1; // jitter + //LOG("%s", "negative jitter") + + currentTime -= rand() % 400 + 1; // jitter } - currentTime += 100; //latency - Packet pack(currentTime, iStream); + currentTime += 5000; //latency + Packet* pack = new Packet(currentTime, buffer, 4096); packets.push_back(pack); - packets.sort([](const Packet& a, const Packet& b) { return a.timeStamp < b.timeStamp; }); + packets.sort([](const Packet* a, const Packet* b) { return a->timeStamp < b->timeStamp; }); } - bool processOrNot; - processOrNot = packets.begin()->timeStamp < al_get_timer_count(timer); - //char buffer[4096]; - //packStream = packets.begin()->bitStream; - if (processOrNot) // maybe while + + if ((int)packets.size() > 0) { - Packet operateOn = *packets.begin(); - InputMemoryBitStream packStream = *operateOn.bitStream; - for (int i = 0; i < numObjects; i++) - { - inObjects[i].Read(packStream); - } - for (int j = 0; j < numDroplets; j++) - { - rain[j].Read(packStream); - } - int serverProjectilesCount; - packStream.Read(serverProjectilesCount); - serverProjectiles.clear(); - for (int i = 0; i < serverProjectilesCount; i++) + bool processOrNot = false; + + processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + cout << "timestamp " << packets.front()->timeStamp << endl; + cout << "current time " << al_get_timer_count(timer) << endl; + //cout << "process: " << processOrNot << endl; + if (processOrNot) // maybe while { - CircleClass* temp = new CircleClass(); - temp->Read(packStream); - serverProjectiles.emplace_back(temp); - } + LOG("%s", "process a packet"); - list::iterator it1 = packets.begin(); - packets.erase(it1); - packets.front(); + InputMemoryBitStream packStream(packets.front()->mBufferPtr, 4096); + for (int i = 0; i < numObjects; i++) + { + inObjects[i].Read(packStream); + } + for (int j = 0; j < numDroplets; j++) + { + rain[j].Read(packStream); + } + int serverProjectilesCount; + packStream.Read(serverProjectilesCount); + serverProjectiles.clear(); + for (int i = 0; i < serverProjectilesCount; i++) + { + CircleClass* temp = new CircleClass(); + temp->Read(packStream); + serverProjectiles.emplace_back(temp); + } + packets.pop_front(); + //readack + } - //readack } - - ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); @@ -551,7 +561,7 @@ void BradsLessOriginalClient() { currentPeriod = al_get_timer_count(timer) - cTime; } - if (cTime < 600000) + if (cTime > 600000) al_set_timer_count(timer, 0); } al_destroy_display(display); From ac637ea88f0a06e8848d5c1bc64d3cae91f22bf1 Mon Sep 17 00:00:00 2001 From: bradley Date: Thu, 14 Apr 2022 23:35:38 -0400 Subject: [PATCH 27/29] Jitter, latency, and Packet Loss Never been so happy to see lag --- RoboCat/Src/Main.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 0e80eb19..6582a931 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -410,7 +410,7 @@ void BradsLessOriginalClient() clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); // Recieve data - char buffer[4096]; + char* buffer = new char[4096]; //PLEASGOD//InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); bytesReceived = clientSocket->Receive(buffer, 4096); @@ -419,37 +419,36 @@ void BradsLessOriginalClient() { //LOG("%s", "Bytes were recieved"); // this worked - double currentTime = al_get_timer_count(timer); + double stampTime = al_get_timer_count(timer); + cout << "time start: " << stampTime; int randomSin = rand() % 2; if (randomSin == 0) { - //LOG("%s", "positive jitter") - currentTime += rand() % 400 + 1; // jitter + stampTime += rand() % 200 + 1; // jitter } else { - //LOG("%s", "negative jitter") - - currentTime -= rand() % 400 + 1; // jitter + stampTime -= rand() % 200 + 1; // jitter } - currentTime += 5000; //latency - Packet* pack = new Packet(currentTime, buffer, 4096); - packets.push_back(pack); - packets.sort([](const Packet* a, const Packet* b) { return a->timeStamp < b->timeStamp; }); + stampTime += 1000; //latency + Packet* pack = new Packet(stampTime, buffer, 4096); + if(!(rand()%100+0 < 5)) //5% packet loss + packets.push_back(pack); + if(packets.size() > 1) + packets.sort([](const Packet* a, const Packet* b) { return a->timeStamp < b->timeStamp; }); } if ((int)packets.size() > 0) { - bool processOrNot = false; processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); - cout << "timestamp " << packets.front()->timeStamp << endl; - cout << "current time " << al_get_timer_count(timer) << endl; + //cout << "timestamp " << packets.front()->timeStamp << endl; + //cout << "current time " << al_get_timer_count(timer) << endl; //cout << "process: " << processOrNot << endl; - if (processOrNot) // maybe while + if(processOrNot) // maybe while { - LOG("%s", "process a packet"); + //LOG("%s", "process a packet"); InputMemoryBitStream packStream(packets.front()->mBufferPtr, 4096); for (int i = 0; i < numObjects; i++) @@ -471,6 +470,7 @@ void BradsLessOriginalClient() } packets.pop_front(); //readack + processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); } } From 1a9dcc85a5a594e1614c7c598a692bc48c1cb6ca Mon Sep 17 00:00:00 2001 From: Bradley Date: Fri, 15 Apr 2022 07:46:32 -0400 Subject: [PATCH 28/29] both jitter now --- RoboCat/Src/Main.cpp | 77 ++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index 6582a931..e635f97d 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -178,6 +178,9 @@ void BradsTotallyOriginalServer() int projShot = 0; + list packets; + DeliveryNotificationManager deliveryManager(true, true); + while (!exit) //GameLoop { //Timer @@ -205,30 +208,67 @@ void BradsTotallyOriginalServer() projectile->Write(oStream); } //write ack + deliveryManager.WriteState(oStream); incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); //recieve Data - char buffer[4096]; + char* buffer = new char[4096]; int32_t bytesReceived = int32_t(); // get username - InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); bytesReceived = incomingSocket->Receive(buffer, 4096); if (bytesReceived != -10035) { - for (int i = 0; i < numObjects; i++) + double stampTime = al_get_timer_count(timer); + int randomSin = rand() % 2; + if (randomSin == 0) { - inObjects[i].Read(iStream); + stampTime += rand() % 200 + 1; // jitter } - int clientProjectilesCount; - iStream.Read(clientProjectilesCount); - clientProjectiles.clear(); - for (int i = 0; i < clientProjectilesCount; i++) + else { - RectangleObject* temp = new RectangleObject(); - temp->Read(iStream); - clientProjectiles.emplace_back(temp); + stampTime -= rand() % 200 + 1; // jitter } + stampTime += 1000; //latency + Packet* pack = new Packet(stampTime, buffer, 4096); + if (!(rand() % 100 + 0 < 5)) //5% packet loss + packets.push_back(pack); + if (packets.size() > 1) + packets.sort([](const Packet* a, const Packet* b) { return a->timeStamp < b->timeStamp; }); + } + if (packets.size() > 0) + { + bool processOrNot = false; + + processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + + while (processOrNot) // maybe while + { + InputMemoryBitStream packStream(packets.front()->mBufferPtr, 4096); + + for (int i = 0; i < numObjects; i++) + { + inObjects[i].Read(packStream); + } + int clientProjectilesCount; + packStream.Read(clientProjectilesCount); + clientProjectiles.clear(); + for (int i = 0; i < clientProjectilesCount; i++) + { + RectangleObject* temp = new RectangleObject(); + temp->Read(packStream); + clientProjectiles.emplace_back(temp); + } + + packets.pop_front(); + //readack + deliveryManager.ReadAndProcessState(packStream); + //process timed out acks + deliveryManager.ProcessTimedOutPackets(); + processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + } + } + ALLEGRO_EVENT events; @@ -385,7 +425,7 @@ void BradsLessOriginalClient() int projShot = 0; list packets; - + DeliveryNotificationManager deliveryManager(true, true); while (!exit) //GameLoop { //Timer @@ -407,18 +447,16 @@ void BradsLessOriginalClient() projectile->Write(oStream); } //Write ack onto packet + deliveryManager.WriteState(oStream); clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); // Recieve data char* buffer = new char[4096]; - //PLEASGOD//InputMemoryBitStream iStream = InputMemoryBitStream(buffer, 4096); int32_t bytesReceived = int32_t(); bytesReceived = clientSocket->Receive(buffer, 4096); if (bytesReceived != -10035) { - //LOG("%s", "Bytes were recieved"); // this worked - double stampTime = al_get_timer_count(timer); cout << "time start: " << stampTime; int randomSin = rand() % 2; @@ -443,12 +481,9 @@ void BradsLessOriginalClient() bool processOrNot = false; processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); - //cout << "timestamp " << packets.front()->timeStamp << endl; - //cout << "current time " << al_get_timer_count(timer) << endl; - //cout << "process: " << processOrNot << endl; - if(processOrNot) // maybe while + + while(processOrNot) // maybe while { - //LOG("%s", "process a packet"); InputMemoryBitStream packStream(packets.front()->mBufferPtr, 4096); for (int i = 0; i < numObjects; i++) @@ -470,6 +505,8 @@ void BradsLessOriginalClient() } packets.pop_front(); //readack + deliveryManager.ReadAndProcessState(packStream); + deliveryManager.ProcessTimedOutPackets(); processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); } From 3137d8e5ef1a02590f8cd7e5a47a6ca1a852a087 Mon Sep 17 00:00:00 2001 From: Bradley Date: Fri, 15 Apr 2022 11:32:14 -0400 Subject: [PATCH 29/29] First Attempt In Life It hurts. --- ...gnment2README.txt => Assignment3README.txt | 6 +- RoboCat/Inc/RectangleObject.h | 6 +- RoboCat/Src/Main.cpp | 141 ++++++++++++------ 3 files changed, 106 insertions(+), 47 deletions(-) rename Assignment2README.txt => Assignment3README.txt (65%) diff --git a/Assignment2README.txt b/Assignment3README.txt similarity index 65% rename from Assignment2README.txt rename to Assignment3README.txt index 2b3f4806..f6583087 100644 --- a/Assignment2README.txt +++ b/Assignment3README.txt @@ -6,8 +6,8 @@ press the escape key to end the Allegro Display server is a green circle client is a red square -movement on both apps is just Up Down Left Right +both can shoot with space bar but the projectiles do nothing and never die. -the rain is the third object +movement on both apps is just Up Down Left Right -it is jittery as hell but whatever, I am proud of it... +the rain is simulated on the server and sent to the client. diff --git a/RoboCat/Inc/RectangleObject.h b/RoboCat/Inc/RectangleObject.h index fb8586c2..428f13eb 100644 --- a/RoboCat/Inc/RectangleObject.h +++ b/RoboCat/Inc/RectangleObject.h @@ -20,9 +20,13 @@ class RectangleObject RectangleObject(); void UpdatePos(int xChange, int yChange); void Draw(); + //bool operator==(const RectangleObject& other); }; - +//bool RectangleObject::operator==(const RectangleObject& other) +//{ +// return mName == other.mName; +//} void RectangleObject::Read(InputMemoryBitStream& stream) { stream.Read(mName); diff --git a/RoboCat/Src/Main.cpp b/RoboCat/Src/Main.cpp index e635f97d..6b7185f4 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -13,6 +13,7 @@ #include #include #include +#include using namespace std; int windowWidth = 800; @@ -39,16 +40,12 @@ Packet::Packet(double stamp, char* buffer, int byteCount) { mBufferPtr = buffer; mByteCount = byteCount; }; -//Packet::Packet(double stamp, InputMemoryBitStream bitstream) { -// timeStamp = stamp; -// bitStream = &bitstream; -//}; + Packet::Packet() { timeStamp = 0; mBufferPtr = new char[4096]; mByteCount = 4096; - //bitStream = new InputMemoryBitStream(buffer, 4096); } Packet::~Packet() @@ -178,8 +175,10 @@ void BradsTotallyOriginalServer() int projShot = 0; - list packets; + list packets = {}; DeliveryNotificationManager deliveryManager(true, true); + list deadRects = {}; + list deadCircles = {}; while (!exit) //GameLoop { @@ -191,6 +190,7 @@ void BradsTotallyOriginalServer() //send Data OutputMemoryBitStream oStream = OutputMemoryBitStream(); + deliveryManager.WriteState(oStream); for (int i = 0; i < numObjects; i++) { greenCircle[i].Write(oStream); @@ -207,8 +207,7 @@ void BradsTotallyOriginalServer() { projectile->Write(oStream); } - //write ack - deliveryManager.WriteState(oStream); + incomingSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); //recieve Data @@ -222,7 +221,7 @@ void BradsTotallyOriginalServer() int randomSin = rand() % 2; if (randomSin == 0) { - stampTime += rand() % 200 + 1; // jitter + stampTime += rand() % 200 + 1; // jitter } else { @@ -230,13 +229,13 @@ void BradsTotallyOriginalServer() } stampTime += 1000; //latency Packet* pack = new Packet(stampTime, buffer, 4096); - if (!(rand() % 100 + 0 < 5)) //5% packet loss + if (!((rand() % 100 + 0) < 5)) //5% packet loss packets.push_back(pack); if (packets.size() > 1) packets.sort([](const Packet* a, const Packet* b) { return a->timeStamp < b->timeStamp; }); } - if (packets.size() > 0) + if (!packets.empty()) { bool processOrNot = false; @@ -246,6 +245,9 @@ void BradsTotallyOriginalServer() { InputMemoryBitStream packStream(packets.front()->mBufferPtr, 4096); + deliveryManager.ReadAndProcessState(packStream); + deliveryManager.ProcessTimedOutPackets(); + for (int i = 0; i < numObjects; i++) { inObjects[i].Read(packStream); @@ -257,18 +259,20 @@ void BradsTotallyOriginalServer() { RectangleObject* temp = new RectangleObject(); temp->Read(packStream); - clientProjectiles.emplace_back(temp); + clientProjectiles.push_back(temp); } + if(!packets.empty()) + packets.pop_front(); - packets.pop_front(); - //readack - deliveryManager.ReadAndProcessState(packStream); //process timed out acks - deliveryManager.ProcessTimedOutPackets(); - processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + if (!packets.empty()) + processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + else + processOrNot = false; + } } - + ALLEGRO_EVENT events; @@ -320,7 +324,7 @@ void BradsTotallyOriginalServer() { ++projShot; CircleClass* proj = new CircleClass(to_string(projShot), windowWidth, windowHeight, greenCircle[0].position[0], greenCircle[0].position[1], 10); - serverProjectiles.emplace_back(proj); + serverProjectiles.push_back(proj); } } @@ -333,27 +337,71 @@ void BradsTotallyOriginalServer() inObjects[i].Draw(); greenCircle[i].Draw(); } + + /*if (!deadRects.empty()) + { + for (RectangleObject* deadRect : deadRects) + { + if(!clientProjectiles.empty()) + for (RectangleObject* liveRect : clientProjectiles) + { + if (deadRect == liveRect) + { + cout << "remove" << endl; + RectangleObject* temp = deadRect; + clientProjectiles.remove(temp); + deadRects.remove(temp); + + if (!clientProjectiles.empty()) + clientProjectiles.front(); + + if (!deadRects.empty()) + deadRects.front(); + + cout << "remove worked at least 1 time" << endl; + delete[] temp; + break; + } + } + } + }*/ + for each (RectangleObject * projectile in clientProjectiles) { projectile->Draw(); } - for each (CircleClass * projectile in serverProjectiles) + /*while (deadCircles.size() > 0) + { + for each (CircleClass * deadCircle in deadCircles) + { + for each (CircleClass * liveRect in serverProjectiles) + { + if (deadCircle == liveRect) + { + serverProjectiles.remove(deadCircle); + deadCircles.remove(deadCircle); + } + } + } + }*/ + for (CircleClass * projectile: serverProjectiles) { projectile->UpdatePos(0, -1); projectile->Draw(); - for each (RectangleObject* rects in clientProjectiles) + /*for (RectangleObject* rects: clientProjectiles) { int xDist = rects->xPos - projectile->position[0]; int yDist = rects->yPos - projectile->position[1]; - float dist = sqrt(exp2(xDist) + exp2(yDist)); - if (dist < 10) + float dist = sqrt((xDist*xDist) + (yDist * yDist)); + if (dist < 1000) { - /*clientProjectiles.remove(rects); - delete(rects); - serverProjectiles.remove(projectile); - delete(projectile);*/ + cout << "kill eachother" << endl; + deadRects.push_back(rects); + deadCircles.push_back(projectile); + cout << "kill eachother worked" << endl; + break; } - } + }*/ } for (int j = 0; j < numDroplets; j++) { @@ -375,10 +423,8 @@ void BradsTotallyOriginalServer() al_destroy_display(display); } - void BradsLessOriginalClient() { - TCPSocketPtr clientSocket = StartClientConnection(); clientSocket->SetNonBlockingMode(true); @@ -402,8 +448,8 @@ void BradsLessOriginalClient() // Read In Objects CircleClass inObjects[numObjects]; - list < RectangleObject* > clientProjectiles; - list < CircleClass* > serverProjectiles; + list < RectangleObject* > clientProjectiles = {}; + list < CircleClass* > serverProjectiles = {}; const int numDroplets = 10; RainParticle rain[numDroplets]; @@ -424,7 +470,7 @@ void BradsLessOriginalClient() int projShot = 0; - list packets; + list packets = {}; DeliveryNotificationManager deliveryManager(true, true); while (!exit) //GameLoop { @@ -436,18 +482,19 @@ void BradsLessOriginalClient() //send Data OutputMemoryBitStream oStream = OutputMemoryBitStream(); + deliveryManager.WriteState(oStream); + for (int i = 0; i < numObjects; i++) { outRectangles[i].Write(oStream); } + int projectileCount = clientProjectiles.size(); oStream.Write(projectileCount); for each (RectangleObject* projectile in clientProjectiles) { projectile->Write(oStream); } - //Write ack onto packet - deliveryManager.WriteState(oStream); clientSocket->Send(oStream.GetBufferPtr(), oStream.GetByteLength()); // Recieve data @@ -458,7 +505,6 @@ void BradsLessOriginalClient() if (bytesReceived != -10035) { double stampTime = al_get_timer_count(timer); - cout << "time start: " << stampTime; int randomSin = rand() % 2; if (randomSin == 0) { @@ -468,15 +514,15 @@ void BradsLessOriginalClient() { stampTime -= rand() % 200 + 1; // jitter } - stampTime += 1000; //latency + stampTime += 1000; //latency Packet* pack = new Packet(stampTime, buffer, 4096); if(!(rand()%100+0 < 5)) //5% packet loss packets.push_back(pack); - if(packets.size() > 1) + if (packets.size() > 1) packets.sort([](const Packet* a, const Packet* b) { return a->timeStamp < b->timeStamp; }); } - if ((int)packets.size() > 0) + if (!packets.empty()) { bool processOrNot = false; @@ -486,6 +532,11 @@ void BradsLessOriginalClient() { InputMemoryBitStream packStream(packets.front()->mBufferPtr, 4096); + + deliveryManager.ReadAndProcessState(packStream); + deliveryManager.ProcessTimedOutPackets(); + + for (int i = 0; i < numObjects; i++) { inObjects[i].Read(packStream); @@ -505,12 +556,16 @@ void BradsLessOriginalClient() } packets.pop_front(); //readack - deliveryManager.ReadAndProcessState(packStream); - deliveryManager.ProcessTimedOutPackets(); - processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + if(!packets.empty()) + processOrNot = packets.front()->timeStamp < al_get_timer_count(timer); + else + processOrNot = false; + + } } + ALLEGRO_EVENT events; al_get_next_event(eventQueue, &events); @@ -562,7 +617,7 @@ void BradsLessOriginalClient() { ++projShot; RectangleObject* proj = new RectangleObject(to_string(projShot), windowWidth, windowHeight, 10, 10, outRectangles[0].xPos, outRectangles[0].yPos); - clientProjectiles.emplace_back(proj); + clientProjectiles.push_back(proj); } }