diff --git a/.gitignore b/.gitignore index 37c9fe57..ac798ac6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,8 @@ *.user *.pdb -Debug/ packages/ +Game/DeanLib/Debug +Game/Debug +Game/GraphicsLib/Debug +RoboCat/Debug diff --git a/Debug/allegro-5.2.dll b/Debug/allegro-5.2.dll new file mode 100644 index 00000000..517701bc Binary files /dev/null and b/Debug/allegro-5.2.dll differ diff --git a/Debug/allegro_acodec-5.2.dll b/Debug/allegro_acodec-5.2.dll new file mode 100644 index 00000000..0a4a584a Binary files /dev/null and b/Debug/allegro_acodec-5.2.dll differ diff --git a/Debug/allegro_audio-5.2.dll b/Debug/allegro_audio-5.2.dll new file mode 100644 index 00000000..5f4540ef Binary files /dev/null and b/Debug/allegro_audio-5.2.dll differ diff --git a/Debug/allegro_color-5.2.dll b/Debug/allegro_color-5.2.dll new file mode 100644 index 00000000..8e851bb1 Binary files /dev/null and b/Debug/allegro_color-5.2.dll differ diff --git a/Debug/allegro_dialog-5.2.dll b/Debug/allegro_dialog-5.2.dll new file mode 100644 index 00000000..cd5427d3 Binary files /dev/null and b/Debug/allegro_dialog-5.2.dll differ diff --git a/Debug/allegro_font-5.2.dll b/Debug/allegro_font-5.2.dll new file mode 100644 index 00000000..6cf5533f Binary files /dev/null and b/Debug/allegro_font-5.2.dll differ diff --git a/Debug/allegro_image-5.2.dll b/Debug/allegro_image-5.2.dll new file mode 100644 index 00000000..d8616356 Binary files /dev/null and b/Debug/allegro_image-5.2.dll differ diff --git a/Debug/allegro_memfile-5.2.dll b/Debug/allegro_memfile-5.2.dll new file mode 100644 index 00000000..4917b1e2 Binary files /dev/null and b/Debug/allegro_memfile-5.2.dll differ diff --git a/Debug/allegro_physfs-5.2.dll b/Debug/allegro_physfs-5.2.dll new file mode 100644 index 00000000..4736d437 Binary files /dev/null and b/Debug/allegro_physfs-5.2.dll differ diff --git a/Debug/allegro_primitives-5.2.dll b/Debug/allegro_primitives-5.2.dll new file mode 100644 index 00000000..d7e517fd Binary files /dev/null and b/Debug/allegro_primitives-5.2.dll differ diff --git a/Debug/allegro_ttf-5.2.dll b/Debug/allegro_ttf-5.2.dll new file mode 100644 index 00000000..504cad16 Binary files /dev/null and b/Debug/allegro_ttf-5.2.dll differ diff --git a/Debug/allegro_video-5.2.dll b/Debug/allegro_video-5.2.dll new file mode 100644 index 00000000..64ccd723 Binary files /dev/null and b/Debug/allegro_video-5.2.dll differ diff --git a/Game/.sln b/Game/.sln new file mode 100644 index 00000000..4f46e6f2 --- /dev/null +++ b/Game/.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsLib", "GraphicsLib\GraphicsLib.vcxproj", "{4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assignment2", "assignment2.vcxproj", "{EC58DA42-88DA-4B82-BFC4-AE6D5219F837}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} = {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeanLib", "..\..\..\..\common\DeanLib\DeanLib.vcxproj", "{DB900E08-5331-46D6-B450-6775A2C7C856}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|ARM.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|ARM.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.ActiveCfg = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.Build.0 = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.Build.0 = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|ARM.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.ActiveCfg = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.Build.0 = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.Build.0 = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|ARM.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.ActiveCfg = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.Build.0 = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.Build.0 = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|ARM.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x64.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x86.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x86.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|ARM.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x64.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x86.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2392FBF6-47CE-4D54-8F5B-DB78E5C9942D} + EndGlobalSection +EndGlobal diff --git a/Game/DeanLib/CircularQueue.cpp b/Game/DeanLib/CircularQueue.cpp new file mode 100644 index 00000000..184644b5 --- /dev/null +++ b/Game/DeanLib/CircularQueue.cpp @@ -0,0 +1,7 @@ +#include "CircularQueue.h" + + + + + + diff --git a/Game/DeanLib/DataRepository.cpp b/Game/DeanLib/DataRepository.cpp new file mode 100644 index 00000000..54717cf5 --- /dev/null +++ b/Game/DeanLib/DataRepository.cpp @@ -0,0 +1,88 @@ +#include "DataRepository.h" +#include + +DataEntry::DataEntry( int val ) + :mType(INT_VAL) +{ + mData.intVal = val; +} + +DataEntry::DataEntry( float val ) + :mType(FLOAT_VAL) +{ + mData.floatVal = val; +} + +DataEntry::DataEntry( double val ) + :mType(DOUBLE_VAL) +{ + mData.doubleVal = val; +} + +DataEntry::DataEntry( const std::string& val ) + :mType(STRING_VAL) +{ + assert( val.size() + 1 < MAX_STRING_VAL_SIZE ); + strcpy_s( mData.stringVal, val.c_str() ); +} + +DataEntry::DataEntry( UINT val ) + :mType(UINT_VAL) +{ + mData.uintVal = val; +} + +void DataRepository::addEntry( const DataKey& key, int val ) +{ + DataEntry entry( val ); + mMap[key] = entry; +} + +void DataRepository::addEntry( const DataKey& key, float val ) +{ + DataEntry entry( val ); + mMap[key] = entry; +} + +void DataRepository::addEntry( const DataKey& key, double val ) +{ + DataEntry entry( val ); + mMap[key] = entry; +} + +void DataRepository::addEntry( const DataKey& key, const std::string& val ) +{ + DataEntry entry( val ); + mMap[key] = entry; +} + +void DataRepository::addEntry( const DataKey& key, UINT val ) +{ + DataEntry entry( val ); + mMap[key] = entry; +} + +const DataEntry& DataRepository::getEntry( const DataKey& key ) +{ + static DataEntry nullEntry(0); + + auto iter = mMap.find( key ); + if( iter != mMap.end() ) + { + return iter->second; + } + else + { + return nullEntry; + } +} + +bool DataRepository::hasEntry(const DataKey& key) +{ + auto iter = mMap.find(key); + if (iter != mMap.end()) + return true; + else + return false; +} + diff --git a/Game/DeanLib/DeanLib.sln b/Game/DeanLib/DeanLib.sln new file mode 100644 index 00000000..4f944383 --- /dev/null +++ b/Game/DeanLib/DeanLib.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29102.190 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeanLib", "DeanLib.vcxproj", "{DB900E08-5331-46D6-B450-6775A2C7C856}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|Win32.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|Win32.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {03C61B9A-23B1-4AE3-B273-100743DFB149} + EndGlobalSection +EndGlobal diff --git a/Game/DeanLib/DeanLib.vcxproj b/Game/DeanLib/DeanLib.vcxproj new file mode 100644 index 00000000..642d08e4 --- /dev/null +++ b/Game/DeanLib/DeanLib.vcxproj @@ -0,0 +1,103 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {DB900E08-5331-46D6-B450-6775A2C7C856} + DeanLib + 10.0 + + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + $(ProjectDir)lib\ + $(ProjectName)$(Configuration) + + + $(ProjectDir)lib\ + $(ProjectName)$(Configuration) + + + + Level3 + Disabled + true + include + + + true + + + + + Level3 + MaxSpeed + true + true + true + include + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Game/DeanLib/DeanLibUtilities.cpp b/Game/DeanLib/DeanLibUtilities.cpp new file mode 100644 index 00000000..0b32c781 --- /dev/null +++ b/Game/DeanLib/DeanLibUtilities.cpp @@ -0,0 +1,42 @@ +#include "DeanLibUtilities.h" + +using namespace std; + +string peekString(ifstream& stream) +{ + if (!stream.good() || stream.eof()) + { + return ""; + } + + int charCnt = 0; + auto currPos = stream.cur; + + string theString; + while (!stream.eof()) + { + char c; + stream >> c; + if (c != ' ') + { + charCnt++; + theString += c; + } + } + + if (charCnt > 0) + { + stream.seekg(currPos + charCnt); + return theString; + } + else + { + return ""; + } +} + +int peekInt(std::ifstream& stream) +{ + return 0; +} + diff --git a/Game/DeanLib/DeanMath.cpp b/Game/DeanLib/DeanMath.cpp new file mode 100644 index 00000000..c933fc25 --- /dev/null +++ b/Game/DeanLib/DeanMath.cpp @@ -0,0 +1,21 @@ +#include "DeanMath.h" +#include "Vector2D.h" + +double calcDotProduct(const Vector2D& vector1, const Vector2D& vector2) +{ + return vector1.dotProduct(vector2); +} + +double mapToRangeMinusPiToPi(double val) +{ + while (val < -PI) + { + val += DOUBLE_PI; + } + + while (val > PI) + { + val -= DOUBLE_PI; + } + return val; +} diff --git a/Game/DeanLib/Desktop.ini b/Game/DeanLib/Desktop.ini new file mode 100644 index 00000000..ae60713d Binary files /dev/null and b/Game/DeanLib/Desktop.ini differ diff --git a/Game/DeanLib/MemoryPool.cpp b/Game/DeanLib/MemoryPool.cpp new file mode 100644 index 00000000..4c66e7e4 --- /dev/null +++ b/Game/DeanLib/MemoryPool.cpp @@ -0,0 +1,121 @@ +#include "MemoryPool.h" +#include +#include +#include + +using namespace std; + +//got this algorithm from: http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/ +int isPowerOfTwo(unsigned int x) +{ + return ((x != 0) && !(x & (x - 1))); +} + +unsigned int getClosestPowerOf2LargerThan(unsigned int num) +{ + static Uint32 powersOf2[32]; + static bool arrayInitted = false; + + //init an array containing all the powers of 2 + //(as it is static this should only run the first time this function is called) + if (!arrayInitted) + { + for (Uint32 i = 0; i < 32; i++) + { + powersOf2[i] = 1 << i; + } + } + + //find the 1st power of 2 which is bigger than or equal to num + for (Uint32 i = 0; i < 32; i++) + { + if ( powersOf2[i] >= num ) + return powersOf2[i]; + } + + //failsafe + return 0; + +} + +MemoryPool::MemoryPool(unsigned int maxNumObjects, unsigned int objectSize) +{ + //make objectSize a power of 2 - used for padding + objectSize = getClosestPowerOf2LargerThan(objectSize); + if (objectSize < 4) + { + objectSize = 4; + } + + //allocate the memory + mMemory = (Byte*)malloc(objectSize * maxNumObjects); + + //set member variables + mMaxNumObjects = maxNumObjects; + mNumAllocatedObjects = 0; + mObjectSize = objectSize; + mHighestValidAddress = mMemory + ((maxNumObjects - 1) * objectSize); + + //allocate the free list + mpFreeList = new CircularQueue(mMaxNumObjects); + + //create the free list + createFreeList(); +} + +void MemoryPool::reset() +{ + //clear the free list + mpFreeList->reset(); + //create the free list again + createFreeList(); + //reset count of allocated objects + mNumAllocatedObjects = 0; +} + +Byte* MemoryPool::allocateObject() +{ + if (mNumAllocatedObjects >= mMaxNumObjects) + { + return NULL; + } + + mNumAllocatedObjects++; + Byte* ptr; + bool success = mpFreeList->popFront(ptr); + if (success) + { + return ptr; + } + else + { + assert(false); + return NULL; + } +} + +void MemoryPool::freeObject(Byte* ptr) +{ + //make sure that the address passed in is actually one managed by this pool + if (ptr >= mMemory && ptr <= mHighestValidAddress) + { + //add address back to free list + mpFreeList->pushBack(ptr); + + mNumAllocatedObjects--; + } + else + { + cout << "ERROR: object freed from a pool that doesn't manage it\n"; + assert(ptr >= mMemory && ptr <= mHighestValidAddress); + } +} + +void MemoryPool::createFreeList() +{ + for (Uint32 i = 0; ipushBack(mMemory + (i * mObjectSize)); + } + +} diff --git a/Game/DeanLib/MemoryTracker.cpp b/Game/DeanLib/MemoryTracker.cpp new file mode 100644 index 00000000..9c6566ba --- /dev/null +++ b/Game/DeanLib/MemoryTracker.cpp @@ -0,0 +1,69 @@ +#include +#include +#include "MemoryTracker.h" + + +using namespace std; + +int MemoryTracker::msAllocationNum = 0; +MemoryTracker* MemoryTracker::mspInstance = NULL; + +MemoryTracker* MemoryTracker::getInstance() +{ + if (mspInstance == NULL) + { + mspInstance = new MemoryTracker; + } + return mspInstance; +} + +MemoryTracker::MemoryTracker() +{ +} + +MemoryTracker::~MemoryTracker() +{ + cout << "MemoryTracker being deleted: final allocations follow:\n"; + reportAllocations( cout ); +} + +void MemoryTracker::addAllocation( void* ptr, size_t size ) +{ + //make sure it's not already in the map + unordered_map::iterator iter = mAllocations.find( ptr ); + if( iter != mAllocations.end() ) + { + //already exists - problem! + } + else + { + AllocationRecord theRec( msAllocationNum, size ); + pair thePair(ptr,theRec); + mAllocations.insert( thePair ); + msAllocationNum++; + } +} + +void MemoryTracker::removeAllocation( void* ptr ) +{ + //find it in the map! + unordered_map::iterator iter = mAllocations.find( ptr ); + if( iter == mAllocations.end() ) + { + //problem!!!! + } + else + { + mAllocations.erase( iter ); + } +} + +void MemoryTracker::reportAllocations( std::ostream& stream ) +{ + stream << "Current memory allocations:\n"; + + unordered_map::iterator iter; + for( iter = mAllocations.begin(); iter != mAllocations.end(); ++iter ) + { + } +} diff --git a/Game/DeanLib/PerformanceTracker.cpp b/Game/DeanLib/PerformanceTracker.cpp new file mode 100644 index 00000000..6817bfbe --- /dev/null +++ b/Game/DeanLib/PerformanceTracker.cpp @@ -0,0 +1,81 @@ +#include "PerformanceTracker.h" + +using namespace std; + +PerformanceTracker::PerformanceTracker() +{ +} + +PerformanceTracker::~PerformanceTracker() +{ + map::iterator iter; + for( iter = mTimers.begin(); iter != mTimers.end(); ++iter ) + { + delete iter->second; + } +} + +void PerformanceTracker::startTracking( const string& trackerName ) +{ + Timer* pTimer = NULL; + + //find if tracker already exists + map::iterator iter = mTimers.find( trackerName ); + if( iter != mTimers.end() ) + { + pTimer = iter->second; + } + else + { + pTimer = new Timer(); + pTimer->start(); + mTimers[trackerName] = pTimer; + } + + pTimer->pause(false); +} + +void PerformanceTracker::stopTracking( const string& trackerName ) +{ + //make sure timer already exists + map::iterator iter = mTimers.find( trackerName ); + if( iter != mTimers.end() ) + { + iter->second->pause(true); + } + +} + +double PerformanceTracker::getElapsedTime( const string& trackerName ) +{ + //make sure timer already exists + map::iterator iter = mTimers.find( trackerName ); + if( iter != mTimers.end() ) + { + return iter->second->getElapsedTime(); + } + else + return 0.0; +} + +void PerformanceTracker::removeTracker( const std::string& trackerName ) +{ + //find the existing timer + map::iterator iter = mTimers.find( trackerName ); + if( iter != mTimers.end() ) + { + delete iter->second; + mTimers.erase( iter ); + } + +} + +void PerformanceTracker::clearTracker( const std::string& trackerName ) +{ + //find if tracker already exists + map::iterator iter = mTimers.find( trackerName ); + if( iter != mTimers.end() ) + { + iter->second->start(); + } +} \ No newline at end of file diff --git a/Game/DeanLib/README.txt b/Game/DeanLib/README.txt new file mode 100644 index 00000000..9935818a --- /dev/null +++ b/Game/DeanLib/README.txt @@ -0,0 +1,5 @@ +This is a Subversion repository; use the 'svnadmin' and 'svnlook' +tools to examine it. Do not add, delete, or modify files here +unless you know how to avoid corrupting the repository. + +Visit http://subversion.apache.org/ for more information. diff --git a/Game/DeanLib/RayCaster.cpp b/Game/DeanLib/RayCaster.cpp new file mode 100644 index 00000000..108576bc --- /dev/null +++ b/Game/DeanLib/RayCaster.cpp @@ -0,0 +1,18 @@ +#include "RayCaster.h" + +std::vector RayCaster::getPoints(const Vector2D& start, const Vector2D& end, float interval) +{ + std::vector thePoints; + + Vector2D diff = end - start; + Vector2D normalizedDiff = diff; + normalizedDiff.normalize(); + + int numIterations = (int)(diff.getLength() / interval)-1; + for (int i = 1; i < numIterations; i++) + { + Vector2D point = (normalizedDiff * interval * (float)i) + start; + thePoints.push_back(point); + } + return thePoints; +} diff --git a/Game/DeanLib/Timer.cpp b/Game/DeanLib/Timer.cpp new file mode 100644 index 00000000..cda35971 --- /dev/null +++ b/Game/DeanLib/Timer.cpp @@ -0,0 +1,87 @@ +#include "Timer.h" + +Timer::Timer() +:mElapsedTime(0.0) +,mPaused(true) +{ + QueryPerformanceFrequency( &mTimerFrequency ); + mStartTime.QuadPart = 0; + mEndTime.QuadPart = 0; +} + +Timer::~Timer() +{ +} + +void Timer::start() +{ + QueryPerformanceCounter( &mStartTime ); + + //reset end time as well + mEndTime.QuadPart = 0; + + mElapsedTime = 0.0; + + pause( false );//unpause +} + +void Timer::stop() +{ + QueryPerformanceCounter( &mEndTime ); + mElapsedTime = calcDifferenceInMS( mStartTime, mEndTime ); +} + +void Timer::pause( bool shouldPause ) +{ + if( shouldPause && !mPaused )//want to pause and we are not currently paused + { + mPaused = true; + QueryPerformanceCounter( &mEndTime ); + mElapsedTime += calcDifferenceInMS( mStartTime, mEndTime ); + } + else if( !shouldPause && mPaused )//want to unpause and we are paused + { + mPaused = false; + QueryPerformanceCounter( &mStartTime ); + } +} + +double Timer::getElapsedTime() const +{ + //if we have an end time then the timer isn't running and we can just return the elapsed time + if( mEndTime.QuadPart != 0 ) + { + return mElapsedTime; + } + else //otherwise we need to get the current time, do the math and return that + { + LARGE_INTEGER currentTime; + QueryPerformanceCounter( ¤tTime ); + return calcDifferenceInMS( mStartTime, currentTime ); + } +} + +void Timer::sleepUntilElapsed( double ms ) +{ + LARGE_INTEGER currentTime, lastTime; + QueryPerformanceCounter( ¤tTime ); + double timeToSleep = ms - calcDifferenceInMS( mStartTime, currentTime ); + + while( timeToSleep > 0.0 ) + { + lastTime = currentTime; + QueryPerformanceCounter( ¤tTime ); + double timeElapsed = calcDifferenceInMS( lastTime, currentTime ); + timeToSleep -= timeElapsed; + if( timeToSleep > 10.0 )//if we are going to be in this loop for a long time - + { //Sleep to relinquish back to Windows + Sleep(10); + } + } +} + +double Timer::calcDifferenceInMS( LARGE_INTEGER from, LARGE_INTEGER to ) const +{ + double difference = (double)(to.QuadPart - from.QuadPart) / (double)mTimerFrequency.QuadPart; + return difference * 1000; +} diff --git a/Game/DeanLib/Trackable.cpp b/Game/DeanLib/Trackable.cpp new file mode 100644 index 00000000..d1bb7e9b --- /dev/null +++ b/Game/DeanLib/Trackable.cpp @@ -0,0 +1,28 @@ +#include "Trackable.h" +#include "MemoryTracker.h" + +void* Trackable::operator new( std::size_t size ) +{ + void* ptr = malloc(size); + MemoryTracker::getInstance()->addAllocation( ptr, size ); + return ptr; +} + +void Trackable::operator delete( void *ptr ) +{ + MemoryTracker::getInstance()->removeAllocation(ptr); + free(ptr); +} + +void* Trackable::operator new[]( std::size_t size ) +{ + void* ptr = malloc(size); + MemoryTracker::getInstance()->addAllocation( ptr, size ); + return ptr; +} + +void Trackable::operator delete[]( void *ptr ) +{ + MemoryTracker::getInstance()->removeAllocation(ptr); + free(ptr); +} \ No newline at end of file diff --git a/Game/DeanLib/Vector2D.cpp b/Game/DeanLib/Vector2D.cpp new file mode 100644 index 00000000..2f74009a --- /dev/null +++ b/Game/DeanLib/Vector2D.cpp @@ -0,0 +1,175 @@ +#include "Vector2D.h" +#include +#include +#include +#include "include\DeanMath.h" + +Vector2D::Vector2D(float x, float y) +:mX(x) +,mY(y) +{ +} + +Vector2D::Vector2D( const Vector2D& rhs ) +:mX( rhs.mX ) +,mY( rhs.mY ) +{ +} + +Vector2D::Vector2D(int x, int y ) + :mX((float)x) + ,mY((float)y) +{ +} + +Vector2D::~Vector2D() +{ +} + +Vector2D& Vector2D::operator += ( const Vector2D& rhs ) +{ + mX += rhs.mX; + mY += rhs.mY; + return *this; +} + +Vector2D& Vector2D::operator -= ( const Vector2D& rhs ) +{ + mX -= rhs.mX; + mY -= rhs.mY; + return *this; +} + +Vector2D& Vector2D::operator = ( const Vector2D& rhs ) +{ + mX = rhs.mX; + mY = rhs.mY; + return *this; +} + +Vector2D& Vector2D::operator *= ( float mult ) +{ + mX *= mult; + mY *= mult; + return *this; +} + +Vector2D& Vector2D::operator /= ( float div ) +{ + mX /= div; + mY /= div; + return *this; +} + +Vector2D Vector2D::operator+(const Vector2D &other) const +{ + Vector2D result = *this; + result += other; + return result; +} + +Vector2D Vector2D::operator-(const Vector2D &other) const +{ + Vector2D result = *this; + result -= other; + return result; +} + +Vector2D Vector2D::operator*(float mult) const +{ + Vector2D result = *this; + result.mX *= mult; + result.mY *= mult; + + return result; +} + +Vector2D Vector2D::operator/(float div) const +{ + Vector2D result = *this; + result.mX /= div; + result.mY /= div; + + return result; +} + +bool Vector2D::operator==( const Vector2D& rhs ) const +{ + if ((getX() == rhs.getX()) && (getY() == rhs.getY())) + return true; + else return false; +} + +bool Vector2D::operator!=( const Vector2D& rhs ) const +{ + if ((getX() == rhs.getX()) && (getY() == rhs.getY())) + return false; + else return true; +} + +bool Vector2D::hasNonZeroLength() const +{ + if( mX != 0.0f || mY != 0.0f ) + { + return true; + } + else + { + return false; + } +} + +float Vector2D::getLength() const +{ + float lengthSquared = getLengthSquared(); + return sqrt( lengthSquared ); +} + +float Vector2D::getLengthSquared() const +{ + float lengthSquared = ( mX * mX ) + ( mY * mY ); + return lengthSquared; +} + +void Vector2D::normalize() +{ + float invLength = 1.0f / (getLength() + FLT_MIN); + mX *= invLength; + mY *= invLength; +} + +Vector2D Vector2D::getNormalizedVector() const +{ + Vector2D newVector(*this); + newVector.normalize(); + return newVector; +} + +float Vector2D::dotProduct(const Vector2D& other) const +{ + return mX * other.mX + mY * other.mY; +} + +Vector2D Vector2D::getRightVector() const +{ + return Vector2D(-mY, mX); +} + +double Vector2D::calcFacing() const +{ + return atan2(mX, -mY); +} + +Vector2D Vector2D::getVectorInDirection(double direction) +{ + return Vector2D((float)cos(direction), (float)sin(direction)); +} + +std::ostream & operator<<(std::ostream& out, const Vector2D& vector) +{ + out << "(" << vector.getX() << "," << vector.getY() << ")"; + return out; +} + + + diff --git a/Game/DeanLib/format b/Game/DeanLib/format new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/Game/DeanLib/format @@ -0,0 +1 @@ +5 diff --git a/Game/DeanLib/include/CircularQueue.h b/Game/DeanLib/include/CircularQueue.h new file mode 100644 index 00000000..98749b6d --- /dev/null +++ b/Game/DeanLib/include/CircularQueue.h @@ -0,0 +1,70 @@ +#pragma once + +#include + +template < class T > +class CircularQueue +{ +public: + explicit CircularQueue(Uint32 size) + : mCapacity(size) + , mFront(0) + , mBack(0) + , mNumEntries(0) + { + mArray = new T[size]; + } + + ~CircularQueue() + { + delete[] mArray; + } + + void reset() + { + mFront = 0; + mBack = 0; + mNumEntries = 0; + } + + bool pushBack(const T& item)//return false if not successfully added (not enough space) + { + if (mNumEntries >= mCapacity)//no room left + return false; + + mArray[mBack] = item; + mBack++; + mNumEntries++; + + if (mBack >= mCapacity) + { + mBack = 0; + } + + return true; + } + + bool popFront(T& item)//returns false if queue is empty + { + if (mNumEntries == 0)//empty + return false; + + item = mArray[mFront]; + mFront++; + mNumEntries--; + + if (mFront >= mCapacity) + { + mFront = 0; + } + + return true; + } +private: + T* mArray; + Uint32 mCapacity; + Uint32 mBack; + Uint32 mFront; + Uint32 mNumEntries; +}; + diff --git a/Game/DeanLib/include/ConditionalCallback.h b/Game/DeanLib/include/ConditionalCallback.h new file mode 100644 index 00000000..568a5389 --- /dev/null +++ b/Game/DeanLib/include/ConditionalCallback.h @@ -0,0 +1,45 @@ +#pragma once + +#pragma once + + + +/*template +void callbackFunc(T var) +{ + F(var); +}*/ + +template +class ConditionalCallback +{ +public: + ConditionalCallback(bool(*condFunc)(), void(*func)(T), T val) + :mpCallbackFunc(func) + , mpConditionalFunc(condFunc) + , mValue(val) + { + }; + + bool update(double dtInMS)//returns true after calling callback, false otherwise + { + if (mpConditionalFunc()) + { + call(mValue); + return true; + } + else + return false; + } + +private: + void(*mpCallbackFunc)(T) = nullptr; + bool(*mpConditionalFunc)() = nullptr; + T mValue; + + void call(T var) + { + mpCallbackFunc(var); + }; + +}; diff --git a/Game/DeanLib/include/DataRepository.h b/Game/DeanLib/include/DataRepository.h new file mode 100644 index 00000000..eb7e6dba --- /dev/null +++ b/Game/DeanLib/include/DataRepository.h @@ -0,0 +1,76 @@ +#pragma once + + +#include +#include +#include +#include + +const UINT MAX_STRING_VAL_SIZE = 128; + +union DataUnion +{ + int intVal; + float floatVal; + double doubleVal; + char stringVal[MAX_STRING_VAL_SIZE]; + UINT uintVal; + +}; + +enum DataType +{ + INT_VAL, + FLOAT_VAL, + DOUBLE_VAL, + STRING_VAL, + UINT_VAL +}; + +class DataEntry +{ +public: + DataEntry( int val ); + DataEntry( float val ); + DataEntry( double val ); + DataEntry( const std::string& val ); + DataEntry( UINT val ); + DataEntry() :mType(UINT_VAL) { mData.uintVal = 0; }; + + ~DataEntry(){}; + + inline int getIntVal() const { assert( mType == INT_VAL ); return mData.intVal; }; + inline float getFloatVal() const { assert( mType == FLOAT_VAL ); return mData.floatVal; }; + inline double getDoubleVal() const { assert( mType == DOUBLE_VAL ); return mData.doubleVal; }; + inline std::string getStringVal() const { assert( mType == STRING_VAL ); return std::string(mData.stringVal); }; + inline UINT getUIntVal() const { assert( mType == UINT_VAL ); return mData.uintVal; }; +private: + DataType mType; + DataUnion mData; + +}; + +typedef int DataKey; + +class DataRepository +{ + +public: + DataRepository(){}; + ~DataRepository(){}; + + void addEntry( const DataKey& key, int val ); + void addEntry( const DataKey& key, float val ); + void addEntry( const DataKey& key, double val ); + void addEntry( const DataKey& key, const std::string& val ); + void addEntry( const DataKey& key, UINT val ); + + const DataEntry& getEntry( const DataKey& key ); + + bool hasEntry(const DataKey& key); +private: + std::unordered_map mMap; +}; + + + diff --git a/Game/DeanLib/include/DeanLibDefines.h b/Game/DeanLib/include/DeanLibDefines.h new file mode 100644 index 00000000..2e235717 --- /dev/null +++ b/Game/DeanLib/include/DeanLibDefines.h @@ -0,0 +1,4 @@ +#pragma once + +typedef unsigned char Byte; +typedef unsigned int Uint32; \ No newline at end of file diff --git a/Game/DeanLib/include/DeanLibUtilities.h b/Game/DeanLib/include/DeanLibUtilities.h new file mode 100644 index 00000000..8956a7b3 --- /dev/null +++ b/Game/DeanLib/include/DeanLibUtilities.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +std::string peekString(std::ifstream& stream); +int peekInt(std::ifstream& stream); + + diff --git a/Game/DeanLib/include/DeanMath.h b/Game/DeanLib/include/DeanMath.h new file mode 100644 index 00000000..4c2c7077 --- /dev/null +++ b/Game/DeanLib/include/DeanMath.h @@ -0,0 +1,13 @@ +#pragma once + +class Vector2D; + +const double PI = 3.14159265358979323846; +const double DOUBLE_PI = PI*2; +const double HALF_PI = PI / 2; +const double QUARTER_PI = PI / 2; + +double mapToRangeMinusPiToPi(double val); + +double calcDotProduct(const Vector2D& vector1, const Vector2D& vector2); + diff --git a/Game/DeanLib/include/MemoryPool.h b/Game/DeanLib/include/MemoryPool.h new file mode 100644 index 00000000..5e9e3451 --- /dev/null +++ b/Game/DeanLib/include/MemoryPool.h @@ -0,0 +1,31 @@ +#pragma once + +#include "DeanLibDefines.h" +#include "CircularQueue.h" + + + +class MemoryPool +{ +public: + MemoryPool(unsigned int maxNumObjects, unsigned int objectSize); + ~MemoryPool() { free(mMemory); delete mpFreeList; }; + + void reset();//doesn't reallocate memory but does reset free list and num allocated objects + + Byte* allocateObject(); + void freeObject(Byte* ptr); + + inline Uint32 getMaxObjectSize(){ return mObjectSize; }; + inline Uint32 getNumFreeObjects(){ return mMaxNumObjects - mNumAllocatedObjects; }; + +private: + Byte* mMemory; + Byte* mHighestValidAddress; + Uint32 mMaxNumObjects; + Uint32 mNumAllocatedObjects; + Uint32 mObjectSize; + CircularQueue* mpFreeList; + + void createFreeList(); +}; \ No newline at end of file diff --git a/Game/DeanLib/include/MemoryTracker.h b/Game/DeanLib/include/MemoryTracker.h new file mode 100644 index 00000000..4c3bac84 --- /dev/null +++ b/Game/DeanLib/include/MemoryTracker.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + + +class MemoryTracker +{ +public: + static MemoryTracker* getInstance(); + + void addAllocation( void* ptr, size_t size ); + void removeAllocation( void* ptr ); + + void reportAllocations( std::ostream& stream ); + +private: + struct AllocationRecord + { + AllocationRecord(int theNum, size_t theSize) : num(theNum), size(theSize) {}; + int num; + size_t size; + }; + + + MemoryTracker(); + ~MemoryTracker(); + + //copying not allowed + MemoryTracker( const MemoryTracker& ); + MemoryTracker& operator=( const MemoryTracker& ); + + std::unordered_map mAllocations; + + static int msAllocationNum; + static MemoryTracker* mspInstance; +}; + diff --git a/Game/DeanLib/include/MultiDimensionalArray.h b/Game/DeanLib/include/MultiDimensionalArray.h new file mode 100644 index 00000000..3a12c97c --- /dev/null +++ b/Game/DeanLib/include/MultiDimensionalArray.h @@ -0,0 +1,62 @@ +#pragma once + + + +template < class T > +class MultiDimensionalArray : +{ +public: + explicit MultiDimensionalArray(unsigned int numRows, unsigned int numCols, const T& initialValue) + :mNumRows(numRows) + ,mNumCols(numCols) + { + mArray = new T[mNumRows*mNumCols]; + for (unsigned int i = 0; i < mNumRows*mNumCols; i++) + { + mArray[i] = initialValue; + } + + } + + ~MultiDimensionalArray() + { + delete [] mArray; + } + + T* get(unsigned int index) + { + if (index < mNumRows * mNumCols) + { + return &(mArray[index]); + } + else + return NULL; + } + + T* get(unsigned int colNum, unsigned int rowNum) + { + return get(convertCoordsToIndex(colNum,rowNum)); + } + + void set(unsigned int index, const T& val) { *(get(index)) = val; } + void set(unsigned int colNum, unsigned int rowNum, const T& val) { *(get(colNum,rowNum)) = val; } + + void convertIndexToCoords(unsigned int index, unsigned int& xOut, unsigned int& yOut) + { + xOut = index % mNumCols; + yOut = index / mNumCols; + } + + unsigned int convertCoordsToIndex(const unsigned int& xIn, const unsigned int& yIn) + { + unsigned int index = yIn * mNumCols + xIn; + return index; + } + +private: + T* mArray; + unsigned int mNumRows; + unsigned int mNumCols; + + +}; diff --git a/Game/DeanLib/include/PerformanceTracker.h b/Game/DeanLib/include/PerformanceTracker.h new file mode 100644 index 00000000..feabdd39 --- /dev/null +++ b/Game/DeanLib/include/PerformanceTracker.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Timer.h" + +#include +#include + + +class PerformanceTracker +{ +public: + PerformanceTracker(); + ~PerformanceTracker(); + + void startTracking( const std::string& trackerName ); + void stopTracking( const std::string& trackerName ); + double getElapsedTime( const std::string& trackerName ); + void removeTracker( const std::string& trackerName ); + void clearTracker( const std::string& trackerName ); + +private: + std::map mTimers; +}; + diff --git a/Game/DeanLib/include/RayCaster.h b/Game/DeanLib/include/RayCaster.h new file mode 100644 index 00000000..e20db57f --- /dev/null +++ b/Game/DeanLib/include/RayCaster.h @@ -0,0 +1,12 @@ +#pragma once + + +#include "Vector2D.h" + +#include + +class RayCaster +{ +public: + static std::vector getPoints(const Vector2D& start, const Vector2D& end, float interval); +}; \ No newline at end of file diff --git a/Game/DeanLib/include/TimedCallback.h b/Game/DeanLib/include/TimedCallback.h new file mode 100644 index 00000000..98384fd1 --- /dev/null +++ b/Game/DeanLib/include/TimedCallback.h @@ -0,0 +1,51 @@ +#pragma once + + + +/*template +void callbackFunc(T var) +{ + F(var); +}*/ + +template +class TimedCallback +{ +public: + TimedCallback(double delayInMS, void(*func)(T), T val) + :mDelayInMS(delayInMS) + ,mTimeLeft(delayInMS) + ,mpCallbackFunc(func) + ,mValue(val) + { + }; + + bool update(double dtInMS)//returns true after calling callback, false otherwise + { + mTimeLeft -= dtInMS; + if (mTimeLeft <= 0.0) + { + call(mValue); + return true; + } + else + return false; + } + + void reset(double delayInMS) + { + mDelayInMS = delayInMS; + mTimeLeft = delayInMS; + } +private: + void(*mpCallbackFunc)(T) = nullptr; + double mDelayInMS = 0.0; + double mTimeLeft = 0.0; + T mValue; + + void call(T var) + { + mpCallbackFunc(var); + }; + +}; diff --git a/Game/DeanLib/include/Timer.h b/Game/DeanLib/include/Timer.h new file mode 100644 index 00000000..18691408 --- /dev/null +++ b/Game/DeanLib/include/Timer.h @@ -0,0 +1,34 @@ +#pragma once +#include + + +/* Timer - high accuracy timer - uses Large Integer to prevent rollover + +Dean Lawson +Champlain College +2011 +*/ + +class Timer +{ +public: + Timer(); + ~Timer(); + + void start(); + void stop(); + double getElapsedTime() const;//returns how much time has elapsed since start + void sleepUntilElapsed( double ms ); + void pause( bool shouldPause ); + +private: + LARGE_INTEGER mStartTime; + LARGE_INTEGER mEndTime; + LARGE_INTEGER mTimerFrequency; + double mElapsedTime; + bool mPaused; + + //helper function - uses current frequency for the Timer + double calcDifferenceInMS( LARGE_INTEGER from, LARGE_INTEGER to ) const; + +}; \ No newline at end of file diff --git a/Game/DeanLib/include/Trackable.h b/Game/DeanLib/include/Trackable.h new file mode 100644 index 00000000..74d2e34f --- /dev/null +++ b/Game/DeanLib/include/Trackable.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +class Trackable +{ +public: + Trackable(std::string info) : mDebugSource(info) {} + Trackable() {} + void* operator new(std::size_t size); + void operator delete(void *ptr); + void* operator new[](std::size_t size); + void operator delete[](void *ptr); + + //for use with placement new + void* operator new(std::size_t size, void* ptr){ return ptr; }; + void operator delete(void *ptr, void*ptr2){}; + void* operator new[](std::size_t size, void* ptr){ return ptr; }; + void operator delete[](void *ptr, void* ptr2){}; + + const std::string& getDebugSource() { return mDebugSource; } +private: + std::string mDebugSource = ""; +}; diff --git a/Game/DeanLib/include/Vector2D.h b/Game/DeanLib/include/Vector2D.h new file mode 100644 index 00000000..dc5f6667 --- /dev/null +++ b/Game/DeanLib/include/Vector2D.h @@ -0,0 +1,70 @@ +#pragma once + +/* Vector2D is a generally usable 2D vector. Most of the operator overloading code is patterned after the notes from + California Institue of Technology site: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html . + Exact author unknown. + May be missing some important functions but this should be enough to do most things. + + by Dean Lawson + Champlain College + 2011 +*/ + + +#include "DeanMath.h" +#include +#include + + +class Vector2D +{ + friend std::ostream & operator<< (std::ostream& out, const Vector2D& vector); + +public: + explicit Vector2D(float x = 0.0f, float y = 0.0f);//constructor + explicit Vector2D(int x, int y);//constructor + Vector2D( const Vector2D& rhs );//copy constructor + ~Vector2D();//destructor + + //math operators + Vector2D& operator += ( const Vector2D& rhs ); + Vector2D& operator -= ( const Vector2D& rhs ); + Vector2D& operator *= ( float mult ); + Vector2D& operator /= ( float div ); + Vector2D& operator = ( const Vector2D& rhs ); + + bool operator == ( const Vector2D& rhs )const; + bool operator != ( const Vector2D& rhs )const; + + Vector2D operator+(const Vector2D &other) const; + Vector2D operator-(const Vector2D &other) const; + Vector2D operator*(float mult) const; + Vector2D operator/(float div) const; + + //getters and setters + inline float getX() const { return mX; }; + inline float getY() const { return mY; }; + inline void setX( float x ) { mX = x; }; + inline void setY( float y ) { mY = y; }; + + //length functions + bool hasNonZeroLength() const; + float getLength() const; + float getLengthSquared() const;//more efficient than get length - use when comparing distances and actual distance is not needed + + void normalize();//makes vector a unit vector (length of 1) + Vector2D getNormalizedVector() const;//returns a vector of length 1 but leaves the original vector unchanged + float dotProduct(const Vector2D& other) const; + Vector2D getRightVector() const;//right vector is a vector perpendicular and on the right side + double calcFacing() const; + static Vector2D getVectorInDirection(double direction); + +private: + float mX; + float mY; +}; + +std::ostream & operator<< (std::ostream& out, const Vector2D& vector); + +const Vector2D ZERO_VECTOR2D(0.0f, 0.0f);//useful when we need to return a pointer to a default vector from a function + diff --git a/Game/DeanLib/lib/DeanLibDebug.idb b/Game/DeanLib/lib/DeanLibDebug.idb new file mode 100644 index 00000000..705b8512 Binary files /dev/null and b/Game/DeanLib/lib/DeanLibDebug.idb differ diff --git a/Game/DeanLib/lib/DeanLibDebug.lib b/Game/DeanLib/lib/DeanLibDebug.lib new file mode 100644 index 00000000..d5426776 Binary files /dev/null and b/Game/DeanLib/lib/DeanLibDebug.lib differ diff --git a/Game/DeanLib/lib/DeanLibRelease.lib b/Game/DeanLib/lib/DeanLibRelease.lib new file mode 100644 index 00000000..4248a25b Binary files /dev/null and b/Game/DeanLib/lib/DeanLibRelease.lib differ diff --git a/Game/DeanLib/svn.ico b/Game/DeanLib/svn.ico new file mode 100644 index 00000000..0896ad00 Binary files /dev/null and b/Game/DeanLib/svn.ico differ diff --git a/Game/DeleteUnitsEvent.cpp b/Game/DeleteUnitsEvent.cpp new file mode 100644 index 00000000..d9953f65 --- /dev/null +++ b/Game/DeleteUnitsEvent.cpp @@ -0,0 +1,10 @@ +#include "DeleteUnitsEvent.h" + +DeleteUnitsEvent::DeleteUnitsEvent() + :Event(7) +{ +} + +DeleteUnitsEvent::~DeleteUnitsEvent() +{ +} diff --git a/Game/DeleteUnitsEvent.h b/Game/DeleteUnitsEvent.h new file mode 100644 index 00000000..e64e4cd9 --- /dev/null +++ b/Game/DeleteUnitsEvent.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Event.h" + +class DeleteUnitsEvent : public Event +{ +public: + DeleteUnitsEvent(); + ~DeleteUnitsEvent(); + + //int getX() const { return num; }; + //int getY() const { return mY; }; + +}; \ No newline at end of file diff --git a/Game/EscEvent.cpp b/Game/EscEvent.cpp new file mode 100644 index 00000000..9032475d --- /dev/null +++ b/Game/EscEvent.cpp @@ -0,0 +1,10 @@ +#include "EscEvent.h" + +EscEvent::EscEvent() + :Event(5) +{ +} + +EscEvent::~EscEvent() +{ +} diff --git a/Game/EscEvent.h b/Game/EscEvent.h new file mode 100644 index 00000000..eb010756 --- /dev/null +++ b/Game/EscEvent.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Event.h" + +class EscEvent : public Event +{ +public: + EscEvent(); + ~EscEvent(); +}; \ No newline at end of file diff --git a/Game/Game.cpp b/Game/Game.cpp new file mode 100644 index 00000000..a30ebe1f --- /dev/null +++ b/Game/Game.cpp @@ -0,0 +1,283 @@ +#include "Game.h" +#include "DeleteUnitsEvent.h" +#include "EscEvent.h" +#include "PauseEvent.h" +#include "PlaceUnitEvent.h" +#include "SwitchAnimEvent.h" + +Game::Game() +{ + mUserY = 0; + mUserX = 0; + mFrameRate = 1000 / 60; //set default frame rate of 60fps + mSinceFrame = 0; + + mpUnitManager = new UnitManager; + mpSystem = new System; + mpGManager = new GraphicsBufferManager; + mpInTranslator = new InputTranslator; + + cont = true; +} + +Game::~Game() +{ + cleanUp(); +} + +void Game::init() +{ + mpSystem->init(800, 600); + + //Add all buffers + mpGManager->addGBuffer("woods", DIRECTORY + WOODS_FILENAME); + mpGManager->addGBuffer("smurfs", DIRECTORY + SMURF_SPRITES_FILENAME); + mpGManager->addGBuffer("dean", DIRECTORY + DEAN_SPRITES_FILENAME); + + //Create animations + for (int i = 0; i < SMURF_ROWS; i++) + { + for (int j = 0; j < SMURF_COLS; j++) + { + mAnimation1.addSprite(Sprite(mpGManager->getGBuffer("smurfs"), { j * SMURF_SIZE, i * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE)); + mAnimation2.addSprite(Sprite(mpGManager->getGBuffer("dean"), { j * SMURF_SIZE, i * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE)); + } + } + + //set animation variables + mAnimation1.setLooping(true); + mAnimation1.setTiming(150); + mAnimation2.setTiming(150); + mAnimation2.setLooping(true); + + mpUnitManager->addUnit(-1000, -1000, mAnimation1, mAnimation2); +} + +void Game::cleanUp() +{ + mpInTranslator->cleanup(); + //delete(mpInTranslator); + + mpUnitManager->cleanup(); + delete mpUnitManager; + + mpGManager->cleanup(); + delete mpGManager; + + mpSystem->cleanup(); + delete(mpSystem); +} + +void Game::doLoop() +{ + //while (cont) + //{ + mTimer.start(); + + //GET INPUT + mpSystem->update(); + + //ADJUST GAME STATE + mpUnitManager->update(mSinceFrame); //units position and frame + + //RENDER + mpSystem->mpGraphicsSystem->draw(mpGManager->getGBuffer("woods"), 0, 0, 0.5); //render woods + mpUnitManager->draw(mpSystem->mpGraphicsSystem); //render unit + + //FLIP SCREEN + mpSystem->mpGraphicsSystem->flip(); + + //NEXT FRAME + mTimer.sleepUntilElapsed(mFrameRate); //sleep until frame is over + mSinceFrame = mTimer.getElapsedTime(); //get the time it took to complete this frame + //cout << mSinceFrame << endl; //output that frame time + //} +} + +void Game::setFrameRate(double fps) +{ + //set the frames per second, using 1000ms a second + mFrameRate = 1000.0 / fps; +} + +Game* Game::mpsInstance = NULL; + +void Game::initInstance() +{ + if (mpsInstance == nullptr) + { + mpsInstance = new Game(); + mpsInstance->init(); + } +} + +void Game::cleanUpInstance() +{ + delete mpsInstance; + mpsInstance = nullptr; +} + +void Game::setWorldStateChanged(bool set) +{ + hasChanged = set; +} + +bool Game::getWorldStateChanged() +{ + return hasChanged; +} + +void Game::escape() +{ + //exit the game + cont = false; +} + +void Game::pause() +{ + //pause all units animations + mpUnitManager->pauseAnim(); +} + +void Game::switchAnim() +{ + //switch animation of last unit + if (mpUnitManager->getUnitAnim(mpUnitManager->getLastUnit()) == 1) + { + mpUnitManager->setUnitAnim(mpUnitManager->getLastUnit(), 0); + } + else + { + mpUnitManager->setUnitAnim(mpUnitManager->getLastUnit(), 1); + } +} + +void Game::placeUnit(int type) +{ + if (mpUnitManager->getUnitCount() < 20) + { + int x = rand() % mpSystem->mpGraphicsSystem->getWidth(); + int y = rand() % mpSystem->mpGraphicsSystem->getHeight(); + Sprite sprite; + switch (type) + { + case 1: + sprite = Sprite(mpGManager->getGBuffer("smurfs"), { 0 * SMURF_SIZE, 0 * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE); + mpUnitManager->addUnit(x - SMURF_SIZE / 2, y - SMURF_SIZE / 2, sprite, type); + break; + case 2: + sprite = Sprite(mpGManager->getGBuffer("smurfs"), { 0 * SMURF_SIZE, 4 * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE); + mpUnitManager->addUnit(x - SMURF_SIZE / 2, y - SMURF_SIZE / 2, sprite, type); + break; + case 3: + sprite = Sprite(mpGManager->getGBuffer("smurfs"), { 6 * SMURF_SIZE, 4 * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE); + mpUnitManager->addUnit(x - SMURF_SIZE / 2, y - SMURF_SIZE / 2, sprite, type); + break; + default: + break; + } + //std::cout << type << endl; + //add a unit + } +} + +void Game::placeUnit(int id, int type, int xLoc, int yLoc) +{ + int x = xLoc; + int y = yLoc; + Sprite sprite; + switch (type) + { + case 1: + sprite = Sprite(mpGManager->getGBuffer("smurfs"), { 0 * SMURF_SIZE, 0 * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE); + mpUnitManager->addUnit(x - SMURF_SIZE / 2, y - SMURF_SIZE / 2, sprite, type, id); + break; + case 2: + sprite = Sprite(mpGManager->getGBuffer("smurfs"), { 0 * SMURF_SIZE, 4 * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE); + mpUnitManager->addUnit(x - SMURF_SIZE / 2, y - SMURF_SIZE / 2, sprite, type, id); + break; + case 3: + sprite = Sprite(mpGManager->getGBuffer("smurfs"), { 6 * SMURF_SIZE, 4 * SMURF_SIZE }, SMURF_SIZE, SMURF_SIZE); + mpUnitManager->addUnit(x - SMURF_SIZE / 2, y - SMURF_SIZE / 2, sprite, type, id); + break; + default: + break; + } + //std::cout << type << endl; + //add a unit +} + +void Game::deleteUnits() +{ + //erase all units in a vicinity + if (mpUnitManager->getUnitCount() > 1) + { + mpUnitManager->deleteRandomUnit(); + } +} + +void Game::deleteUnit(int id) +{ + //cout << "got to delting \n"; + mpUnitManager->deleteUnitID(id); +} + +void Game::deleteAllUnits() +{ + mpUnitManager->deleteAllUnits(); +} + +void Game::updateWorldState(int xLoc[], int yLoc[], int type[]) +{ + /* + mpUnitManager->deleteAllUnits(); + + for (int i = 0; i < sizeof(type); i++) + { + placeUnit(type[i], xLoc[i], yLoc[i]); + } + */ +} + +Unit* Game::unitWithID(int id) +{ + return mpUnitManager->getUnitWithID(id); +} + +void Game::updateUnitLocation(int id, int xLoc, int yLoc) +{ + unitWithID(id)->mX = xLoc; + unitWithID(id)->mY = yLoc; +} + +void Game::addUnitTranslation(int velX, int velY) +{ + mpUnitManager->updatePositions(velX*10, velY*10); +} + +/* +void Game::updateWorldState(Unit* units[4096]) +{ + mpUnitManager->deleteAllUnits(); + for (int i = 0; i < sizeof(units); i++) + { + placeUnit(units[i].mType, units[i].mX, units[i].mY); + } +} +*/ + +vector> Game::getUnitData() +{ + return mpUnitManager->getAllUnitsLocation(); +} + +vector Game::getUnitDeletion() +{ + return mpUnitManager->getDeletedUnits(); +} + + + + + + diff --git a/Game/Game.h b/Game/Game.h new file mode 100644 index 00000000..d018231d --- /dev/null +++ b/Game/Game.h @@ -0,0 +1,87 @@ +#pragma once + +#include "System.h" + + +#include "Timer.h" +#include "UnitManager.h" +#include "GraphicsBuffer.h" +#include "GraphicsBufferManager.h" +#include "UnitManager.h" +#include "InputTranslator.h" +#include "EventListener.h" + +//Paths +const string DIRECTORY = "..\\..\\..\\Game\\assets\\"; +const string WOODS_FILENAME = "Woods.png"; +const string SMURF_SPRITES_FILENAME = "glowing-balls.png"; +const string DEAN_SPRITES_FILENAME = "dean_sprites.png"; + +//Sizes +const int SMURF_ROWS = 4; +const int SMURF_COLS = 4; +const int SMURF_SIZE = 32; + +class Game +{ +private: + Game(); + ~Game(); + + //Instance of game + static Game* mpsInstance; + + //Game Systems + System * mpSystem; + InputTranslator* mpInTranslator; + + //MouseX and Y + int mUserX; + int mUserY; + + //Time + Timer mTimer; + double mFrameRate; + float mSinceFrame; + bool cont; + + //Managers + GraphicsBufferManager* mpGManager; + UnitManager* mpUnitManager; + Animation mAnimation1; + Animation mAnimation2; + + bool hasChanged; + +public: + + void init(); + void cleanUp(); + void doLoop(); + void setFrameRate(double fps); + + //INSTANCE FUNCTIONS + static Game* getInstance() { return mpsInstance; } + static void initInstance(); + static void cleanUpInstance(); + + void setWorldStateChanged(bool set); + bool getWorldStateChanged(); + + //EVENT FUNCTIONS + void escape(); + void pause(); + void switchAnim(); + void placeUnit(int type); + void placeUnit(int id, int type, int xLoc, int yLoc); + void deleteUnits(); + void deleteUnit(int id); + void deleteAllUnits(); + void updateWorldState(int xLoc[], int yLoc[], int type[]); + Unit* unitWithID(int id); + void updateUnitLocation(int id, int xLoc, int yLoc); + void addUnitTranslation(int velX, int velY); + //void updateWorldState(Unit* units[4096]); + vector> getUnitData(); + vector getUnitDeletion(); +}; \ No newline at end of file diff --git a/Game/GameEvent.cpp b/Game/GameEvent.cpp new file mode 100644 index 00000000..47d4eed0 --- /dev/null +++ b/Game/GameEvent.cpp @@ -0,0 +1,11 @@ +#include "GameEvent.h" + +/*GameEvent::GameEvent(GameEventType type) + :mType(type) +{ +} + +GameEvent::~GameEvent() +{ +}*/ + diff --git a/Game/GameEvent.h b/Game/GameEvent.h new file mode 100644 index 00000000..16d17e98 --- /dev/null +++ b/Game/GameEvent.h @@ -0,0 +1,30 @@ +#pragma once + +#include + + +using namespace std; + +/*enum GameEventType +{ + //INVALID_EVENT_TYPE = -1, + PLACE_UNIT_EVENT, + DELETE_UNITS_EVENT, + SWITCH_ANIM_EVENT, + ESC_EVENT, + PAUSE_EVENT, + TIME_CHANGE_EVENT, + NUM_EVENT_TYPES +}; + +class GameEvent: +{ +public: + GameEvent(GameEventType type ); + virtual ~GameEvent(); + + GameEventType getType() const { return mType; }; + +private: + GameEventType mType; +};*/ \ No newline at end of file diff --git a/Game/GameEventSystem.cpp b/Game/GameEventSystem.cpp new file mode 100644 index 00000000..c37fd69c --- /dev/null +++ b/Game/GameEventSystem.cpp @@ -0,0 +1,124 @@ +#include "GameEventSystem.h" +#include "GameEvent.h" +#include "Game.h" +#include + +/*GameEventSystem* GameEventSystem::mspInstance = nullptr; + +GameEventSystem::GameEventSystem() +{ + mIsInitted = true; +} + +GameEventSystem::~GameEventSystem() +{ + cleanup(); +} + +void GameEventSystem::addListener(GameEventType type, Game* pListener) +{ + if (mIsInitted) + { + mListenerMap.insert(pair< GameEventType, Game* >(type, pListener)); + } +} + +void GameEventSystem::removeListener(GameEventType type, Game* pListener) +{ + if (mIsInitted) + { + pair::iterator, multimap::iterator> ret; + + ret = mListenerMap.equal_range(type); + multimap::iterator iter; + + for (iter = ret.first; iter != ret.second; ++iter) + { + if (iter->second == pListener) + { + mListenerMap.erase(iter); + break;//to prevent using invalidated iterator + } + } + } +} + +void GameEventSystem::removeListenerFromAllEvents(Game* pListener) +{ + if (mIsInitted) + { + multimap::iterator iter; + + bool allTheWayThrough = false; + + while (!allTheWayThrough) + { + allTheWayThrough = true; + for (iter = mListenerMap.begin(); iter != mListenerMap.end(); ++iter) + { + if (iter->second == pListener) + { + mListenerMap.erase(iter); + allTheWayThrough = false; //didn't make it the whole way through + break;//to prevent using invalidated iterator + } + } + } + } +} + +GameEventSystem* GameEventSystem::getInstance() +{ + assert(mspInstance); + return mspInstance; +} + +void GameEventSystem::initInstance() +{ + assert(!mspInstance); + mspInstance = new GameEventSystem; +} + +void GameEventSystem::cleanupInstance() +{ + delete mspInstance; + mspInstance = nullptr; +} + +void GameEventSystem::init() +{ + if (mIsInitted) + { + cleanup(); + } + mIsInitted = true; +} + +void GameEventSystem::cleanup() +{ + mListenerMap.clear(); + mIsInitted = false; +} + +void GameEventSystem::fireEvent(const GameEvent& theEvent) +{ + if (mIsInitted) + { + dispatchAllEvents(theEvent); + } +} + +void GameEventSystem::dispatchAllEvents(const Event& theEvent) +{ + if (mIsInitted) + { + pair::iterator, multimap::iterator> ret; + ret = mListenerMap.equal_range(theEvent.getType()); + + multimap::iterator iter; + for (iter = ret.first; iter != ret.second; ++iter) + { + iter->second->handleEvent(theEvent); + } + } +}*/ \ No newline at end of file diff --git a/Game/GameEventSystem.h b/Game/GameEventSystem.h new file mode 100644 index 00000000..17104b2a --- /dev/null +++ b/Game/GameEventSystem.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +/* +class GameEvent; +class Game; +enum GameEventType; + +using namespace std; + +class GameEventSystem : +{ +public: + static GameEventSystem* getInstance(); + static void initInstance(); + static void cleanupInstance(); + + void init(); + void cleanup(); + + void fireEvent(const GameEvent& theEvent); + void addListener(GameEventType type, Game* pListener); + void removeListener(GameEventType type, Game* pListener); + void removeListenerFromAllEvents(Game* pListener); + + GameEventSystem(); + ~GameEventSystem(); + +private: + static GameEventSystem* mspInstance; + multimap< GameEventType, Game* > mListenerMap; + bool mIsInitted = false; + + void dispatchAllEvents(const GameEvent& theEvent); +};*/ \ No newline at end of file diff --git a/Game/GameLib.sln b/Game/GameLib.sln new file mode 100644 index 00000000..4f46e6f2 --- /dev/null +++ b/Game/GameLib.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsLib", "GraphicsLib\GraphicsLib.vcxproj", "{4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assignment2", "assignment2.vcxproj", "{EC58DA42-88DA-4B82-BFC4-AE6D5219F837}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} = {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeanLib", "..\..\..\..\common\DeanLib\DeanLib.vcxproj", "{DB900E08-5331-46D6-B450-6775A2C7C856}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|ARM.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|ARM.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.ActiveCfg = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.Build.0 = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.Build.0 = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|ARM.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.ActiveCfg = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.Build.0 = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.Build.0 = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|ARM.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.ActiveCfg = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.Build.0 = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.Build.0 = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|ARM.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x64.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x86.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x86.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|ARM.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x64.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x86.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2392FBF6-47CE-4D54-8F5B-DB78E5C9942D} + EndGlobalSection +EndGlobal diff --git a/Game/GameListener.cpp b/Game/GameListener.cpp new file mode 100644 index 00000000..5f4e3765 --- /dev/null +++ b/Game/GameListener.cpp @@ -0,0 +1,85 @@ +#include "GameListener.h" + +GameListener::GameListener() +{ +} + +GameListener::~GameListener() +{ +} + +void GameListener::init() +{ + //Establish Game listener as a listener to events + EventSystem* pEventSytem = EventSystem::getInstance(); + pEventSytem->addListener(DELETE_UNITS_EVENT, this); + pEventSytem->addListener(PLACE_UNIT_EVENT, this); + pEventSytem->addListener(PAUSE_EVENT, this); + pEventSytem->addListener(ESC_EVENT, this); + pEventSytem->addListener(SWITCH_ANIM_EVENT, this); + pEventSytem->addListener(WASD_EVENT, this); + + mpGame = Game::getInstance(); +} + +void GameListener::cleanup() +{ + EventSystem::getInstance()->removeListenerFromAllEvents(this); +} + +void GameListener::handleEvent(const Event& theEvent) +{ + //escape game + if (theEvent.getType() == 5) + { + //std::cout << "escape game" << endl; + mpGame->escape(); + mpGame->setWorldStateChanged(true); + } + //pause game + else if (theEvent.getType() == 8) + { + mpGame->pause(); + mpGame->setWorldStateChanged(true); + } + //switch animations + else if (theEvent.getType() == SWITCH_ANIM_EVENT) + { + mpGame->switchAnim(); + mpGame->setWorldStateChanged(true); + } + //place unit + else if (theEvent.getType() == 6) + { + const PlaceUnitEvent& placeUnitEvent = static_cast(theEvent); + int x = 50; + int y = 50; + + mpGame->placeUnit(placeUnitEvent.getX()); + mpGame->setWorldStateChanged(true); + // cout << "setting to true b"; + } + //delete units + else if (theEvent.getType() == 7) + { + + //std::cout << "I am deleteing a unity :)" << endl; + const DeleteUnitsEvent& deleteUnitsEvent = static_cast(theEvent); + + //erase all units in a vicinity + mpGame->deleteUnits(); + mpGame->setWorldStateChanged(true); + } + + else if (theEvent.getType() == 20) + { + const WASDEvent& moveEvent = static_cast(theEvent); + + mpGame->addUnitTranslation(moveEvent.dir.getX(), moveEvent.dir.getY()); + mpGame->setWorldStateChanged(true); + } + + + +} + diff --git a/Game/GameListener.h b/Game/GameListener.h new file mode 100644 index 00000000..200214d7 --- /dev/null +++ b/Game/GameListener.h @@ -0,0 +1,30 @@ +#pragma once + +#include "EventListener.h" +#include "EventSystem.h" +#include "Game.h" + +#include "DeleteUnitsEvent.h" +#include "PlaceUnitEvent.h" +#include "EscEvent.h" +#include "PauseEvent.h" +#include "SwitchAnimEvent.h" +#include "WASDEvent.h" + +using namespace std; + +//A listener specifically for game events +class GameListener : public EventListener +{ +public: + GameListener(); + ~GameListener(); + + void init(); + void cleanup(); + + void handleEvent(const Event& theEvent); + +private: + Game* mpGame; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/Animation.cpp b/Game/GraphicsLib/Animation.cpp new file mode 100644 index 00000000..5566d8b1 --- /dev/null +++ b/Game/GraphicsLib/Animation.cpp @@ -0,0 +1,105 @@ +#include "Animation.h" + +Animation::Animation() +{ + mUntilFrame = 0; + mLoop = false; + mCurrentSprite = 0; + mFrameTiming = 0; +} + +Animation::Animation(double time, bool loop) +{ + mUntilFrame = 0; + mFrameTiming = time; + mLoop = loop; + mCurrentSprite = 0; +} + +Animation::~Animation() +{ +} + +void Animation::addSprite(Sprite newSprite) +{ + mSpriteList.push_back(newSprite); +} + +void Animation::deleteSprite(int pos) +{ + mSpriteList.erase(mSpriteList.begin() + pos); +} + +void Animation::update(double deltaTime) +{ + if (!paused) + { + //update current frames time + mUntilFrame -= deltaTime; + + //check if need to update sprite + if (mUntilFrame <= 0) + { + //go forward one sprite + mCurrentSprite++; + + //check if need to loop or not + if ((int16_t)mCurrentSprite >= (int16_t)mSpriteList.size() - 1) + { + if (mLoop) + { + mCurrentSprite = 0; + } + else + { + mCurrentSprite = mSpriteList.size() - 1; + } + } + + //reset frame time + mUntilFrame = mFrameTiming; + } + } +} + +Sprite Animation::getCurrentSprite() +{ + return mSpriteList.at(mCurrentSprite); +} + +void Animation::speedUp(int modify) +{ + mFrameTiming -= modify; //update timing between frames + + //cap animation at -2000ms between frames + if (mFrameTiming < -2000) + { + mFrameTiming = -2000; + } +} + +void Animation::slowDown(int modify) +{ + mFrameTiming += modify; //update timing between frames + + //cap animation at 2000ms between frames + if (mFrameTiming > 2000) + { + mFrameTiming = 2000; + } +} + +void Animation::setTiming(double time) +{ + mFrameTiming = time; +} + +void Animation::setLooping(bool loop) +{ + mLoop = loop; +} + +void Animation::setPaused() +{ + paused = !paused; +} diff --git a/Game/GraphicsLib/Animation.h b/Game/GraphicsLib/Animation.h new file mode 100644 index 00000000..cee06e75 --- /dev/null +++ b/Game/GraphicsLib/Animation.h @@ -0,0 +1,41 @@ +#pragma once + +using namespace std; + +#include + +#include "Sprite.h" + + +class Animation +{ +private: + //Keeps track of sprites + vector mSpriteList; + int mCurrentSprite; + bool mLoop; + + bool paused; + + //Keeps track of speed + double mFrameTiming; + double mUntilFrame; + +public: + Animation(); + Animation(double time, bool loop); + ~Animation(); + + //Sprites + void addSprite(Sprite newSprite); + void deleteSprite(int pos); + //Updates + void update(double deltaTime); + Sprite getCurrentSprite(); + //Timing + void speedUp(int modify); + void slowDown(int modify); + void setTiming(double time); + void setLooping(bool loop); + void setPaused(); +}; \ No newline at end of file diff --git a/Game/GraphicsLib/Event.cpp b/Game/GraphicsLib/Event.cpp new file mode 100644 index 00000000..b6316149 --- /dev/null +++ b/Game/GraphicsLib/Event.cpp @@ -0,0 +1,11 @@ +#include "Event.h" + +Event::Event(EventType type) +:mType(type) +{ +} + +Event::~Event() +{ +} + diff --git a/Game/GraphicsLib/Event.h b/Game/GraphicsLib/Event.h new file mode 100644 index 00000000..33a5b397 --- /dev/null +++ b/Game/GraphicsLib/Event.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +using namespace std; + +enum EventType +{ + //Input events + MOUSE_EVENT_B, + MOUSE_MOVE_EVENT_B, + KEY_EVENT_B, + + //Game events + PLACE_UNIT_EVENT, + DELETE_UNITS_EVENT, + SWITCH_ANIM_EVENT, + ESC_EVENT, + PAUSE_EVENT, + TIME_CHANGE_EVENT, + WASD_EVENT, + + NUM_EVENT_TYPES_B +}; + +class Event +{ +public: + Event(int type); + virtual ~Event(); + + int getType() const { return mType; }; + +private: + int mType; + +}; \ No newline at end of file diff --git a/Game/GraphicsLib/EventListener.cpp b/Game/GraphicsLib/EventListener.cpp new file mode 100644 index 00000000..e5c058e7 --- /dev/null +++ b/Game/GraphicsLib/EventListener.cpp @@ -0,0 +1,11 @@ +#include "EventListener.h" +#include "EventSystem.h" + +EventListener::EventListener() +{ +} + +EventListener::~EventListener() +{ + EventSystem::getInstance()->removeListenerFromAllEvents( this ); +} diff --git a/Game/GraphicsLib/EventListener.h b/Game/GraphicsLib/EventListener.h new file mode 100644 index 00000000..a3b3edb3 --- /dev/null +++ b/Game/GraphicsLib/EventListener.h @@ -0,0 +1,17 @@ +#pragma once + + + +class Event; +class EventSystem; + +class EventListener +{ +public: + EventListener(); + virtual ~EventListener(); + + virtual void handleEvent( const Event& theEvent ) = 0; + +private: +}; \ No newline at end of file diff --git a/Game/GraphicsLib/EventSystem.cpp b/Game/GraphicsLib/EventSystem.cpp new file mode 100644 index 00000000..1519d141 --- /dev/null +++ b/Game/GraphicsLib/EventSystem.cpp @@ -0,0 +1,130 @@ +#include "EventSystem.h" +#include "Event.h" +#include "EventListener.h" +#include + +EventSystem* EventSystem::mspInstance = nullptr; + +EventSystem::EventSystem() +{ + mIsInitted = true; +} + +EventSystem::~EventSystem() +{ + cleanup(); +} + +void EventSystem::addListener(EventType type, EventListener* pListener) +{ + + if (mIsInitted) + { + //std::cout << "adding a listner " << type << endl; + mListenerMap.insert(pair< EventType, EventListener* >(type, pListener)); + } +} + +void EventSystem::removeListener(EventType type, EventListener *pListener) +{ + if (mIsInitted) + { + pair::iterator, multimap::iterator> ret; + + ret = mListenerMap.equal_range(type); + multimap::iterator iter; + + for (iter = ret.first; iter != ret.second; ++iter) + { + if (iter->second == pListener) + { + mListenerMap.erase(iter); + break;//to prevent using invalidated iterator + } + } + } +} + +void EventSystem::removeListenerFromAllEvents( EventListener* pListener ) +{ + if (mIsInitted) + { + multimap::iterator iter; + + bool allTheWayThrough = false; + + while (!allTheWayThrough) + { + allTheWayThrough = true; + for (iter = mListenerMap.begin(); iter != mListenerMap.end(); ++iter) + { + if (iter->second == pListener) + { + mListenerMap.erase(iter); + allTheWayThrough = false; //didn't make it the whole way through + break;//to prevent using invalidated iterator + } + } + } + } +} + +EventSystem* EventSystem::getInstance() +{ + assert(mspInstance); + return mspInstance; +} + +void EventSystem::initInstance() +{ + assert(!mspInstance); + mspInstance = new EventSystem; +} + +void EventSystem::cleanupInstance() +{ + delete mspInstance; + mspInstance = nullptr; +} + +void EventSystem::init() +{ + if (mIsInitted) + { + cleanup(); + } + mIsInitted = true; +} + +void EventSystem::cleanup() +{ + mListenerMap.clear(); + mIsInitted = false; +} + +void EventSystem::fireEvent( const Event& theEvent ) +{ + //std::cout << "firing event" << theEvent.getType() << endl; + + if (mIsInitted) + { + dispatchAllEvents(theEvent); + } +} + +void EventSystem::dispatchAllEvents( const Event& theEvent ) +{ + if (mIsInitted) + { + //std::cout << "dispatching event" << endl; + pair::iterator, multimap::iterator> ret; + ret = mListenerMap.equal_range(KEY_EVENT_B); + + multimap::iterator iter; + for (iter = mListenerMap.begin(); iter != mListenerMap.end(); ++iter) + { + //std::cout << "sending to listener" << endl; + iter->second->handleEvent(theEvent); + } + } +} \ No newline at end of file diff --git a/Game/GraphicsLib/EventSystem.h b/Game/GraphicsLib/EventSystem.h new file mode 100644 index 00000000..58ce491d --- /dev/null +++ b/Game/GraphicsLib/EventSystem.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +class Event; +class EventListener; +enum EventType; + +using namespace std; + +class EventSystem +{ +public: + static EventSystem* getInstance(); + static void initInstance(); + static void cleanupInstance(); + + void init(); + void cleanup(); + + void fireEvent( const Event& theEvent ); + void addListener( EventType type, EventListener* pListener ); + void removeListener( EventType type, EventListener* pListener ); + void removeListenerFromAllEvents( EventListener* pListener ); + +private: + static EventSystem* mspInstance; + multimap< EventType, EventListener* > mListenerMap; + bool mIsInitted = false; + + void dispatchAllEvents( const Event& theEvent ); + + EventSystem(); + ~EventSystem(); +}; + diff --git a/Game/GraphicsLib/Game.h b/Game/GraphicsLib/Game.h new file mode 100644 index 00000000..7d755be1 --- /dev/null +++ b/Game/GraphicsLib/Game.h @@ -0,0 +1,62 @@ +#pragma once + +#include "System.h" + +#include "Trackable.h" +#include "Timer.h" +#include "UnitManager.h" +#include "GraphicsBuffer.h" +#include "GraphicsBufferManager.h" +#include "UnitManager.h" + +//Paths +const string DIRECTORY = "..\\..\\..\\..\\common\\assets\\"; +const string WOODS_FILENAME = "Woods.png"; +const string SMURF_SPRITES_FILENAME = "smurf_sprites.png"; +const string DEAN_SPRITES_FILENAME = "dean_sprites.png"; + +//Sizes +const int SMURF_ROWS = 4; +const int SMURF_COLS = 4; +const int SMURF_SIZE = 60; + +class Game : public Trackable +{ +private: + Game(); + ~Game(); + + //Instance of game + static Game* mpsInstance; + + //Units in the game + System * mpSystem; + InputTranslator* mpInTranslator; + + //MouseX and Y + int mUserX; + int mUserY; + + //Time + Timer mTimer; + double mFrameRate; + float mSinceFrame; + + //Managers + GraphicsBufferManager* mpGManager; + UnitManager* mpUnitManager; + Animation mAnimation1; + Animation mAnimation2; + +public: + + void init(); + void cleanUp(); + void doLoop(); + void setFrameRate(double fps); + + //INSTANCE FUNCTIONS + static Game* getInstance() { return mpsInstance; } + static void initInstance(); + static void cleanUpInstance(); +}; \ No newline at end of file diff --git a/Game/GraphicsLib/GraphicsBuffer.cpp b/Game/GraphicsLib/GraphicsBuffer.cpp new file mode 100644 index 00000000..1e2657c3 --- /dev/null +++ b/Game/GraphicsLib/GraphicsBuffer.cpp @@ -0,0 +1,26 @@ +#include "GraphicsBuffer.h" + +GraphicsBuffer::GraphicsBuffer() +{ + mpBitmap = nullptr; +} + +GraphicsBuffer::GraphicsBuffer(string ASSET_PATH) +{ + mpBitmap = al_load_bitmap(ASSET_PATH.c_str()); + assert(mpBitmap); +} + +GraphicsBuffer::~GraphicsBuffer() +{ +} + +int GraphicsBuffer::getHeight() +{ + return al_get_bitmap_height(mpBitmap); +} + +int GraphicsBuffer::getWidth() +{ + return al_get_bitmap_width(mpBitmap); +} diff --git a/Game/GraphicsLib/GraphicsBuffer.h b/Game/GraphicsLib/GraphicsBuffer.h new file mode 100644 index 00000000..4f35118d --- /dev/null +++ b/Game/GraphicsLib/GraphicsBuffer.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + + +using namespace std; + +class GraphicsBuffer +{ +public: + friend class GraphicsSystem; + friend class GraphicsBufferManager; + ~GraphicsBuffer(); + +private: + ALLEGRO_BITMAP* mpBitmap; + + GraphicsBuffer(); + GraphicsBuffer(string ASSET_PATH); //Create a bitmap of an image + + int getHeight(); + int getWidth(); + +}; \ No newline at end of file diff --git a/Game/GraphicsLib/GraphicsBufferManager.cpp b/Game/GraphicsLib/GraphicsBufferManager.cpp new file mode 100644 index 00000000..e256524a --- /dev/null +++ b/Game/GraphicsLib/GraphicsBufferManager.cpp @@ -0,0 +1,67 @@ +#include "GraphicsBufferManager.h" + +GraphicsBufferManager::GraphicsBufferManager() +{ +} + +GraphicsBufferManager::~GraphicsBufferManager() +{ +} + +void GraphicsBufferManager::cleanup() +{ + clear(); +} + +void GraphicsBufferManager::addGBuffer(string key, GraphicsBuffer* newBuffer) +{ + mUMap[key] = newBuffer; +} + +void GraphicsBufferManager::addGBuffer(string key, string ASSET_PATH) +{ + mUMap[key] = new GraphicsBuffer(ASSET_PATH); +} + +void GraphicsBufferManager::deleteGBuffer(GraphicsBuffer* bufferToDelete) +{ + //run through map until buffer is found + for (auto it = mUMap.begin(); it != mUMap.end(); it++) + { + if (it->second == bufferToDelete) + { + mUMap.erase(it); + } + } +} + +void GraphicsBufferManager::deleteGBuffer(string key) +{ + mUMap.erase(key); +} + +GraphicsBuffer* GraphicsBufferManager::getGBuffer(string key) +{ + return mUMap.find(key)->second; +} + +void GraphicsBufferManager::clear() +{ + //run through map and delete all buffers + for (auto it = mUMap.begin(); it != mUMap.end(); it++) + { + delete (it->second); + } + + mUMap.clear(); +} + +int GraphicsBufferManager::getBHeight(string key) +{ + return mUMap.find(key)->second->getHeight(); +} + +int GraphicsBufferManager::getBWidth(string key) +{ + return mUMap.find(key)->second->getWidth(); +} diff --git a/Game/GraphicsLib/GraphicsBufferManager.h b/Game/GraphicsLib/GraphicsBufferManager.h new file mode 100644 index 00000000..991cfb16 --- /dev/null +++ b/Game/GraphicsLib/GraphicsBufferManager.h @@ -0,0 +1,33 @@ +#pragma once + +using namespace std; + + +#include +#include "GraphicsBuffer.h" + +class GraphicsBufferManager +{ +private: + unordered_map mUMap; + +public: + GraphicsBufferManager(); + ~GraphicsBufferManager(); + + void cleanup(); + + //ADDERS + void addGBuffer(string key, GraphicsBuffer* newBuffer); + void addGBuffer(string key,string ASSET_PATH); + + //DELETERS + void deleteGBuffer(GraphicsBuffer* bufferToDelete); + void deleteGBuffer(string key); + void clear(); + + //GETTERS + GraphicsBuffer* getGBuffer(string key); + int getBHeight(string key); + int getBWidth(string key); +}; \ No newline at end of file diff --git a/Game/GraphicsLib/GraphicsLib.sln b/Game/GraphicsLib/GraphicsLib.sln new file mode 100644 index 00000000..f5d41dbb --- /dev/null +++ b/Game/GraphicsLib/GraphicsLib.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2024 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsLib", "GraphicsLib.vcxproj", "{4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.ActiveCfg = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.Build.0 = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AB5A11A9-41DC-4165-8CEB-5563252277B6} + EndGlobalSection +EndGlobal diff --git a/Game/GraphicsLib/GraphicsLib.vcxproj b/Game/GraphicsLib/GraphicsLib.vcxproj new file mode 100644 index 00000000..dcd6d0c3 --- /dev/null +++ b/Game/GraphicsLib/GraphicsLib.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} + Win32Proj + 10.0 + + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + + + Application + true + v142 + + + Application + false + v142 + + + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)$(Configuration)\ + + + true + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + ..\DeanLib\include;GraphicsLib\;..\..\packages\Allegro.5.2.7.1\build\native\include + + + MachineX86 + true + Windows + + + + + + + + + + + + + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + MachineX86 + true + Windows + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {db900e08-5331-46d6-b450-6775a2c7c856} + + + + + + \ No newline at end of file diff --git a/Game/GraphicsLib/GraphicsSystem.cpp b/Game/GraphicsLib/GraphicsSystem.cpp new file mode 100644 index 00000000..9506d5e2 --- /dev/null +++ b/Game/GraphicsLib/GraphicsSystem.cpp @@ -0,0 +1,121 @@ +#include "GraphicsSystem.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +GraphicsSystem::GraphicsSystem() +{ + mpDisplay = nullptr; +} + +GraphicsSystem::~GraphicsSystem() +{ + cleanup(); +} + +void GraphicsSystem::init(int width, int height) +{ + //Initialize all necassary addons + + if (!al_init()) + { + cout << "error initting Allegro\n"; + } + if (!al_init_image_addon()) + { + cout << "error - Image Add-on not initted\n"; + } + if (!al_init_font_addon()) + { + cout << "error - Font Add-on not initted\n"; + } + if (!al_init_ttf_addon()) + { + cout << "error - TTF Add-on not initted\n"; + } + if (!al_init_primitives_addon()) + { + cout << "error - primitives Add-on not initted\n"; + } + if (!al_install_audio()) + { + cout << "error - Audio Add-on not initted\n"; + } + if (!al_init_acodec_addon()) + { + cout << "error - Audio Codec Add-on not initted\n"; + } + if (!al_reserve_samples(1)) + { + cout << "error - samples not reserved\n"; + } + + //create the display + mpDisplay = al_create_display(width, height); + assert(mpDisplay); +} + +void GraphicsSystem::cleanup() +{ + al_destroy_display(mpDisplay); + mpDisplay = nullptr; +} + +int GraphicsSystem::getHeight() +{ + return al_get_display_height(mpDisplay); +} + +int GraphicsSystem::getWidth() +{ + return al_get_display_width(mpDisplay); +} + +void GraphicsSystem::flip() +{ + al_flip_display(); +} + +void GraphicsSystem::draw(int x, int y, Sprite sprite, float scale) +{ + al_set_target_bitmap(al_get_backbuffer(mpDisplay)); //Set the target to the display + //Draw the scaled sprite + al_draw_scaled_bitmap(sprite.getBuffer().mpBitmap, sprite.getSouceLoc()[0], sprite.getSouceLoc()[1], sprite.getWidth(), sprite.getHeight(),x, y, sprite.getWidth() * scale, sprite.getHeight() * scale,0); +} + +void GraphicsSystem::draw(GraphicsBuffer* backBuffer, int x, int y, Sprite sprite, float scale) +{ + al_set_target_bitmap(backBuffer->mpBitmap); //Set the target to the inputed bitmap + //Draw the scaled sprite + al_draw_scaled_bitmap(sprite.getBuffer().mpBitmap, sprite.getSouceLoc()[0], sprite.getSouceLoc()[1], sprite.getWidth(), sprite.getHeight(), x, y, sprite.getWidth() * scale, sprite.getHeight() * scale, 0); +} + +void GraphicsSystem::draw(GraphicsBuffer* backBuffer, int x, int y, float scale) +{ + al_set_target_bitmap(al_get_backbuffer(mpDisplay)); //Set the target to the display + //draw that bitmap to screen at scale + al_draw_scaled_bitmap(backBuffer->mpBitmap, 0, 0, backBuffer->getWidth(), backBuffer->getHeight(), x, y, backBuffer->getWidth() * scale, backBuffer->getHeight() * scale, 0); +} + +void GraphicsSystem::saveBuffer(string filename) +{ + al_save_bitmap(filename.c_str(), al_get_backbuffer(mpDisplay)); +} + +void GraphicsSystem::saveBuffer(GraphicsBuffer* backBufferToSave, string filename) +{ + al_save_bitmap(filename.c_str(), backBufferToSave->mpBitmap); +} diff --git a/Game/GraphicsLib/GraphicsSystem.h b/Game/GraphicsLib/GraphicsSystem.h new file mode 100644 index 00000000..a54a4bec --- /dev/null +++ b/Game/GraphicsLib/GraphicsSystem.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include "Sprite.h" + + +#include + +using namespace std; + +class GraphicsSystem +{ +public: + GraphicsSystem(); + ~GraphicsSystem(); + + void init(int width, int height); //intialize all necassary addons + void cleanup(); + + int getHeight(); + int getWidth(); + + void flip(); + + void draw(int x, int y, Sprite sprite, float scale); //Draw sprite to graphics system + void draw(GraphicsBuffer* backBuffer, int x, int y, Sprite sprite, float scale); //Draw sprite to given GraphicsBuffer + void draw(GraphicsBuffer* backBuffer, int x, int y, float scale); + void saveBuffer(string filename); //Save the buffer + void saveBuffer(GraphicsBuffer* backBufferToSave, string filename); //Save the given buffer + +private: + ALLEGRO_DISPLAY* mpDisplay; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/InputSystem.cpp b/Game/GraphicsLib/InputSystem.cpp new file mode 100644 index 00000000..6703569b --- /dev/null +++ b/Game/GraphicsLib/InputSystem.cpp @@ -0,0 +1,134 @@ +#include "InputSystem.h" + +InputSystem::InputSystem() +{ + mpEventSystem = EventSystem::getInstance(); +} + +InputSystem::~InputSystem() +{ + +} + +void InputSystem::init() +{ + std::cout << "init InputSystem" << endl; + coolDown = 0; + //install allegro dependencies + if (!al_install_keyboard()) + std::cout << "keyboard install failed"; + if (!al_install_mouse()) + std::cout << "mouse install failed"; + + cout << "inited"; +} + +void InputSystem::cleanup() +{ + //uninstall allegro dependencies + al_uninstall_keyboard(); + al_uninstall_mouse(); +} + +void InputSystem::update() +{ + coolDown++; + + //std::cout << coolDown << endl; + int eee = 10; + + al_get_keyboard_state(&mKeyState);//get allegro key state + + if (al_key_down(&mKeyState, ALLEGRO_KEY_DELETE) || al_key_down(&mKeyState, ALLEGRO_KEY_BACKSPACE)) + { + //fire key event with enter click + if (coolDown > eee) + { + mpEventSystem->fireEvent(KeyEvent("enter")); + coolDown = 0; + } + //std::cout << "key event enter" << endl; + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_ESCAPE)) + { + if (coolDown > eee) + { + //fire key event with esc click + mpEventSystem->fireEvent(KeyEvent("esc")); + //std::cout << "key event esc" << endl; + coolDown = 0; + } + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_1)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("1")); + //std::cout << "key event 1" << endl; + coolDown = 0; + } + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_2)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("2")); + //std::cout << "key event 2" << endl; + coolDown = 0; + } + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_3)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("3")); + //std::cout << "key event 3" << endl; + coolDown = 0; + } + } + + else if (al_key_down(&mKeyState, ALLEGRO_KEY_W)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("W")); + //std::cout << "key event 3" << endl; + coolDown = 0; + } + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_A)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("A")); + //std::cout << "key event 3" << endl; + coolDown = 0; + } + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_S)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("S")); + //std::cout << "key event 3" << endl; + coolDown = 0; + } + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_D)) + { + if (coolDown > eee) + { + //fire key event with space click + mpEventSystem->fireEvent(KeyEvent("D")); + //std::cout << "key event 3" << endl; + coolDown = 0; + } + } + +} diff --git a/Game/GraphicsLib/InputSystem.h b/Game/GraphicsLib/InputSystem.h new file mode 100644 index 00000000..fecd5100 --- /dev/null +++ b/Game/GraphicsLib/InputSystem.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include "EventSystem.h" + +#include "KeyEvent.h" +#include "MouseEvent.h" +#include "MouseMoveEvent.h" + +using namespace std; + +class InputSystem +{ +public: + InputSystem(); + ~InputSystem(); + + void init(); + void cleanup(); + + void update(); + +private: + ALLEGRO_KEYBOARD_STATE mKeyState; + ALLEGRO_MOUSE_STATE mMouseState; + + EventSystem* mpEventSystem; + + float coolDown; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/KeyEvent.cpp b/Game/GraphicsLib/KeyEvent.cpp new file mode 100644 index 00000000..b93a5325 --- /dev/null +++ b/Game/GraphicsLib/KeyEvent.cpp @@ -0,0 +1,11 @@ +#include "KeyEvent.h" + +KeyEvent::KeyEvent(const string key) + :Event(1) + , mKey(key) +{ +} + +KeyEvent::~KeyEvent() +{ +} diff --git a/Game/GraphicsLib/KeyEvent.h b/Game/GraphicsLib/KeyEvent.h new file mode 100644 index 00000000..d99d3b7d --- /dev/null +++ b/Game/GraphicsLib/KeyEvent.h @@ -0,0 +1,15 @@ +#pragma once +#include "Event.h" +#include + +class KeyEvent : public Event +{ +public: + KeyEvent(const string key); + ~KeyEvent(); + + string getState() const { return mKey; }; + +private: + string mKey; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/LeftMouseEvent.h b/Game/GraphicsLib/LeftMouseEvent.h new file mode 100644 index 00000000..6f70f09b --- /dev/null +++ b/Game/GraphicsLib/LeftMouseEvent.h @@ -0,0 +1 @@ +#pragma once diff --git a/Game/GraphicsLib/MouseEvent.cpp b/Game/GraphicsLib/MouseEvent.cpp new file mode 100644 index 00000000..9272c9ba --- /dev/null +++ b/Game/GraphicsLib/MouseEvent.cpp @@ -0,0 +1,13 @@ +#include "MouseEvent.h" + +MouseEvent::MouseEvent(const int mouseButton, int x, int y) + :Event(0) + , mMouseButton(mouseButton) + , mX(x) + , mY(y) +{ +} + +MouseEvent::~MouseEvent() +{ +} diff --git a/Game/GraphicsLib/MouseEvent.h b/Game/GraphicsLib/MouseEvent.h new file mode 100644 index 00000000..a04694e6 --- /dev/null +++ b/Game/GraphicsLib/MouseEvent.h @@ -0,0 +1,18 @@ +#pragma once +#include "Event.h" +#include + +class MouseEvent : public Event +{ +public: + MouseEvent(const int mouseButton, int x, int y); + ~MouseEvent(); + + int getState() const { return mMouseButton; }; + int getX() const { return mX; }; + int getY() const { return mY; }; + +private: + int mMouseButton; + int mX, mY; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/MouseMoveEvent.cpp b/Game/GraphicsLib/MouseMoveEvent.cpp new file mode 100644 index 00000000..a7469998 --- /dev/null +++ b/Game/GraphicsLib/MouseMoveEvent.cpp @@ -0,0 +1,11 @@ +#include "MouseMoveEvent.h" + +MouseMoveEvent::MouseMoveEvent(const Vector2D& loc) + :Event(MOUSE_MOVE_EVENT_B) + , mLoc(loc) +{ +} + +MouseMoveEvent::~MouseMoveEvent() +{ +} diff --git a/Game/GraphicsLib/MouseMoveEvent.h b/Game/GraphicsLib/MouseMoveEvent.h new file mode 100644 index 00000000..5d9ac712 --- /dev/null +++ b/Game/GraphicsLib/MouseMoveEvent.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include "Event.h" + +class MouseMoveEvent : public Event +{ +public: + MouseMoveEvent(const Vector2D& loc); + ~MouseMoveEvent(); + + Vector2D getLocation() const { return mLoc; }; + +private: + Vector2D mLoc; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/Sprite.cpp b/Game/GraphicsLib/Sprite.cpp new file mode 100644 index 00000000..2adb350b --- /dev/null +++ b/Game/GraphicsLib/Sprite.cpp @@ -0,0 +1,38 @@ +#include "Sprite.h" + +Sprite::Sprite(GraphicsBuffer *image, vector sourceLoc, int width, int height) +{ + mpBuffer = image; + mSourceLoc = sourceLoc; + mWidth = width; + mHeight = height; +} + +Sprite::Sprite() +{ +} + + +Sprite::~Sprite() +{ +} + +vector Sprite::getSouceLoc() +{ + return mSourceLoc; +} + +int Sprite::getHeight() +{ + return mHeight; +} + +int Sprite::getWidth() +{ + return mWidth; +} + +GraphicsBuffer Sprite::getBuffer() +{ + return *mpBuffer; +} diff --git a/Game/GraphicsLib/Sprite.h b/Game/GraphicsLib/Sprite.h new file mode 100644 index 00000000..7b56fb5f --- /dev/null +++ b/Game/GraphicsLib/Sprite.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include "GraphicsBuffer.h" +#include +#include + + +using namespace std; + +class Sprite +{ +public: + Sprite(GraphicsBuffer *image, vector sourceLoc, int width, int height); + Sprite(); + ~Sprite(); + + //getters + vector getSouceLoc(); + int getHeight(); + int getWidth(); + GraphicsBuffer getBuffer(); + +private: + GraphicsBuffer* mpBuffer; + vector mSourceLoc; + int mWidth, mHeight; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/System.cpp b/Game/GraphicsLib/System.cpp new file mode 100644 index 00000000..3a231194 --- /dev/null +++ b/Game/GraphicsLib/System.cpp @@ -0,0 +1,105 @@ +#include "System.h" + +System::System() +{ + mpGraphicsSystem = nullptr; + mpISystem = nullptr; +} + +System::~System() +{ +} + +void System::init(int width, int height) +{ + //create the GSystem + mpGraphicsSystem = new GraphicsSystem(); + mpGraphicsSystem->init(width,height); + + mpISystem = new InputSystem(); + mpISystem->init(); + + //install allegro dependencies + if (!al_install_keyboard()) + std::cout << "keyboard install failed"; + if (!al_install_mouse()) + std::cout << "mouse install failed"; + +} + +void System::cleanup() +{ + //destroy GSystem + mpGraphicsSystem->cleanup(); + delete(mpGraphicsSystem); + + mpISystem->cleanup(); + delete(mpISystem); +} + +void System::update() +{ + mpISystem->update(); +} + +/* +int System::getMouseState() +{ + al_get_mouse_state(&mMouseState); + + //if right clicked, return true + if (mMouseState.buttons & 1) + { + return 1; + } + else if(mMouseState.buttons & 2) + { + return 2; + } + else + { + return 0; + } +} + +string System::getKeyState() +{ + al_get_keyboard_state(&mKeyState); + + //return the current key being pressed + if (al_key_down(&mKeyState, ALLEGRO_KEY_F)) + { + return "f"; + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_S)) + { + return "s"; + + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_ENTER)) + { + return "enter"; + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_ESCAPE)) + { + return "esc"; + } + else if (al_key_down(&mKeyState, ALLEGRO_KEY_SPACE)) + { + return "space"; + } + else + { + return " "; + } +} + +float System::getMouseX() +{ + return mMouseState.x; +} + +float System::getMouseY() +{ + return mMouseState.y; +}*/ diff --git a/Game/GraphicsLib/System.h b/Game/GraphicsLib/System.h new file mode 100644 index 00000000..b92dba80 --- /dev/null +++ b/Game/GraphicsLib/System.h @@ -0,0 +1,27 @@ +#pragma once +using namespace std; + +#include + +#include "GraphicsSystem.h" +#include "InputSystem.h" + + + +class System +{ +private: + GraphicsSystem * mpGraphicsSystem; + InputSystem* mpISystem; + +public: + System(); + ~System(); + + void init(int width, int height); + void cleanup(); + + void update(); + + friend class Game; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/Unit.cpp b/Game/GraphicsLib/Unit.cpp new file mode 100644 index 00000000..38c5a0b3 --- /dev/null +++ b/Game/GraphicsLib/Unit.cpp @@ -0,0 +1,108 @@ +#include "Unit.h" + +Unit::Unit() +{ + //Default constructor + Animation anim = Animation(); + mAnimations = vector(2, anim); + mX = 0; + mY = 0; + mCurrentAnim = 0; + mUnitID = rand() % 100001; +} + +Unit::Unit(int x, int y) +{ + //Filled constructor + Animation anim = Animation(); + mAnimations = vector(2, anim); + mX = x; + mY = y; + mCurrentAnim = 0; + mUnitID = rand() % 100001; +} + +Unit::Unit(int x, int y, Sprite newsprite) +{ + //Filled constructor + Animation anim = Animation(); + anim.addSprite(newsprite); + mAnimations = vector(2, anim); + mX = x; + mY = y; + mCurrentAnim = 0; + mUnitID = rand() % 100001; +} + +Unit::Unit(int x, int y, Sprite newsprite, int type) +{ + //Filled constructor + Animation anim = Animation(); + anim.addSprite(newsprite); + mAnimations = vector(2, anim); + mX = x; + mY = y; + mType = type; + mCurrentAnim = 0; + mUnitID = rand() % 100001; +} + +Unit::Unit(int x, int y, Sprite newsprite, int type, int uID) +{ + //Filled constructor + Animation anim = Animation(); + anim.addSprite(newsprite); + mAnimations = vector(2, anim); + mX = x; + mY = y; + mType = type; + mCurrentAnim = 0; + mUnitID = uID; +} + +Unit::Unit(int x, int y, Animation anim1, Animation anim2) +{ + Animation anim = Animation(); + mAnimations.push_back(anim1); + mAnimations.push_back(anim2); + mX = x; + mY = y; + mCurrentAnim = 0; + mUnitID = rand() % 100001; +} + +Unit::~Unit() +{ +} + +void Unit::update(double deltaTime) +{ + mAnimations.at(mCurrentAnim).update(deltaTime); +} + +void Unit::draw(GraphicsSystem * gSystem) +{ + //draw to the graphics system + gSystem->draw(mX, mY, mAnimations.at(mCurrentAnim).getCurrentSprite(), 1); +} + +void Unit::setAnimation(int newAnimation) +{ + mCurrentAnim = newAnimation; +} + +void Unit::movePos(int xVel, int yVel) +{ + mX -= xVel; + mY -= yVel; +} + +int Unit::getAnimation() +{ + return mCurrentAnim; +} + +void Unit::addAnimation(Animation anim) +{ +} + diff --git a/Game/GraphicsLib/Unit.h b/Game/GraphicsLib/Unit.h new file mode 100644 index 00000000..e51155ff --- /dev/null +++ b/Game/GraphicsLib/Unit.h @@ -0,0 +1,45 @@ +#pragma once + +using namespace std; + +#include + +#include "Animation.h" + +#include "GraphicsSystem.h" + +class Unit +{ +private: + //current state of unit + + //All animations + //Sprite sprite; + vector mAnimations; + + Unit(); + Unit(int x, int y); + Unit(int x, int y, Sprite newsprite); + Unit(int x, int y, Sprite newsprite, int type); + Unit(int x, int y, Sprite newsprite, int type, int uID); + Unit(int x, int y, Animation anim1, Animation anim2); + ~Unit(); + + //State changes + void update(double deltaTime); + void draw(GraphicsSystem* gSystem); + void setAnimation(int newAnimation); + void movePos(int xVel, int yVel); + + //Get current animation + int getAnimation(); + + void addAnimation(Animation anim); + +public: + int mType; + int mX, mY = 0; + int mCurrentAnim; + int mUnitID; + friend class UnitManager; +}; \ No newline at end of file diff --git a/Game/GraphicsLib/UnitManager.cpp b/Game/GraphicsLib/UnitManager.cpp new file mode 100644 index 00000000..e3257614 --- /dev/null +++ b/Game/GraphicsLib/UnitManager.cpp @@ -0,0 +1,342 @@ +#include "UnitManager.h" +#include "UnitManager.h" + +UnitManager::UnitManager() +{ + mCurrentlyPaused = false; +} + +UnitManager::~UnitManager() +{ + //clear(); +} + +void UnitManager::cleanup() +{ + clear(); +} + +//ADDERS +void UnitManager::addUnit(Unit* newUnit) +{ + mUnits.push_back(newUnit); +} + +void UnitManager::addUnit() +{ + mUnits.push_back(new Unit()); +} + +void UnitManager::addUnit(int x, int y) +{ + mUnits.push_back(new Unit(x, y)); +} + +void UnitManager::addUnit(int x, int y, Sprite sprite) +{ + mUnits.push_back(new Unit(x, y, sprite)); +} + +void UnitManager::addUnit(int x, int y, Sprite sprite, int type) +{ + mUnits.push_back(new Unit(x, y, sprite, type)); +} + +void UnitManager::addUnit(int x, int y, Sprite sprite, int type, int uID) +{ + mUnits.push_back(new Unit(x, y, sprite, type, uID)); +} + +void UnitManager::addUnit(int x, int y, Animation anim1, Animation anim2) +{ + mUnits.push_back(new Unit(x, y, anim1, anim2)); +} + + +//DELETES +void UnitManager::deleteUnit(int unitLoc) +{ + delete(mUnits[unitLoc]); + mUnits.erase(mUnits.begin() + unitLoc); +} + +void UnitManager::deleteAllUnits() +{ + while (mUnits.size() > 1) + { + deleteUnit(1); + } + + //addUnit(-1000, -1000); +} + +void UnitManager::deleteRandomUnit() +{ + if (mUnits.size() > 0) + { + int loc = rand() % (mUnits.size() - 1) + 1; + deletedUnits.push_back(mUnits[loc]->mUnitID); + deleteUnit(loc); + } +} + +void UnitManager::deleteUnit(Unit* delUnit) +{ + cout << "got to delting in UM \n"; + int counter = 0; + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + if ((*it) == delUnit) + { + deleteUnit(counter); + } + + counter++; + } + + cout << "finished deleting in UM \n"; +} + +void UnitManager::deleteUnitID(int id) +{ + //cout << "got to delting in UM \n"; + for (int i = 0; i < mUnits.size(); i++) + { + if (mUnits[i]->mUnitID = id) + { + deleteUnit(i); + return; + } + } + //cout << "finished deleting in UM \n"; + +} + +void UnitManager::erase(int mouseX, int mouseY, const int UNIT_WIDTH, const int UNIT_HEIGHT) +{ + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + //check if unit is in range of mouse + if (((*it)->mX >= mouseX -( UNIT_WIDTH / 2) && (*it)->mX <= mouseX + (UNIT_WIDTH / 2)) && ((*it)->mY >= mouseY - (UNIT_HEIGHT / 2) && (*it)->mY <= mouseY + (UNIT_HEIGHT / 2))) + { + if (it != mUnits.begin()) + { + delete (*it); //delete unit + mUnits.erase(it--); //erase unit one position behind, which is the current units actual location in the vector? + } + else + { + delete (*mUnits.begin()); + mUnits.erase(mUnits.begin()); + } + } + } +} + +//GETTERS +Unit* UnitManager::getUnit(int unitLoc) +{ + return mUnits.at(unitLoc); +} + +Unit* UnitManager::getLastUnit() +{ + return mUnits.back(); +} + +Unit* UnitManager::getUnitWithID(int id) +{ + for (int i = 0; i < mUnits.size(); i++) + { + if (mUnits[i]->mUnitID == id) + { + return(mUnits[i]); + } + } + return nullptr; +} + +//ANIMATION SETTERS +void UnitManager::setUnitAnim(Unit* unit, int anim) +{ + unit->setAnimation(anim); +} + +void UnitManager::setUnitAnim(int unitLoc, int anim) +{ + mUnits.at(unitLoc)->setAnimation(anim); +} + +void UnitManager::setUnitAnim(int anim) +{ + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + (*it)->setAnimation(anim); + } +} + +//ANIMATION ADDERS +void UnitManager::addUnitAnim(Animation anim) +{ + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + (*it)->addAnimation(anim); + } +} + +void UnitManager::addUnitAnim(Animation anim, Unit* unit) +{ + unit->addAnimation(anim); +} + +void UnitManager::addUnitAnim(Animation anim, int unitLoc) +{ + mUnits.at(unitLoc)->addAnimation(anim); +} + +//ANIMATION GETTERS +int UnitManager::getUnitAnim(int unitLoc) +{ + return mUnits.at(unitLoc)->getAnimation(); +} + +int UnitManager::getUnitAnim(Unit* unit) +{ + return unit->getAnimation(); +} + +//PAUSERS +void UnitManager::pauseAnim() +{ + //run through all units and pause them + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + for (auto at = (*it)->mAnimations.begin(); at != (*it)->mAnimations.end(); at++) //do all animations + { + (*at).setPaused(); + } + } + mCurrentlyPaused = !mCurrentlyPaused; +} + +void UnitManager::pauseAnim(int unitLoc) +{ + //pause a unit at location + for (auto at = mUnits.at(unitLoc)->mAnimations.begin(); at != mUnits.at(unitLoc)->mAnimations.end(); at++) //do all animations + { + (*at).setPaused(); + } +} + +void UnitManager::pauseAnim(Unit* unit) +{ + //pause a set unit + for (auto at = unit->mAnimations.begin(); at != unit->mAnimations.end(); at++) //do all animations + { + (*at).setPaused(); + } +} + +bool UnitManager::isPaused() +{ + return mCurrentlyPaused; +} + +//DELETE ALL UNITS +void UnitManager::clear() +{ + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + delete (*it); + } + + mUnits.clear(); +} + +//UPDATE ALL UNITS +void UnitManager::update(double deltaTime) +{ + //run through all units and call their update function + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + (*it)->update(deltaTime); + } +} + +//DRAW ALL UNITS +void UnitManager::draw(GraphicsSystem* gSystem) +{ + //run through all units and call their draw function + for (auto it = mUnits.begin(); it != mUnits.end(); it++) + { + (*it)->draw(gSystem); + } +} + +void UnitManager::updatePositions(int xVel, int yVel) +{ + for (int i = 0; i < mUnits.size(); i++) + { + mUnits[i]->movePos(xVel, yVel); + } +} + +vector> UnitManager::getAllUnitsLocation() +{ + vector> locs; + + //cout << "BIG WHOOP" << endl; + + for (int i = 0; i < mUnits.size(); i++) + { + Unit newUnit = *getUnit(i); + vector loc = vector(); + loc.push_back(newUnit.mUnitID); + loc.push_back(newUnit.mType); + loc.push_back(newUnit.mX); + loc.push_back(newUnit.mY); + locs.push_back(loc); + //loc[i] = Vector2D( getUnit(i)->mX, getUnit(i)->mY ); + } + + /* + for (int i = 0; i < locs.size(); i++) + { + cout << "new Loc " << locs[i][0] << " " << locs[i][1] << " " << locs[i][2] << endl; + } + */ + + return locs; +} + +vector UnitManager::getDeletedUnits() +{ + vector temp = deletedUnits; + deletedUnits.clear(); + return temp; +} + +int* UnitManager::getAllUnitsTypes() +{ + int* types = new int[mUnits.size()]; + for (int i = 0; i < mUnits.size(); i++) + { + types[i] = getUnit(i)->mType; + } + return types; +} + +Unit* UnitManager::getAllUnits() +{ + Unit* units = new Unit[mUnits.size()]; + for (int i = 0; i < mUnits.size(); i++) + { + units[i] = *getUnit(i); + } + return units; +} + +int UnitManager::getUnitCount() +{ + return mUnits.size(); +} diff --git a/Game/GraphicsLib/UnitManager.h b/Game/GraphicsLib/UnitManager.h new file mode 100644 index 00000000..97d6555b --- /dev/null +++ b/Game/GraphicsLib/UnitManager.h @@ -0,0 +1,77 @@ +#pragma once + +using namespace std; + + +#include +#include "Vector2D.h" +#include "Unit.h" +#include "Animation.h" + +class UnitManager +{ +private: + vector mUnits; + vector deletedUnits; + bool mCurrentlyPaused; + +public: + UnitManager(); + ~UnitManager(); + + void cleanup(); + + //ADD UNIT + void addUnit(Unit* newUnit); + void addUnit(); + void addUnit(int x, int y); + void addUnit(int x, int y, Sprite sprite); + void addUnit(int x, int y, Sprite sprite, int type); + void addUnit(int x, int y, Sprite sprite, int type, int uID); + void addUnit(int x, int y, Animation anim1, Animation anim2); + + //DELETE UNIT + void deleteUnit(int unitLoc); + void deleteAllUnits(); + void deleteRandomUnit(); + void deleteUnit(Unit* delUnit); + void deleteUnitID(int id); + void erase(int mouseX, int mouseY, const int UNIT_WIDTH, const int UNIT_HEIGHT); + void clear(); + + //GET UNIT + Unit* getUnit(int unitLoc); + Unit* getLastUnit(); + Unit* getUnitWithID(int id); + + //SET ANIMATIONS + void setUnitAnim(Unit* unit, int anim); + void setUnitAnim(int unitLoc, int anim); + void setUnitAnim(int anim); + + //ADD ANIMATIONS + void addUnitAnim(Animation anim); + void addUnitAnim(Animation anim, Unit* unit); + void addUnitAnim(Animation anim, int unitLoc); + + //GET ANIMATIONS + int getUnitAnim(int unitLoc); + int getUnitAnim(Unit* unit); + + //PAUSE ANIMATIONS + void pauseAnim(); + void pauseAnim(int unitLoc); + void pauseAnim(Unit* unit); + bool isPaused(); + + //GAME FUNCTIONS + void update(double deltaTime); + void draw(GraphicsSystem* gSystem); + void updatePositions(int xVel, int yVel); + + vector> getAllUnitsLocation(); + vector getDeletedUnits(); + int* getAllUnitsTypes(); + Unit* getAllUnits(); + int getUnitCount(); +}; \ No newline at end of file diff --git a/Game/GraphicsLib/x64/Debug/GraphicsLib.log b/Game/GraphicsLib/x64/Debug/GraphicsLib.log new file mode 100644 index 00000000..61d48ba8 --- /dev/null +++ b/Game/GraphicsLib/x64/Debug/GraphicsLib.log @@ -0,0 +1,29 @@ + Event.cpp + Animation.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\Sprite.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + EventListener.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\EventListener.h(3,10): fatal error C1083: Cannot open include file: 'Trackable.h': No such file or directory + EventSystem.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\EventListener.h(3,10): fatal error C1083: Cannot open include file: 'Trackable.h': No such file or directory + GraphicsBuffer.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\GraphicsBuffer.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + GraphicsBufferManager.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\GraphicsBufferManager.h(5,10): fatal error C1083: Cannot open include file: 'Trackable.h': No such file or directory + GraphicsSystem.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\GraphicsSystem.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + InputSystem.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\InputSystem.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + KeyEvent.cpp + MouseEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\MouseEvent.h(3,10): fatal error C1083: Cannot open include file: 'Vector2D.h': No such file or directory + MouseMoveEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\MouseMoveEvent.h(3,10): fatal error C1083: Cannot open include file: 'Vector2D.h': No such file or directory + Sprite.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\Sprite.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + System.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\GraphicsSystem.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + Unit.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\Sprite.h(3,10): fatal error C1083: Cannot open include file: 'allegro5/allegro.h': No such file or directory + UnitManager.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GraphicsLib\UnitManager.h(5,10): fatal error C1083: Cannot open include file: 'Trackable.h': No such file or directory + Generating Code... diff --git a/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.command.1.tlog b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.command.1.tlog new file mode 100644 index 00000000..87d7ae73 Binary files /dev/null and b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.command.1.tlog differ diff --git a/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.read.1.tlog b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.read.1.tlog new file mode 100644 index 00000000..29e3b951 Binary files /dev/null and b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.read.1.tlog differ diff --git a/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.write.1.tlog b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.write.1.tlog new file mode 100644 index 00000000..d718be06 Binary files /dev/null and b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/CL.write.1.tlog differ diff --git a/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/GraphicsLib.lastbuildstate b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/GraphicsLib.lastbuildstate new file mode 100644 index 00000000..b037df16 --- /dev/null +++ b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/GraphicsLib.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v142:VCToolArchitecture=Native64Bit:VCToolsVersion=14.29.30133:VCServicingVersionCrtHeaders=14.29.30136:TargetPlatformVersion=10.0.19041.0: +Debug|x64|C:\Users\Gavin\source\repos\SocketDemo\| diff --git a/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/unsuccessfulbuild b/Game/GraphicsLib/x64/Debug/GraphicsLib.tlog/unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/Game/GraphicsLib/x64/Debug/vc142.idb b/Game/GraphicsLib/x64/Debug/vc142.idb new file mode 100644 index 00000000..b9927feb Binary files /dev/null and b/Game/GraphicsLib/x64/Debug/vc142.idb differ diff --git a/Game/InputTranslator.cpp b/Game/InputTranslator.cpp new file mode 100644 index 00000000..f7c1b9e3 --- /dev/null +++ b/Game/InputTranslator.cpp @@ -0,0 +1,104 @@ +#include "InputTranslator.h" +#include "Event.h" +#include "MouseEvent.h" +#include "KeyEvent.h" + + +InputTranslator::InputTranslator() +{ + mpESystem = EventSystem::getInstance(); + //mpESystem->addListener(MOUSE_EVENT_B, this); + mpESystem->addListener(KEY_EVENT_B, this); +} + +InputTranslator::~InputTranslator() +{ +} + +void InputTranslator::init() +{ +} + +void InputTranslator::cleanup() +{ + EventSystem::getInstance()->removeListenerFromAllEvents(this); +} + +void InputTranslator::handleEvent(const Event& theEvent) +{ + //std::cout << "handeling an event :)" << theEvent.getType() << " " << MOUSE_EVENT_B << endl; + //Check for mouse Event + //if (theEvent.getType() == MOUSE_EVENT_B) + //{ + /* + const MouseEvent& mouseEvent = static_cast(theEvent); + if (mouseEvent.getState() == 1) + { + //fire place unit game event + mpESystem->fireEvent(PlaceUnitEvent(mouseEvent.getX(),mouseEvent.getY())); + } + else if (mouseEvent.getState() == 2) + { + //fire delete unit game event + mpESystem->fireEvent(DeleteUnitsEvent(mouseEvent.getX(), mouseEvent.getY())); + } + */ + //} + //Check for keyboard event + if (theEvent.getType() == 1) + { + const KeyEvent& keyEvent = static_cast(theEvent); + if (keyEvent.getState() == "space") + { + //fire pause game event + mpESystem->fireEvent(PauseEvent()); + } + else if (keyEvent.getState() == "enter") + { + //fire switch animation event + mpESystem->fireEvent(DeleteUnitsEvent()); + } + else if (keyEvent.getState() == "esc") + { + //std::cout << "handeling an event for escape" << endl; + //fire exit game event + mpESystem->fireEvent(EscEvent()); + } + else if (keyEvent.getState() == "1") + { + //std::cout << "handeling an event for button 1" << endl; + //fire exit game event + mpESystem->fireEvent(PlaceUnitEvent(1)); + } + else if (keyEvent.getState() == "2") + { + //std::cout << "handeling an event for button 2" << endl; + //fire exit game event + mpESystem->fireEvent(PlaceUnitEvent(2)); + } + else if (keyEvent.getState() == "3") + { + //std::cout << "handeling an event for button 3" << endl; + //fire exit game event + mpESystem->fireEvent(PlaceUnitEvent(3)); + } + + else if (keyEvent.getState() == "W") + { + mpESystem->fireEvent(WASDEvent(Vector2D(0, 1))); + } + else if (keyEvent.getState() == "A") + { + mpESystem->fireEvent(WASDEvent(Vector2D(-1, 0))); + } + else if (keyEvent.getState() == "S") + { + mpESystem->fireEvent(WASDEvent(Vector2D(0, -1))); + } + else if (keyEvent.getState() == "D") + { + mpESystem->fireEvent(WASDEvent(Vector2D(1, 0))); + } + + } +} diff --git a/Game/InputTranslator.h b/Game/InputTranslator.h new file mode 100644 index 00000000..dfc14e81 --- /dev/null +++ b/Game/InputTranslator.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "EventListener.h" +#include "EventSystem.h" + +#include "DeleteUnitsEvent.h" +#include "PlaceUnitEvent.h" +#include "EscEvent.h" +#include "PauseEvent.h" +#include "SwitchAnimEvent.h" +#include "KeyEvent.h" +#include "MouseEvent.h" +#include "WASDEvent.h" + +using namespace std; + +class InputTranslator : public EventListener +{ +public: + InputTranslator(); + ~InputTranslator(); + + void init(); + void cleanup(); + + void handleEvent(const Event& theEvent); + +private: + EventSystem* mpESystem; +}; \ No newline at end of file diff --git a/Game/PauseEvent.cpp b/Game/PauseEvent.cpp new file mode 100644 index 00000000..4c9e7a5a --- /dev/null +++ b/Game/PauseEvent.cpp @@ -0,0 +1,10 @@ +#include "PauseEvent.h" + +PauseEvent::PauseEvent() + :Event(8) +{ +} + +PauseEvent::~PauseEvent() +{ +} diff --git a/Game/PauseEvent.h b/Game/PauseEvent.h new file mode 100644 index 00000000..5a9fc092 --- /dev/null +++ b/Game/PauseEvent.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Event.h" + +class PauseEvent : public Event +{ +public: + PauseEvent(); + ~PauseEvent(); +}; \ No newline at end of file diff --git a/Game/PlaceUnitEvent.cpp b/Game/PlaceUnitEvent.cpp new file mode 100644 index 00000000..475868bf --- /dev/null +++ b/Game/PlaceUnitEvent.cpp @@ -0,0 +1,11 @@ +#include "PlaceUnitEvent.h" + +PlaceUnitEvent::PlaceUnitEvent(int num) + :Event(6) + , type(num) +{ +} + +PlaceUnitEvent::~PlaceUnitEvent() +{ +} diff --git a/Game/PlaceUnitEvent.h b/Game/PlaceUnitEvent.h new file mode 100644 index 00000000..1e47ee3d --- /dev/null +++ b/Game/PlaceUnitEvent.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "Event.h" + +class PlaceUnitEvent : public Event +{ +public: +public: + PlaceUnitEvent(int num); + ~PlaceUnitEvent(); + + int getX() const { return type; }; + int getY() const { return mY; }; + +private: + int mX, mY, type; +}; \ No newline at end of file diff --git a/Game/SwitchAnimEvent.cpp b/Game/SwitchAnimEvent.cpp new file mode 100644 index 00000000..f26d7976 --- /dev/null +++ b/Game/SwitchAnimEvent.cpp @@ -0,0 +1,10 @@ +#include "SwitchAnimEvent.h" + +SwitchAnimEvent::SwitchAnimEvent() + :Event(SWITCH_ANIM_EVENT) +{ +} + +SwitchAnimEvent::~SwitchAnimEvent() +{ +} diff --git a/Game/SwitchAnimEvent.h b/Game/SwitchAnimEvent.h new file mode 100644 index 00000000..4a8248db --- /dev/null +++ b/Game/SwitchAnimEvent.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Event.h" + +class SwitchAnimEvent : public Event +{ +public: + SwitchAnimEvent(); + ~SwitchAnimEvent(); +}; \ No newline at end of file diff --git a/Game/WASDEvent.cpp b/Game/WASDEvent.cpp new file mode 100644 index 00000000..3ca0f908 --- /dev/null +++ b/Game/WASDEvent.cpp @@ -0,0 +1,11 @@ +#include "WASDEvent.h" + +WASDEvent::WASDEvent(Vector2D newDir) + :Event(20) + , dir(newDir) +{ +} + +WASDEvent::~WASDEvent() +{ +} diff --git a/Game/WASDEvent.h b/Game/WASDEvent.h new file mode 100644 index 00000000..f639835b --- /dev/null +++ b/Game/WASDEvent.h @@ -0,0 +1,13 @@ +#pragma once +#include "Event.h" +#include +class WASDEvent : + public Event +{ + public: + WASDEvent(Vector2D newDir); + ~WASDEvent(); + + Vector2D dir; +}; + diff --git a/Game/assets/Mayor_Quimby.png b/Game/assets/Mayor_Quimby.png new file mode 100644 index 00000000..dc96c61e Binary files /dev/null and b/Game/assets/Mayor_Quimby.png differ diff --git a/Game/assets/Woods.png b/Game/assets/Woods.png new file mode 100644 index 00000000..8cf6c786 Binary files /dev/null and b/Game/assets/Woods.png differ diff --git a/Game/assets/axamer-lizum.png b/Game/assets/axamer-lizum.png new file mode 100644 index 00000000..47a000bb Binary files /dev/null and b/Game/assets/axamer-lizum.png differ diff --git a/Game/assets/clapping.wav b/Game/assets/clapping.wav new file mode 100644 index 00000000..84c2031f Binary files /dev/null and b/Game/assets/clapping.wav differ diff --git a/Game/assets/cour.ttf b/Game/assets/cour.ttf new file mode 100644 index 00000000..2c99e08c Binary files /dev/null and b/Game/assets/cour.ttf differ diff --git a/Game/assets/dean_sprites.png b/Game/assets/dean_sprites.png new file mode 100644 index 00000000..45850b65 Binary files /dev/null and b/Game/assets/dean_sprites.png differ diff --git a/Game/assets/glowing-balls.png b/Game/assets/glowing-balls.png new file mode 100644 index 00000000..1dcf352d Binary files /dev/null and b/Game/assets/glowing-balls.png differ diff --git a/Game/assets/imp.png b/Game/assets/imp.png new file mode 100644 index 00000000..4dbbfa79 Binary files /dev/null and b/Game/assets/imp.png differ diff --git a/Game/assets/smurf_sprites.png b/Game/assets/smurf_sprites.png new file mode 100644 index 00000000..ba64e4c7 Binary files /dev/null and b/Game/assets/smurf_sprites.png differ diff --git a/Game/assets/smurf_sprites_numbered.png b/Game/assets/smurf_sprites_numbered.png new file mode 100644 index 00000000..353d6f89 Binary files /dev/null and b/Game/assets/smurf_sprites_numbered.png differ diff --git a/Game/assets/sprites.png b/Game/assets/sprites.png new file mode 100644 index 00000000..f1fe1d97 Binary files /dev/null and b/Game/assets/sprites.png differ diff --git a/Game/assets/steps.png b/Game/assets/steps.png new file mode 100644 index 00000000..3f93af58 Binary files /dev/null and b/Game/assets/steps.png differ diff --git a/Game/assignment2.vcxproj b/Game/assignment2.vcxproj new file mode 100644 index 00000000..ea9ba764 --- /dev/null +++ b/Game/assignment2.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837} + assignment1 + 10.0 + GameLib + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + true + true + true + true + + + + Level3 + Disabled + true + DeanLib\include;GraphicsLib\;..\packages\Allegro.5.2.7.1\build\native\include + + + GraphicsLib\debug;deanlib\lib;..\packages\Allegro.5.2.7.1\build\native\v142\win32\lib + allegro.lib;allegro_font.lib;allegro_ttf.lib;allegro_audio.lib;allegro_acodec.lib;allegro_image.lib;allegro_primitives.lib;GraphicsLib.lib;DeanLibDebug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + true + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + {db900e08-5331-46d6-b450-6775a2c7c856} + + + {4b9ab2da-44cb-4f3d-866f-fa7f345bd810} + + + + + + + + + + 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/Game/lawson/Event System/Debug/EventSystem.ilk b/Game/lawson/Event System/Debug/EventSystem.ilk new file mode 100644 index 00000000..32081d9d Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.ilk differ diff --git a/Game/lawson/Event System/Debug/EventSystem.log b/Game/lawson/Event System/Debug/EventSystem.log new file mode 100644 index 00000000..666122b3 --- /dev/null +++ b/Game/lawson/Event System/Debug/EventSystem.log @@ -0,0 +1,10 @@ + Event.cpp + EventListener.cpp + EventSystem.cpp + main.cpp + MoveEvent.cpp + ExampleListener.cpp + SoundSystem.cpp + StringEvent.cpp + Generating Code... + EventSystem.vcxproj -> C:\Users\Evan\source\repos\sp20-gpr250\common\lawson\Event System\Debug\EventSystem.exe diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/CL.command.1.tlog b/Game/lawson/Event System/Debug/EventSystem.tlog/CL.command.1.tlog new file mode 100644 index 00000000..584a1444 Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.tlog/CL.command.1.tlog differ diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/CL.read.1.tlog b/Game/lawson/Event System/Debug/EventSystem.tlog/CL.read.1.tlog new file mode 100644 index 00000000..d3800d95 Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.tlog/CL.read.1.tlog differ diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/CL.write.1.tlog b/Game/lawson/Event System/Debug/EventSystem.tlog/CL.write.1.tlog new file mode 100644 index 00000000..a53f05b0 Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.tlog/CL.write.1.tlog differ diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/EventSystem.lastbuildstate b/Game/lawson/Event System/Debug/EventSystem.tlog/EventSystem.lastbuildstate new file mode 100644 index 00000000..986eb08e --- /dev/null +++ b/Game/lawson/Event System/Debug/EventSystem.tlog/EventSystem.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v142:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0 +Debug|Win32|C:\Users\Evan\source\repos\sp20-gpr250\common\lawson\Event System\| diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/link.command.1.tlog b/Game/lawson/Event System/Debug/EventSystem.tlog/link.command.1.tlog new file mode 100644 index 00000000..091aee80 Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.tlog/link.command.1.tlog differ diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/link.read.1.tlog b/Game/lawson/Event System/Debug/EventSystem.tlog/link.read.1.tlog new file mode 100644 index 00000000..92f08a75 Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.tlog/link.read.1.tlog differ diff --git a/Game/lawson/Event System/Debug/EventSystem.tlog/link.write.1.tlog b/Game/lawson/Event System/Debug/EventSystem.tlog/link.write.1.tlog new file mode 100644 index 00000000..8e179a3b Binary files /dev/null and b/Game/lawson/Event System/Debug/EventSystem.tlog/link.write.1.tlog differ diff --git a/Game/lawson/Event System/Debug/vc142.idb b/Game/lawson/Event System/Debug/vc142.idb new file mode 100644 index 00000000..6d8a07e9 Binary files /dev/null and b/Game/lawson/Event System/Debug/vc142.idb differ diff --git a/Game/lawson/Event System/Event.cpp b/Game/lawson/Event System/Event.cpp new file mode 100644 index 00000000..5f0eb7f6 --- /dev/null +++ b/Game/lawson/Event System/Event.cpp @@ -0,0 +1,17 @@ +//#include "Event.h" +#include "..\..\GraphicsLib\Event.h" +//#include "..\..\GraphicsLib\Event.h" +//#include "..\..\GraphicsLib\Event.h" + + +Event::Event(int type) +{ + mType = type; +} + +Event::~Event() +{ +} + + + diff --git a/Game/lawson/Event System/Event.h b/Game/lawson/Event System/Event.h new file mode 100644 index 00000000..03ba5683 --- /dev/null +++ b/Game/lawson/Event System/Event.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +using namespace std; + +enum EventType +{ + INVALID_EVENT_TYPE = -1, + MOVE_EVENT, + MESSAGE_EVENT, + NUM_EVENT_TYPES +}; + +class Event:public Trackable +{ +public: + Event( EventType type ); + virtual ~Event(); + + EventType getType() const { return mType; }; + +private: + EventType mType; + +}; \ No newline at end of file diff --git a/Game/lawson/Event System/EventListener.cpp b/Game/lawson/Event System/EventListener.cpp new file mode 100644 index 00000000..e5c058e7 --- /dev/null +++ b/Game/lawson/Event System/EventListener.cpp @@ -0,0 +1,11 @@ +#include "EventListener.h" +#include "EventSystem.h" + +EventListener::EventListener() +{ +} + +EventListener::~EventListener() +{ + EventSystem::getInstance()->removeListenerFromAllEvents( this ); +} diff --git a/Game/lawson/Event System/EventListener.h b/Game/lawson/Event System/EventListener.h new file mode 100644 index 00000000..21eb7383 --- /dev/null +++ b/Game/lawson/Event System/EventListener.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +class Event; +class EventSystem; + +class EventListener:public Trackable +{ +public: + EventListener(); + virtual ~EventListener(); + + virtual void handleEvent( const Event& theEvent ) = 0; + +private: +}; \ No newline at end of file diff --git a/Game/lawson/Event System/EventSystem.cpp b/Game/lawson/Event System/EventSystem.cpp new file mode 100644 index 00000000..0f22f773 --- /dev/null +++ b/Game/lawson/Event System/EventSystem.cpp @@ -0,0 +1,123 @@ +#include "EventSystem.h" +#include "Event.h" +#include "EventListener.h" +#include + +EventSystem* EventSystem::mspInstance = nullptr; + +EventSystem::EventSystem() +{ +} + +EventSystem::~EventSystem() +{ + cleanup(); +} + +void EventSystem::addListener(EventType type, EventListener* pListener) +{ + if (mIsInitted) + { + mListenerMap.insert(pair< EventType, EventListener* >(type, pListener)); + } +} + +void EventSystem::removeListener(EventType type, EventListener *pListener) +{ + if (mIsInitted) + { + pair::iterator, multimap::iterator> ret; + + ret = mListenerMap.equal_range(type); + multimap::iterator iter; + + for (iter = ret.first; iter != ret.second; ++iter) + { + if (iter->second == pListener) + { + mListenerMap.erase(iter); + break;//to prevent using invalidated iterator + } + } + } +} + +void EventSystem::removeListenerFromAllEvents( EventListener* pListener ) +{ + if (mIsInitted) + { + multimap::iterator iter; + + bool allTheWayThrough = false; + + while (!allTheWayThrough) + { + allTheWayThrough = true; + for (iter = mListenerMap.begin(); iter != mListenerMap.end(); ++iter) + { + if (iter->second == pListener) + { + mListenerMap.erase(iter); + allTheWayThrough = false; //didn't make it the whole way through + break;//to prevent using invalidated iterator + } + } + } + } +} + +EventSystem* EventSystem::getInstance() +{ + assert(mspInstance); + return mspInstance; +} + +void EventSystem::initInstance() +{ + assert(!mspInstance); + mspInstance = new EventSystem; +} + +void EventSystem::cleanupInstance() +{ + delete mspInstance; + mspInstance = nullptr; +} + +void EventSystem::init() +{ + if (mIsInitted) + { + cleanup(); + } + mIsInitted = true; +} + +void EventSystem::cleanup() +{ + mListenerMap.clear(); + mIsInitted = false; +} + +void EventSystem::fireEvent( const Event& theEvent ) +{ + if (mIsInitted) + { + dispatchAllEvents(theEvent); + } +} + +void EventSystem::dispatchAllEvents( const Event& theEvent ) +{ + if (mIsInitted) + { + pair::iterator, multimap::iterator> ret; + ret = mListenerMap.equal_range(theEvent.getType()); + + multimap::iterator iter; + for (iter = ret.first; iter != ret.second; ++iter) + { + iter->second->handleEvent(theEvent); + } + } +} \ No newline at end of file diff --git a/Game/lawson/Event System/EventSystem.h b/Game/lawson/Event System/EventSystem.h new file mode 100644 index 00000000..7782d2ee --- /dev/null +++ b/Game/lawson/Event System/EventSystem.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +class Event; +class EventListener; +enum EventType; + +using namespace std; + +class EventSystem:public Trackable +{ +public: + static EventSystem* getInstance(); + static void initInstance(); + static void cleanupInstance(); + + void init(); + void cleanup(); + + void fireEvent( const Event& theEvent ); + void addListener( EventType type, EventListener* pListener ); + void removeListener( EventType type, EventListener* pListener ); + void removeListenerFromAllEvents( EventListener* pListener ); + +private: + static EventSystem* mspInstance; + multimap< EventType, EventListener* > mListenerMap; + bool mIsInitted = false; + + void dispatchAllEvents( const Event& theEvent ); + + EventSystem(); + ~EventSystem(); + + +}; + diff --git a/Game/lawson/Event System/EventSystem.sln b/Game/lawson/Event System/EventSystem.sln new file mode 100644 index 00000000..1d18177c --- /dev/null +++ b/Game/lawson/Event System/EventSystem.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2027 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EventSystem", "EventSystem.vcxproj", "{4B602022-E8DA-41DB-B4B6-A43B8DB5041D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B602022-E8DA-41DB-B4B6-A43B8DB5041D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4B602022-E8DA-41DB-B4B6-A43B8DB5041D}.Debug|Win32.Build.0 = Debug|Win32 + {4B602022-E8DA-41DB-B4B6-A43B8DB5041D}.Release|Win32.ActiveCfg = Release|Win32 + {4B602022-E8DA-41DB-B4B6-A43B8DB5041D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {87B9D9D5-ECBE-4F19-BB0D-903949EA5AFE} + EndGlobalSection +EndGlobal diff --git a/Game/lawson/Event System/EventSystem.vcxproj b/Game/lawson/Event System/EventSystem.vcxproj new file mode 100644 index 00000000..e6320b4d --- /dev/null +++ b/Game/lawson/Event System/EventSystem.vcxproj @@ -0,0 +1,93 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {4B602022-E8DA-41DB-B4B6-A43B8DB5041D} + EventSystem + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + true + ../../DeanLib/include + + + true + ../../DeanLib/lib + DeanLibDebug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Game/lawson/Event System/ExampleListener.cpp b/Game/lawson/Event System/ExampleListener.cpp new file mode 100644 index 00000000..fbd7875d --- /dev/null +++ b/Game/lawson/Event System/ExampleListener.cpp @@ -0,0 +1,33 @@ +#include "ExampleListener.h" +#include "EventSystem.h" +#include "Event.h" +#include "MoveEvent.h" +#include "StringEvent.h" + +ExampleListener::ExampleListener() +{ + EventSystem* pEventSystem = EventSystem::getInstance(); + pEventSystem->addListener( MOVE_EVENT, this ); + pEventSystem->addListener(MESSAGE_EVENT, this); +} + +ExampleListener::~ExampleListener() +{ +} + +void ExampleListener::handleEvent(const Event &theEvent) +{ + cout << endl << "ExampleListener" << endl; + + if( theEvent.getType() == MOVE_EVENT ) + { + const MoveEvent& moveEvent = static_cast(theEvent); + cout << endl << "\tMove to: " << moveEvent.getLocation().getX() + << "," << moveEvent.getLocation().getY() << endl; + } + else if( theEvent.getType() == MESSAGE_EVENT) + { + const StringEvent& stringEvent = static_cast(theEvent); + cout << endl << "\tMessage: " << stringEvent.getString() << endl; + } +} \ No newline at end of file diff --git a/Game/lawson/Event System/ExampleListener.h b/Game/lawson/Event System/ExampleListener.h new file mode 100644 index 00000000..3caabdad --- /dev/null +++ b/Game/lawson/Event System/ExampleListener.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include "EventListener.h" + +class EventSystem; + +class ExampleListener : public EventListener +{ +public: + ExampleListener(); + ~ExampleListener(); + + void handleEvent( const Event& theEvent ); + +private: +}; \ No newline at end of file diff --git a/Game/lawson/Event System/KillEvent.h b/Game/lawson/Event System/KillEvent.h new file mode 100644 index 00000000..f57989ff --- /dev/null +++ b/Game/lawson/Event System/KillEvent.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Event.h" +#include "GameEvent.h" + +class KillEvent : public Event +{ +public: + KillEvent() :Event((EventType)KILL) {}; + ~KillEvent() {}; +private: +}; \ No newline at end of file diff --git a/Game/lawson/Event System/MoveEvent.cpp b/Game/lawson/Event System/MoveEvent.cpp new file mode 100644 index 00000000..32deb3d8 --- /dev/null +++ b/Game/lawson/Event System/MoveEvent.cpp @@ -0,0 +1,11 @@ +#include "MoveEvent.h" + +MoveEvent::MoveEvent(const Vector2D& loc) +:Event( MOVE_EVENT ) +,mLoc(loc) +{ +} + +MoveEvent::~MoveEvent() +{ +} diff --git a/Game/lawson/Event System/MoveEvent.h b/Game/lawson/Event System/MoveEvent.h new file mode 100644 index 00000000..aa95a7ca --- /dev/null +++ b/Game/lawson/Event System/MoveEvent.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include "Event.h" + +class MoveEvent : public Event +{ +public: + MoveEvent( const Vector2D& loc ); + ~MoveEvent(); + + Vector2D getLocation() const { return mLoc; }; + +private: + Vector2D mLoc; +}; \ No newline at end of file diff --git a/Game/lawson/Event System/SoundSystem.cpp b/Game/lawson/Event System/SoundSystem.cpp new file mode 100644 index 00000000..f8864964 --- /dev/null +++ b/Game/lawson/Event System/SoundSystem.cpp @@ -0,0 +1,18 @@ +#include "SoundSystem.h" +#include "EventSystem.h" +#include "Event.h" + +SoundSystem::SoundSystem() +{ + EventSystem::getInstance()->addListener(MESSAGE_EVENT, this); +} + +void SoundSystem::handleEvent(const Event& theEvent) +{ + cout << endl << "SoundSystem" << endl; + + if (theEvent.getType() == MESSAGE_EVENT) + { + cout << endl << "Ding" << endl; + } +} diff --git a/Game/lawson/Event System/SoundSystem.h b/Game/lawson/Event System/SoundSystem.h new file mode 100644 index 00000000..0627e7f8 --- /dev/null +++ b/Game/lawson/Event System/SoundSystem.h @@ -0,0 +1,17 @@ +#pragma once + +#include "EventSystem.h" +#include "EventListener.h" + +class SoundSystem : public EventListener +{ +public: + SoundSystem(); + ~SoundSystem() {}; + +private: + virtual void handleEvent(const Event& theEvent); + +}; + + diff --git a/Game/lawson/Event System/StringEvent.cpp b/Game/lawson/Event System/StringEvent.cpp new file mode 100644 index 00000000..c60d08d7 --- /dev/null +++ b/Game/lawson/Event System/StringEvent.cpp @@ -0,0 +1,11 @@ +#include "StringEvent.h" + +StringEvent::StringEvent(const string& theString) + :Event( MESSAGE_EVENT ) +,mString(theString) +{ +} + +StringEvent::~StringEvent() +{ +} diff --git a/Game/lawson/Event System/StringEvent.h b/Game/lawson/Event System/StringEvent.h new file mode 100644 index 00000000..c5e5e8b3 --- /dev/null +++ b/Game/lawson/Event System/StringEvent.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "Event.h" + +using namespace std; + +class StringEvent : public Event +{ +public: + StringEvent( const string& theString ); + ~StringEvent(); + + inline string getString() const { return mString; }; + +private: + string mString; +}; \ No newline at end of file diff --git a/Game/lawson/Event System/main.cpp b/Game/lawson/Event System/main.cpp new file mode 100644 index 00000000..467f0219 --- /dev/null +++ b/Game/lawson/Event System/main.cpp @@ -0,0 +1,49 @@ + +#include +#include + +#include +#include + +#include +#include +#include + +#include "EventSystem.h" +#include "ExampleListener.h" +#include "MoveEvent.h" +#include "StringEvent.h" +#include "SoundSystem.h" + +int main() +{ + EventSystem::initInstance(); + EventSystem* pEventSystem = EventSystem::getInstance(); + + pEventSystem->init(); + + ExampleListener* pListener = new ExampleListener; + SoundSystem* pSoundSystem = new SoundSystem; + + + //fire some events + pEventSystem->fireEvent( MoveEvent( Vector2D( 1.0f, 2.0f ) ) ); + + pEventSystem->fireEvent( StringEvent( "Initialization complete" ) ); + + pEventSystem->fireEvent( StringEvent( "Text1" ) ); + + + delete pListener;//make sure you delete listeners before the event system they use + + pEventSystem->fireEvent(StringEvent("Text\n")); + + delete pSoundSystem; + + EventSystem::cleanupInstance(); + MemoryTracker::getInstance()->reportAllocations(std::cout); + + system("pause"); + + return 0; +} \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/Game.cpp b/Game/lawson/Manager and Singleton examples/Game.cpp new file mode 100644 index 00000000..934bf064 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/Game.cpp @@ -0,0 +1,3 @@ +#include "Game.h" + +Game * Game::mpGameInstance = nullptr; \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/Game.h b/Game/lawson/Manager and Singleton examples/Game.h new file mode 100644 index 00000000..9d5b97ae --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/Game.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +class Game +{ +public: + static Game* getInstance(){ assert(mpGameInstance != nullptr); return mpGameInstance; }; + static void initInstance(){ mpGameInstance = new Game; }; + static void cleanupInstance(){ delete mpGameInstance; }; +private: + Game(); + + static Game* mpGameInstance; + +}; \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/Singleton.cpp b/Game/lawson/Manager and Singleton examples/Singleton.cpp new file mode 100644 index 00000000..8a3e12dc --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/Singleton.cpp @@ -0,0 +1,25 @@ +#include "Singleton.h" +#include + +Singleton* Singleton::mpsInstance = NULL; + +Singleton* Singleton::getInstance() +{ + if (mpsInstance == NULL) + mpsInstance = new Singleton; + return mpsInstance; +} + +/*void Singleton::cleanup() +{ + delete mpsInstance; + mpsInstance = NULL; +}; + +void Singleton::init() +{ + if (mpsInstance == NULL) + { + mpsInstance = new Singleton; + } +}*/ \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/Singleton.h b/Game/lawson/Manager and Singleton examples/Singleton.h new file mode 100644 index 00000000..d390f024 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/Singleton.h @@ -0,0 +1,21 @@ +#include +#include + +class Singleton:public Trackable +{ +private: + static Singleton* mpsInstance; + Singleton(){ mAString = "Hi"; mAnInt = 12; }; + ~Singleton(){}; + + int mAnInt; + std::string mAString; + +public: + static Singleton* getInstance(); + //static void init(); + //static void cleanup(); + + int getInt(){ return mAnInt; }; + const std::string& getString(){ return mAString; }; +}; \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/Widget.cpp b/Game/lawson/Manager and Singleton examples/Widget.cpp new file mode 100644 index 00000000..b5892c00 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/Widget.cpp @@ -0,0 +1 @@ +#include "Widget.h" \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/Widget.h b/Game/lawson/Manager and Singleton examples/Widget.h new file mode 100644 index 00000000..f8a183f9 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/Widget.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +class Widget : public Trackable +{ + friend class WidgetManager; + +public: + inline float getContents() const {return mContents;}; + +private: + float mContents; + + Widget( float contents ):mContents(contents){}; + ~Widget(){}; +}; \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/WidgetManager.cpp b/Game/lawson/Manager and Singleton examples/WidgetManager.cpp new file mode 100644 index 00000000..2d446e8e --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/WidgetManager.cpp @@ -0,0 +1,81 @@ +#include "WidgetManager.h" +#include "Widget.h" + +using namespace std; + +WidgetManager::~WidgetManager() +{ + cleanup(); +} + +void WidgetManager::cleanup() +{ + //go through all entries in map and delete + for( auto iter : mMap ) + { + Widget* pWidget = iter.second; + delete pWidget; + } + + mMap.clear(); +} + +Widget* WidgetManager::createAndManageWidget( const WidgetKey& key, float contents ) +{ + Widget* pWidget = NULL; + + //figure out if it exists already + auto iter = mMap. find( key ); + + //already in map? + if( iter == mMap.end() ) + { + //not already there - just create and add it + pWidget = new Widget( contents ); + mMap[key] = pWidget; + } + + return pWidget; +} + +void WidgetManager::deleteWidget( const WidgetKey& key ) +{ + //figure out if it exists already + auto iter = mMap.find( key ); + + if( iter != mMap.end() )//found + { + delete iter->second; + mMap.erase( iter ); + } + +} + +void WidgetManager::deleteWidget( Widget* pWidget ) +{ + //go through all entries in map searching for pWidget + for( auto iter: mMap ) + { + if( pWidget == iter.second ) + { + delete pWidget; + mMap.erase( iter.first ); + return; + } + } + +} + +Widget* WidgetManager::getWidget( const WidgetKey& key ) const +{ + auto iter = mMap.find( key ); + + if( iter != mMap.end() ) + { + return iter->second; + } + else + { + return NULL; + } +} diff --git a/Game/lawson/Manager and Singleton examples/WidgetManager.h b/Game/lawson/Manager and Singleton examples/WidgetManager.h new file mode 100644 index 00000000..182fc333 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/WidgetManager.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + + +class Widget; + +typedef std::string WidgetKey; + +class WidgetManager : public Trackable +{ +public: + WidgetManager(){}; + ~WidgetManager(); + + void cleanup(); + + Widget* createAndManageWidget( const WidgetKey& key, float contents ); + void deleteWidget( const WidgetKey& key ); + void deleteWidget( Widget* pWidget ); + + Widget* getWidget( const WidgetKey& key ) const; + +private: + std::unordered_map mMap; + +}; diff --git a/Game/lawson/Manager and Singleton examples/WidgetManager.sln b/Game/lawson/Manager and Singleton examples/WidgetManager.sln new file mode 100644 index 00000000..9b635254 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/WidgetManager.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2027 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WidgetManager", "WidgetManager.vcxproj", "{840C5A96-6243-42D8-BEDE-184F075B4522}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {840C5A96-6243-42D8-BEDE-184F075B4522}.Debug|Win32.ActiveCfg = Debug|Win32 + {840C5A96-6243-42D8-BEDE-184F075B4522}.Debug|Win32.Build.0 = Debug|Win32 + {840C5A96-6243-42D8-BEDE-184F075B4522}.Release|Win32.ActiveCfg = Release|Win32 + {840C5A96-6243-42D8-BEDE-184F075B4522}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {51EFABDE-57EC-4F59-8068-29D9C347D030} + EndGlobalSection +EndGlobal diff --git a/Game/lawson/Manager and Singleton examples/WidgetManager.vcxproj b/Game/lawson/Manager and Singleton examples/WidgetManager.vcxproj new file mode 100644 index 00000000..41d151b8 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/WidgetManager.vcxproj @@ -0,0 +1,86 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {840C5A96-6243-42D8-BEDE-184F075B4522} + WidgetManager + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + true + ../../DeanLib/include + + + true + ../../DeanLib/lib + DeanLibDebug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Game/lawson/Manager and Singleton examples/main.cpp b/Game/lawson/Manager and Singleton examples/main.cpp new file mode 100644 index 00000000..85e1f9b6 --- /dev/null +++ b/Game/lawson/Manager and Singleton examples/main.cpp @@ -0,0 +1,40 @@ + +#include +#include + +#include +#include + +#include "WidgetManager.h" +#include "Widget.h" +#include "Singleton.h" +using namespace std; +int main() +{ + + //Singleton::init(); + + Singleton* ptr = Singleton::getInstance(); + cout << ptr->getString() << " " << ptr->getInt() << endl; + + WidgetManager* pWidgetManager = new WidgetManager; + + pWidgetManager->createAndManageWidget( "PI", 3.14f ); + pWidgetManager->createAndManageWidget( "Square Root of 2", 1.414f ); + Widget* pSine = pWidgetManager->createAndManageWidget( "sine of 45", 0.707f ); + pWidgetManager->createAndManageWidget( "tangent of 30", 0.577f ); + + cout << "PI " << pWidgetManager->getWidget("PI")->getContents() << endl; + + pWidgetManager->deleteWidget( pSine ); + pWidgetManager->deleteWidget("tangent of 30"); + delete pWidgetManager; + + + //Singleton::cleanup(); + + MemoryTracker::getInstance()->reportAllocations(std::cout); + system("pause"); + + return 0; +} \ No newline at end of file diff --git a/Game/lawson/assignment1/Debug/assignment1.log b/Game/lawson/assignment1/Debug/assignment1.log new file mode 100644 index 00000000..653ebe56 --- /dev/null +++ b/Game/lawson/assignment1/Debug/assignment1.log @@ -0,0 +1,2 @@ + main.cpp +C:\Users\felix.abbott\Desktop\GameArchFelix\common\lawson\assignment1\main.cpp(26,10): error C1083: Cannot open include file: 'PerformanceTracker.h': No such file or directory diff --git a/Game/lawson/assignment1/Debug/assignment1.tlog/CL.command.1.tlog b/Game/lawson/assignment1/Debug/assignment1.tlog/CL.command.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/Game/lawson/assignment1/Debug/assignment1.tlog/CL.command.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/Game/lawson/assignment1/Debug/assignment1.tlog/assignment1.lastbuildstate b/Game/lawson/assignment1/Debug/assignment1.tlog/assignment1.lastbuildstate new file mode 100644 index 00000000..f08f5c9d --- /dev/null +++ b/Game/lawson/assignment1/Debug/assignment1.tlog/assignment1.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v142:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0 +Debug|Win32|C:\Users\felix.abbott\Desktop\GameArchFelix\common\lawson\assignment1\| diff --git a/Game/lawson/assignment1/Debug/assignment1.tlog/unsuccessfulbuild b/Game/lawson/assignment1/Debug/assignment1.tlog/unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/Game/lawson/assignment1/Debug/vc142.idb b/Game/lawson/assignment1/Debug/vc142.idb new file mode 100644 index 00000000..17c7faf7 Binary files /dev/null and b/Game/lawson/assignment1/Debug/vc142.idb differ diff --git a/Game/lawson/assignment1/assignment1.sln b/Game/lawson/assignment1/assignment1.sln new file mode 100644 index 00000000..acd80ac6 --- /dev/null +++ b/Game/lawson/assignment1/assignment1.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assignment1", "assignment1.vcxproj", "{EC58DA42-88DA-4B82-BFC4-AE6D5219F837}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.ActiveCfg = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.Build.0 = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.Build.0 = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.ActiveCfg = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.Build.0 = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2392FBF6-47CE-4D54-8F5B-DB78E5C9942D} + EndGlobalSection +EndGlobal diff --git a/Game/lawson/assignment1/assignment1.vcxproj b/Game/lawson/assignment1/assignment1.vcxproj new file mode 100644 index 00000000..afbf7098 --- /dev/null +++ b/Game/lawson/assignment1/assignment1.vcxproj @@ -0,0 +1,137 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837} + assignment1 + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + ..\..\..\common\allegro\include; ..\..\..\common\DeanLib\include + + + ..\..\..\common\allegro\debug\v141\win32\lib; ..\..\..\common\DeanLib\lib + allegro.lib, allegro_font.lib, allegro_ttf.lib, allegro_audio.lib, allegro_acodec.lib, allegro_image.lib, allegro_primitives.lib, DeanLibDebug.lib, DeanLibRelease.lib + + + + + Level3 + Disabled + true + ..\..\shared\allegro\include;..\..\shared\DeanLib\include + + + ..\..\shared\allegro\debug\v141\win32\lib; ..\..\shared\DeanLib\lib + allegro-debug.lib;allegro_font-debug.lib;allegro_ttf-debug.lib;allegro_audio-debug.lib;allegro_acodec-debug.lib;allegro_image-debug.lib;allegro_primitives-debug.lib;DeanLibDebug.lib + + + + + Level3 + MaxSpeed + true + true + true + ..\..\shared\allegro\include;..\..\shared\DeanLib\include + + + true + true + ..\..\shared\allegro\debug\v141\win32\lib; ..\..\shared\DeanLib\lib + allegro.lib;allegro_font.lib;allegro_ttf.lib;allegro_audio.lib;allegro_acodec.lib;allegro_image.lib;allegro_primitives.lib;DeanLibRelease.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + ..\..\shared\allegro\include;..\..\shared\DeanLib\include + + + true + true + ..\..\shared\allegro\debug\v141\win32\lib; ..\..\shared\DeanLib\lib + allegro.lib;allegro_font.lib;allegro_ttf.lib;allegro_audio.lib;allegro_acodec.lib;allegro_image.lib;allegro_primitives.lib;DeanLibRelease.lib;%(AdditionalDependencies) + + + + + C:\Users\felix.abbott\Desktop\GameArchFelix\common\allegro\include + + + + + + \ No newline at end of file diff --git a/Game/lawson/assignment1/main.cpp b/Game/lawson/assignment1/main.cpp new file mode 100644 index 00000000..c3756db3 --- /dev/null +++ b/Game/lawson/assignment1/main.cpp @@ -0,0 +1,138 @@ +/* +References: +http://wiki.allegro.cc/index.php?title=Windows,_Visual_Studio_2010_and_Allegro_5 +http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Addons/Audio +http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Bitmaps +*/ + +/* + please note that the installation of Allegro we are using doesn't include the monolith libs described in the references. + You must refer to the allegro.lib and each lib for each add-on separately!! +*/ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +using namespace std; + +int main() +{ + PerformanceTracker* pPerformanceTracker = new PerformanceTracker;//leave this alone + + const string INIT_TRACKER_NAME = "init"; + const string DRAW_TRACKER_NAME = "draw"; + const string WAIT_TRACKER_NAME = "wait"; + + + pPerformanceTracker->startTracking(INIT_TRACKER_NAME);//leave this alone + + if (!al_init()) + { + cout << "error initting Allegro\n"; + system("pause"); + return 1; + } + if (!al_init_image_addon()) + { + cout << "error initting image add-on\n"; + system("pause"); + return 1; + } + + //init the various add-ons - you will need image, font, ttf, primitives, audio, and acodec + + //various constants that you should use for asset loading and locating things to be drawn + const int DISP_WIDTH = 800; + const int DISP_HEIGHT = 600; + + const string ASSET_PATH = "..\\shared\\assets\\";//may need to change this + const string BACKGROUND_FILENAME = "axamer-lizum.png"; + const string QUIMBY_FILENAME = "mayor_quimby.png"; + const string FONT_FILENAME = "cour.ttf"; + const int FONT_SIZE = 24; + const string SAMPLE_FILENAME = "clapping.wav"; + const double SLEEP_TIME_IN_SECONDS = 5.0; + + //create the display + ALLEGRO_DISPLAY* display = al_create_display(DISP_WIDTH, DISP_HEIGHT); + assert(display); + + //example of how to construct the path and pass it to allegro + ALLEGRO_BITMAP* bitmap = al_load_bitmap((ASSET_PATH + BACKGROUND_FILENAME).c_str()); + assert(bitmap); + + //some colors + const ALLEGRO_COLOR WHITE = al_map_rgb(255, 255, 255); + const ALLEGRO_COLOR BLACK = al_map_rgb(0, 0, 0); + const ALLEGRO_COLOR BLACK_TRANSPARENT = al_map_rgba(0, 0, 0, 200); + const ALLEGRO_COLOR PURPLE = al_map_rgb(128, 64, 212); + + //load all assets and start playing sample (looping) + + pPerformanceTracker->stopTracking(INIT_TRACKER_NAME);//leave this alone + + pPerformanceTracker->startTracking(DRAW_TRACKER_NAME);//leave this alone + + const int CIRCLE_RADIUS = 150; + const string MESSAGE_TEXT = "Welcome to Allegro!"; + + //used for circle one - circle black and text white + const int LOC1_X = 400; + const int LOC1_Y = 300; + + //used for circle two - circle transparent black and text purple + const int LOC2_X = 200; + const int LOC2_Y = 500; + + //used for quimby + const int LOC3_X = 500; + const int LOC3_Y = 400; + const float SCALE_FACTOR = 0.75f; + + /* + PSEUDOCODE + clear screen to WHITE + draw the axamer-lizum background image + draw circle 1 with message + draw circle 2 with message + draw quimby image scaled appropriately + flip the display + */ + + + pPerformanceTracker->stopTracking(DRAW_TRACKER_NAME);//leave this alone + + pPerformanceTracker->startTracking(WAIT_TRACKER_NAME);//leave this alone + + //al_rest(SLEEP_TIME_IN_SECONDS); - leave this alone for now + Timer* pTimer = new Timer; + pTimer->start(); + pTimer->sleepUntilElapsed(SLEEP_TIME_IN_SECONDS*1000.0); + + pPerformanceTracker->stopTracking(WAIT_TRACKER_NAME);//leave this alone + + al_destroy_display(display); + + //report elapsed times - leave this alone + cout << endl << "Time to Init:" << pPerformanceTracker->getElapsedTime(INIT_TRACKER_NAME) << " ms" << endl; + cout << endl << "Time to Draw:" << pPerformanceTracker->getElapsedTime(DRAW_TRACKER_NAME) << " ms" << endl; + cout << endl << "Time spent waiting:" << pPerformanceTracker->getElapsedTime(WAIT_TRACKER_NAME) << " ms" << endl; + + MemoryTracker::getInstance()->reportAllocations(cout);//leave this alone - will report memory leaks - don't worry about this for now + + system("pause"); + return 0; +} \ No newline at end of file diff --git a/Game/lawson/assignment2/GraphicsLib/GraphicsLib.cpp b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.cpp new file mode 100644 index 00000000..7f173d87 --- /dev/null +++ b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.cpp @@ -0,0 +1,208 @@ +#include "GraphicsLib.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace std; + +ALLEGRO_DISPLAY* initAllegro() +{ + if (!al_init()) + { + cout << "error initting Allegro\n"; + return nullptr; + } + if (!al_init_image_addon()) + { + cout << "error - Image Add-on not initted\n"; + return nullptr; + } + if (!al_init_font_addon()) + { + cout << "error - Font Add-on not initted\n"; + return nullptr; + } + if (!al_init_ttf_addon()) + { + cout << "error - TTF Add-on not initted\n"; + return nullptr; + } + if (!al_init_primitives_addon()) + { + cout << "error - primitives Add-on not initted\n"; + return nullptr; + } + if (!al_install_audio()) + { + cout << "error - Audio Add-on not initted\n"; + //return 1; + } + if (!al_init_acodec_addon()) + { + cout << "error - Audio Codec Add-on not initted\n"; + //return 1; + } + if (!al_reserve_samples(1)) + { + cout << "error - samples not reserved\n"; + //return 1; + } + + const int DISP_WIDTH = 800; + const int DISP_HEIGHT = 600; + + + ALLEGRO_DISPLAY* display = al_create_display(DISP_WIDTH, DISP_HEIGHT); + assert(display); + + al_install_keyboard(); + al_install_mouse(); + return display; +} + +void drawScene(ALLEGRO_DISPLAY* pDisplay) +{ + const string ASSET_PATH = "..\\..\\..\\common\\assets\\"; + const string BACKGROUND_FILENAME = "axamer-lizum.png"; + const string QUIMBY_FILENAME = "mayor_quimby.png"; + const string FONT_FILENAME = "cour.ttf"; + const int FONT_SIZE = 24; + const string SAMPLE_FILENAME = "clapping.wav"; + + ALLEGRO_BITMAP* bitmap = al_load_bitmap((ASSET_PATH + BACKGROUND_FILENAME).c_str()); + assert(bitmap); + ALLEGRO_BITMAP* quimby = al_load_bitmap((ASSET_PATH + QUIMBY_FILENAME).c_str()); + assert(quimby); + + ALLEGRO_FONT* cour_font = al_load_ttf_font((ASSET_PATH + FONT_FILENAME).c_str(), FONT_SIZE, 0); + assert(cour_font); + + const ALLEGRO_COLOR WHITE = al_map_rgb(255, 255, 255); + const ALLEGRO_COLOR BLACK = al_map_rgb(0, 0, 0); + const ALLEGRO_COLOR BLACK_TRANSPARENT = al_map_rgba(0, 0, 0, 200); + const ALLEGRO_COLOR PURPLE = al_map_rgb(128, 64, 212); + + ALLEGRO_SAMPLE* sample = al_load_sample((ASSET_PATH + SAMPLE_FILENAME).c_str()); + assert(sample); + + al_play_sample(sample, 1.0f, ALLEGRO_AUDIO_PAN_NONE, 1.0f, ALLEGRO_PLAYMODE_LOOP, nullptr); + + + al_clear_to_color(WHITE); + + al_draw_bitmap(bitmap, 0, 0, 0); + const int CIRCLE_RADIUS = 150; + const int LOC1_X = 400; + const int LOC1_Y = 300; + + al_draw_filled_circle(LOC1_X, LOC1_Y, CIRCLE_RADIUS, BLACK); + al_draw_text(cour_font, WHITE, LOC1_X, LOC1_Y, ALLEGRO_ALIGN_CENTER, "Welcome to Allegro!"); + + const int LOC2_X = 200; + const int LOC2_Y = 500; + al_draw_filled_circle(LOC2_X, LOC2_Y, CIRCLE_RADIUS, BLACK_TRANSPARENT); + al_draw_text(cour_font, PURPLE, LOC2_X, LOC2_Y, ALLEGRO_ALIGN_CENTER, "Welcome to Allegro!"); + + const int LOC3_X = 500; + const int LOC3_Y = 400; + int sourceWidth = al_get_bitmap_width(quimby); + int sourceHeight = al_get_bitmap_height(quimby); + const float SCALE_FACTOR = 0.75f; + al_draw_scaled_bitmap(quimby, 0, 0, sourceWidth, sourceHeight, LOC3_X, LOC3_Y, sourceWidth * SCALE_FACTOR, sourceHeight * SCALE_FACTOR, 0); + + al_flip_display(); + + al_destroy_bitmap(bitmap); + al_destroy_bitmap(quimby); + //al_destroy_sample(sample); + al_destroy_font(cour_font); +} + +void cleanupAllegro(ALLEGRO_DISPLAY* pDisplay) +{ + al_destroy_display(pDisplay); + +} + +ALLEGRO_EVENT_QUEUE* initEventQueue() +{ + ALLEGRO_EVENT_QUEUE* pQueue = al_create_event_queue(); + if (pQueue == NULL) + { + cout << "InputSystem: unable to create Event Queue!\n"; + assert(false); + } + else + { + al_register_event_source(pQueue, al_get_keyboard_event_source()); + al_register_event_source(pQueue, al_get_mouse_event_source()); + } + return pQueue; +} + +bool processEventQueue(ALLEGRO_EVENT_QUEUE* theQueue) +{ + ALLEGRO_EVENT theEvent; + + while (al_get_next_event(theQueue, &theEvent)) + { + switch (theEvent.type) + { + case ALLEGRO_EVENT_KEY_DOWN: + case ALLEGRO_EVENT_KEY_UP: + if (theEvent.type == ALLEGRO_EVENT_KEY_DOWN) + { + cout << theEvent.keyboard.keycode << " Down\n"; + } + else if (theEvent.type == ALLEGRO_EVENT_KEY_UP) + { + cout << theEvent.keyboard.keycode << " Up\n"; + if (theEvent.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return true; + } + break; + case ALLEGRO_EVENT_MOUSE_AXES: + { + Vector2D vec(theEvent.mouse.x, theEvent.mouse.y); + cout << vec << endl; + } + break; + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + if (theEvent.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) + { + cout << theEvent.mouse.button << " Mouse Down\n"; + } + else if (theEvent.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) + { + cout << theEvent.mouse.button << " Mouse Up\n"; + } + Vector2D vec(theEvent.mouse.x, theEvent.mouse.y); + cout << vec << endl; + break; + } + } + return false; +} + +void cleanupEventQueue(ALLEGRO_EVENT_QUEUE* theQueue) +{ + al_unregister_event_source(theQueue, al_get_keyboard_event_source()); + al_unregister_event_source(theQueue, al_get_mouse_event_source()); + al_destroy_event_queue(theQueue); +} diff --git a/Game/lawson/assignment2/GraphicsLib/GraphicsLib.h b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.h new file mode 100644 index 00000000..03602ad7 --- /dev/null +++ b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.h @@ -0,0 +1,10 @@ +#pragma once +#include + +ALLEGRO_DISPLAY* initAllegro(); +void drawScene(ALLEGRO_DISPLAY* pDisplay); +void cleanupAllegro(ALLEGRO_DISPLAY* pDisplay); + +ALLEGRO_EVENT_QUEUE* initEventQueue(); +bool processEventQueue(ALLEGRO_EVENT_QUEUE* theQueue); +void cleanupEventQueue(ALLEGRO_EVENT_QUEUE* theQueue); diff --git a/Game/lawson/assignment2/GraphicsLib/GraphicsLib.sln b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.sln new file mode 100644 index 00000000..f5d41dbb --- /dev/null +++ b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2024 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsLib", "GraphicsLib.vcxproj", "{4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.ActiveCfg = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.Build.0 = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AB5A11A9-41DC-4165-8CEB-5563252277B6} + EndGlobalSection +EndGlobal diff --git a/Game/lawson/assignment2/GraphicsLib/GraphicsLib.vcxproj b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.vcxproj new file mode 100644 index 00000000..f187fba4 --- /dev/null +++ b/Game/lawson/assignment2/GraphicsLib/GraphicsLib.vcxproj @@ -0,0 +1,120 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} + Win32Proj + 10.0 + + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + + + Application + true + v142 + + + Application + false + v142 + + + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)$(Configuration)\ + + + true + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + ..\..\..\allegro\include;..\..\..\deanlib\include; + + + MachineX86 + true + Windows + + + + + + + + + + + + + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + MachineX86 + true + Windows + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/Game/lawson/assignment2/assignment2.sln b/Game/lawson/assignment2/assignment2.sln new file mode 100644 index 00000000..4e0956e5 --- /dev/null +++ b/Game/lawson/assignment2/assignment2.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29411.108 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsLib", "GraphicsLib\GraphicsLib.vcxproj", "{4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assignment2", "assignment2.vcxproj", "{EC58DA42-88DA-4B82-BFC4-AE6D5219F837}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} = {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeanLib", "..\..\DeanLib\DeanLib.vcxproj", "{DB900E08-5331-46D6-B450-6775A2C7C856}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|ARM.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x86.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|ARM.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.ActiveCfg = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.Build.0 = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x86.Build.0 = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|ARM.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.ActiveCfg = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x64.Build.0 = Debug|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.ActiveCfg = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Debug|x86.Build.0 = Debug|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|ARM.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.ActiveCfg = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x64.Build.0 = Release|x64 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.ActiveCfg = Release|Win32 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837}.Release|x86.Build.0 = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|ARM.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x64.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x86.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x86.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|ARM.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x64.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x86.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2392FBF6-47CE-4D54-8F5B-DB78E5C9942D} + EndGlobalSection +EndGlobal diff --git a/Game/lawson/assignment2/assignment2.vcxproj b/Game/lawson/assignment2/assignment2.vcxproj new file mode 100644 index 00000000..b6de3697 --- /dev/null +++ b/Game/lawson/assignment2/assignment2.vcxproj @@ -0,0 +1,124 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {EC58DA42-88DA-4B82-BFC4-AE6D5219F837} + assignment1 + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + ..\..\..\common\deanlib\include;GraphicsLib\;..\..\..\common\allegro\include + + + GraphicsLib\debug;..\..\..\common\deanlib\lib;..\..\..\common\allegro\debug\v141\win32\lib + allegro.lib;allegro_font.lib;allegro_ttf.lib;allegro_audio.lib;allegro_acodec.lib;allegro_image.lib;allegro_primitives.lib;GraphicsLib.lib;DeanLibDebug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/Game/lawson/assignment2/main.cpp b/Game/lawson/assignment2/main.cpp new file mode 100644 index 00000000..421dbdc2 --- /dev/null +++ b/Game/lawson/assignment2/main.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +#include +#include + +#include +#include + + +using namespace std; + +int main() +{ + const double SLEEP_TIME = 0.0; + + PerformanceTracker* pPerformanceTracker = new PerformanceTracker; + + const string INIT_TRACKER_NAME = "init"; + const string DRAW_TRACKER_NAME = "draw"; + const string WAIT_TRACKER_NAME = "wait"; + + pPerformanceTracker->startTracking(INIT_TRACKER_NAME); + ALLEGRO_DISPLAY* pDisplay = initAllegro(); + pPerformanceTracker->stopTracking(INIT_TRACKER_NAME); + + + pPerformanceTracker->startTracking(DRAW_TRACKER_NAME); + drawScene(pDisplay); + pPerformanceTracker->stopTracking(DRAW_TRACKER_NAME); + + Timer* pTimer = new Timer; + + pPerformanceTracker->startTracking(WAIT_TRACKER_NAME); + pTimer->start(); + pTimer->sleepUntilElapsed(SLEEP_TIME * 1000.0); + pPerformanceTracker->stopTracking(WAIT_TRACKER_NAME); + + //event queue stuff starts here!!!! + + ALLEGRO_EVENT_QUEUE* pQueue = initEventQueue(); + + //this is our fake game loop + Timer theTimer; + bool shouldStop = false; + while (!shouldStop) + { + theTimer.start(); + shouldStop = processEventQueue(pQueue); + theTimer.sleepUntilElapsed(16.7); + } + + cleanupEventQueue(pQueue); + + //event queue stuff stops here!!!! + + + cleanupAllegro(pDisplay); + + //report elapsed times + cout << endl << "Time to Init:" << pPerformanceTracker->getElapsedTime(INIT_TRACKER_NAME) << " ms" << endl; + cout << endl << "Time to Draw:" << pPerformanceTracker->getElapsedTime(DRAW_TRACKER_NAME) << " ms" << endl; + cout << endl << "Time to Wait:" << pPerformanceTracker->getElapsedTime(WAIT_TRACKER_NAME) << " ms" << endl; + + MemoryTracker::getInstance()->reportAllocations(cout); + system("pause"); + + return 0; + +} \ No newline at end of file diff --git a/Game/lawson/assignment2/solution.jpg b/Game/lawson/assignment2/solution.jpg new file mode 100644 index 00000000..0f68d14a Binary files /dev/null and b/Game/lawson/assignment2/solution.jpg differ diff --git a/Game/main.cpp b/Game/main.cpp new file mode 100644 index 00000000..f0dc3159 --- /dev/null +++ b/Game/main.cpp @@ -0,0 +1,53 @@ +/* +Author: Evan Koppers +Class: GPR-250
+Assignment: Assignment 5 +Certification of Authenticity: I certify that this assignment is entirely my own work. +*/ + +#include +#include +#include + +#include +#include +#include + +#include "Game.h" +#include "allegro5/allegro.h" +#include "EventSystem.h" +#include "GameEventSystem.h" +#include "GameListener.h" + +using namespace std; + +int main() +{ + EventSystem::initInstance(); + + const double SLEEP_TIME = 5.0; + + PerformanceTracker* pPerformanceTracker = new PerformanceTracker; + + Game::initInstance(); + GameListener* gameListener = new GameListener(); + + gameListener->init(); + + Game::getInstance()->setFrameRate(60.0); + Game::getInstance()->doLoop(); + Game::getInstance()->cleanUpInstance(); + + gameListener->cleanup(); + delete(gameListener); + + EventSystem::getInstance()->cleanupInstance(); + + delete pPerformanceTracker; + + MemoryTracker::getInstance()->reportAllocations(cout); + system("pause"); + + return 0; + +} \ No newline at end of file diff --git a/Game/packages.config b/Game/packages.config new file mode 100644 index 00000000..9ff6486d --- /dev/null +++ b/Game/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Game/x64/Debug/assignment2.log b/Game/x64/Debug/assignment2.log new file mode 100644 index 00000000..fe0e1b54 --- /dev/null +++ b/Game/x64/Debug/assignment2.log @@ -0,0 +1,23 @@ + DeleteUnitsEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\DeleteUnitsEvent.h(3,10): fatal error C1083: Cannot open include file: 'Event.h': No such file or directory + EscEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\EscEvent.h(3,10): fatal error C1083: Cannot open include file: 'Event.h': No such file or directory + Game.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\Game.h(3,10): fatal error C1083: Cannot open include file: 'System.h': No such file or directory + GameEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GameEvent.h(4,10): fatal error C1083: Cannot open include file: 'trackable.h': No such file or directory + GameEventSystem.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GameEvent.h(4,10): fatal error C1083: Cannot open include file: 'trackable.h': No such file or directory + GameListener.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\GameListener.h(3,10): fatal error C1083: Cannot open include file: 'EventListener.h': No such file or directory + InputTranslator.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\InputTranslator.h(4,10): fatal error C1083: Cannot open include file: 'EventListener.h': No such file or directory + main.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\main.cpp(12,10): fatal error C1083: Cannot open include file: 'PerformanceTracker.h': No such file or directory + PauseEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\PauseEvent.h(3,10): fatal error C1083: Cannot open include file: 'Event.h': No such file or directory + PlaceUnitEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\PlaceUnitEvent.h(3,10): fatal error C1083: Cannot open include file: 'Vector2D.h': No such file or directory + SwitchAnimEvent.cpp +C:\Users\Gavin\source\repos\SocketDemo\Game\SwitchAnimEvent.h(3,10): fatal error C1083: Cannot open include file: 'Event.h': No such file or directory + Generating Code... diff --git a/Game/x64/Debug/assignment2.tlog/CL.command.1.tlog b/Game/x64/Debug/assignment2.tlog/CL.command.1.tlog new file mode 100644 index 00000000..f61f8600 Binary files /dev/null and b/Game/x64/Debug/assignment2.tlog/CL.command.1.tlog differ diff --git a/Game/x64/Debug/assignment2.tlog/assignment2.lastbuildstate b/Game/x64/Debug/assignment2.tlog/assignment2.lastbuildstate new file mode 100644 index 00000000..b037df16 --- /dev/null +++ b/Game/x64/Debug/assignment2.tlog/assignment2.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v142:VCToolArchitecture=Native64Bit:VCToolsVersion=14.29.30133:VCServicingVersionCrtHeaders=14.29.30136:TargetPlatformVersion=10.0.19041.0: +Debug|x64|C:\Users\Gavin\source\repos\SocketDemo\| diff --git a/Game/x64/Debug/assignment2.tlog/unsuccessfulbuild b/Game/x64/Debug/assignment2.tlog/unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/Game/x64/Debug/vc142.idb b/Game/x64/Debug/vc142.idb new file mode 100644 index 00000000..b8752656 Binary files /dev/null and b/Game/x64/Debug/vc142.idb differ diff --git a/RoboCat/Bin/Debug/allegro-5.2.dll b/RoboCat/Bin/Debug/allegro-5.2.dll new file mode 100644 index 00000000..517701bc Binary files /dev/null and b/RoboCat/Bin/Debug/allegro-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_acodec-5.2.dll b/RoboCat/Bin/Debug/allegro_acodec-5.2.dll new file mode 100644 index 00000000..0a4a584a Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_acodec-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_audio-5.2.dll b/RoboCat/Bin/Debug/allegro_audio-5.2.dll new file mode 100644 index 00000000..5f4540ef Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_audio-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_color-5.2.dll b/RoboCat/Bin/Debug/allegro_color-5.2.dll new file mode 100644 index 00000000..8e851bb1 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_color-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_dialog-5.2.dll b/RoboCat/Bin/Debug/allegro_dialog-5.2.dll new file mode 100644 index 00000000..cd5427d3 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_dialog-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_font-5.2.dll b/RoboCat/Bin/Debug/allegro_font-5.2.dll new file mode 100644 index 00000000..6cf5533f Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_font-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_image-5.2.dll b/RoboCat/Bin/Debug/allegro_image-5.2.dll new file mode 100644 index 00000000..d8616356 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_image-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_memfile-5.2.dll b/RoboCat/Bin/Debug/allegro_memfile-5.2.dll new file mode 100644 index 00000000..4917b1e2 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_memfile-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_physfs-5.2.dll b/RoboCat/Bin/Debug/allegro_physfs-5.2.dll new file mode 100644 index 00000000..4736d437 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_physfs-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_primitives-5.2.dll b/RoboCat/Bin/Debug/allegro_primitives-5.2.dll new file mode 100644 index 00000000..d7e517fd Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_primitives-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_ttf-5.2.dll b/RoboCat/Bin/Debug/allegro_ttf-5.2.dll new file mode 100644 index 00000000..504cad16 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_ttf-5.2.dll differ diff --git a/RoboCat/Bin/Debug/allegro_video-5.2.dll b/RoboCat/Bin/Debug/allegro_video-5.2.dll new file mode 100644 index 00000000..64ccd723 Binary files /dev/null and b/RoboCat/Bin/Debug/allegro_video-5.2.dll differ diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index c2d193be..08f86c3d 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -92,6 +92,17 @@ true true Bin\$(Configuration)\ + true + true + true + true + true + true + true + true + true + true + true true @@ -127,12 +138,12 @@ WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) ProgramDatabase EnableFastChecks - ..\SDL\include;Inc;..\ - Use + ..\Game\;..\Game\DeanLib\include;..\Game\GraphicsLib\;Inc\ + NotUsing RoboCatPCH.h - d3d11.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies);Ws2_32.lib + d3d11.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies);Ws2_32.lib;allegro.lib;allegro_font.lib;allegro_ttf.lib;allegro_audio.lib;allegro_acodec.lib;allegro_image.lib;allegro_primitives.lib;GraphicsLib.lib;DeanLibDebug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib true true true @@ -141,6 +152,7 @@ AsInvoker %(DelayLoadDLLs) Console + ..\Game\GraphicsLib\debug;..\packages\Allegro.5.2.7.1\build\native\v142\win32\lib;..\Game\DeanLib\lib;..\Game\Debug true @@ -370,7 +382,21 @@ + + + + + + + + + + + + + + @@ -382,7 +408,24 @@ + + + + + + + + + + + + + + + + + @@ -391,15 +434,23 @@ + 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/Main.cpp b/RoboCat/Src/Main.cpp index 3b0ac9de..1a672661 100644 --- a/RoboCat/Src/Main.cpp +++ b/RoboCat/Src/Main.cpp @@ -1,11 +1,558 @@ - #include "RoboCatPCH.h" +#include +#include +#include +#include +#include +#include +#include -#if _WIN32 +//Game Includes +#include +#include "allegro5/allegro.h" +#include +#include +#include + +/// +/// Run the game +/// +void runGame() +{ + Game::getInstance()->doLoop(); +} + +/// +/// Create TCP Server Program to send and recieve data +/// +void DoTcpServer() +{ + // Create socket + TCPSocketPtr listenSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (listenSocket == nullptr) + { + SocketUtil::ReportError("Creating listening socket"); + ExitProcess(1); + } + unordered_map> unackPacks; + vector recievedPacks; + + + //listenSocket->SetNonBlockingMode(true); + + LOG("%s", "Listening socket created"); + + // Bind() - "Bind" socket -> tells OS we want to use a specific address + + SocketAddressPtr listenAddress = SocketAddressFactory::CreateIPv4FromString("0.0.0.0:8080"); + if (listenAddress == nullptr) + { + SocketUtil::ReportError("Creating listen address"); + ExitProcess(1); + } + + if (listenSocket->Bind(*listenAddress) != NO_ERROR) + { + SocketUtil::ReportError("Binding listening socket"); + // This doesn't block! + ExitProcess(1); + } + + LOG("%s", "Bound listening socket"); + + // Blocking function call -> Waits for some input; halts the program until something "interesting" happens + // Non-Blocking function call -> Returns right away, as soon as the action is completed + + // Listen() - Listen on socket -> Non-blocking; tells OS we care about incoming connections on this socket + if (listenSocket->Listen() != NO_ERROR) + { + SocketUtil::ReportError("Listening on listening socket"); + ExitProcess(1); + } + + LOG("%s", "Listening on socket"); + + // Accept() - Accept on socket -> Blocking; Waits for incoming connection and completes TCP handshake + + LOG("%s", "Waiting to accept connections..."); + SocketAddress incomingAddress; + TCPSocketPtr connSocket = listenSocket->Accept(incomingAddress); + while (connSocket == nullptr) + { + connSocket = listenSocket->Accept(incomingAddress); + // SocketUtil::ReportError("Accepting connection"); + // ExitProcess(1); + } + + LOG("Accepted connection from %s", incomingAddress.ToString().c_str()); + + bool quit = false; + std::thread receiveThread([&connSocket, &quit, &incomingAddress, &unackPacks, &recievedPacks]() { // don't use [&] :) + while (!quit) // Need to add a quit here to have it really exit! + { + //Create Buffer + char buffer[8192]; + int32_t bytesReceived = connSocket->Receive(buffer, 4096); + //Check recieved buffer for any data + if (bytesReceived == 0) + { + std::cout << incomingAddress.ToString() << " has disconnected"; + quit = true; + } + if (bytesReceived < 0) + { + SocketUtil::ReportError("Receiving"); + return; + } + + //Random Ignore Packet + if (rand() % 10 == 1) + { + std::cout << "gonna ignore this packet :( \n"; + } + else + { + //Recieve data + std::string receivedMsg(buffer, bytesReceived); + vector> data; + vector deletedUnits; + + string del1 = "\n"; + string del2 = " "; + string del3 = "END"; + + //Get Package ID + size_t idPos = 0; + idPos = receivedMsg.find(del1); + int id = stoi(receivedMsg.substr(0, idPos)); + receivedMsg.erase(0, idPos + del1.length()); + + bool cont = true; + + if (unackPacks.find(id) != unackPacks.end()) + { + //Check if acknowledged + unackPacks.find(id)->second.second = true; + cont = false; + } + else + { + std::cout << "acknowledging packet " << id << "\n"; + if (std::find(recievedPacks.begin(), recievedPacks.end(), id) != recievedPacks.end()) + { + //acknowledgment was lost, do not repeat instructions + cont = false; + } + else + { + //Acknowledgement was found push packet to be interpreted + recievedPacks.push_back(id); + } + + + //Send Acknowledgement + connSocket->Send(to_string(id).c_str(), to_string(id).length()); + } + + //If packets were aquired load the data into the game + if (cont) + { + //Game::getInstance()->deleteAllUnits(); + size_t pos = 0; + size_t pos2 = 0; + std::string token; + std::cout << endl; + + size_t tempPos = receivedMsg.find(del3); + string tempMsg = receivedMsg.substr(0, tempPos); + receivedMsg.erase(0, tempPos + del3.length()); + std::cout << tempMsg << " END\n" << receivedMsg << endl; + while ((pos = tempMsg.find(del1)) != std::string::npos) { + token = tempMsg.substr(0, pos); + //Add new Unit + vector unitData; + while ((pos2 = token.find(del2)) != std::string::npos) { + //Getting new Unit position + string token2 = token.substr(0, pos); + unitData.push_back(stoi(token2)); + token.erase(0, pos2 + del2.length()); + } + //Add Unit to the data to get updated + data.push_back(unitData); + tempMsg.erase(0, pos + del1.length()); + } + + while ((pos2 = receivedMsg.find(del1)) != std::string::npos) { + //Get new Unit data + string token2 = receivedMsg.substr(0, pos); + deletedUnits.push_back(stoi(token2)); + receivedMsg.erase(0, pos2 + del1.length()); + } + + //All data aquired + + for (UINT i = 0; i < data.size(); i++) + { + //Update Unit position + if (Game::getInstance()->unitWithID(data[i][0])) + { + Game::getInstance()->updateUnitLocation(data[i][0], data[i][2], data[i][3]); + } + else + { + //Place new Units + Game::getInstance()->placeUnit(data[i][0], data[i][1], data[i][2], data[i][3]); + } + } + + for (UINT i = 0; i < deletedUnits.size(); i++) + { + //Delete deleted units + Game::getInstance()->deleteUnit(deletedUnits[i]); + } + } + } + } + }); + while (!quit) + { + runGame(); + + vector toDelte; + for (auto& it : unackPacks) { + if (!it.second.second) + { + //If data lost resend the data + std::cout << "resending lost packet " << it.first <<"\n"; + connSocket->Send(it.second.first.c_str(), it.second.first.length()); + } + else if (it.second.second) + { + //Delete packets + std::cout << "deleting acknowledged packet " << it.first << "\n"; + toDelte.push_back(it.first); + } + } + + for (UINT i = 0; i < toDelte.size(); i++) + { + unackPacks.erase(toDelte[i]); + } + + if (Game::getInstance()->getWorldStateChanged()) + { + int id = (rand() % 2000) + 2001; + + while (unackPacks.find(id) != unackPacks.end()) + { + id = (rand() % 2000) + 2001; + } + + string msg = to_string(id) + "\n"; + //Begin transferring data + Game::getInstance()->setWorldStateChanged(false); + vector> data = Game::getInstance()->getUnitData(); + for (UINT i = 1; i < data.size(); i++) + { + msg += to_string(data[i][0]) + " " + to_string(data[i][1]) + " " + to_string(data[i][2]) + " " + to_string(data[i][3]) + " \n"; + } + msg += "END"; + //Add unit deletion + vector data2 = Game::getInstance()->getUnitDeletion(); + for (UINT i = 0; i < data2.size(); i++) + { + msg += to_string(data2[i]) + " \n"; + } + //Send data + unackPacks.emplace(id, std::make_pair(msg, false)); + if (rand() % 10 != 5) + { + connSocket->Send(msg.c_str(), msg.length()); + } + } + } + connSocket->~TCPSocket(); // Forcibly close socket (shouldn't call destructors like this -- make a new function for it! + receiveThread.join(); +} + +/// +/// Create TCP Client Program to send and recieve data +/// +/// Client port to connect to the server +void DoTcpClient(std::string port) +{ + // Create socket + unordered_map> unackPacks; + vector recievedPacks; + TCPSocketPtr clientSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (clientSocket == nullptr) + { + SocketUtil::ReportError("Creating client socket"); + ExitProcess(1); + } + LOG("%s", "Client socket created"); + std::string address = StringUtils::Sprintf("127.0.0.1:%s", port.c_str()); + SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); + if (clientAddress == nullptr) + { + SocketUtil::ReportError("Creating client address"); + ExitProcess(1); + } + + if (clientSocket->Bind(*clientAddress) != NO_ERROR) + { + SocketUtil::ReportError("Binding client socket"); + ExitProcess(1); + } + + LOG("%s", "Bound client socket"); + SocketAddressPtr servAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:8080"); + if (servAddress == nullptr) + { + SocketUtil::ReportError("Creating server address"); + ExitProcess(1); + } + + if (clientSocket->Connect(*servAddress) != NO_ERROR) + { + SocketUtil::ReportError("Connecting to server"); + ExitProcess(1); + } + + LOG("%s", "Connected to server!"); + bool quit = false; + + //Recieve game data from server + std::thread receiveThread([&clientSocket, &quit, &unackPacks, &recievedPacks]() { + while (!quit) + { + //Create Buffer + char buffer[8192]; + int32_t bytesReceived = clientSocket->Receive(buffer, 4096); + + //Check how many bytes have been recieved + if (bytesReceived == 0) + { + std::cout << "Server disconnected"; + quit = true; + } + if (bytesReceived < 0) + { + SocketUtil::ReportError("Receiving"); + return; + } + + //Variation of randomness + if (rand() % 10 == 0) + { + cout << "ignoring this packet :(\n"; + } + //Recieve packets + else + { + //Create recieved message to send back + std::string receivedMsg(buffer, bytesReceived); + + + vector> data; + vector deletedUnits; + + string del1 = "\n"; + string del2 = " "; + string del3 = "END"; + + //Get Package ID + size_t idPos = 0; + idPos = receivedMsg.find(del1); + int id = stoi(receivedMsg.substr(0, idPos)); + receivedMsg.erase(0, idPos + del1.length()); + + bool cont = true; + + //Check if acknowledged + if (unackPacks.find(id) != unackPacks.end()) + { + cout << "setting packet as acknowledged " << id << endl; + unackPacks.find(id)->second.second = true; + cont = false; + } + else + { + //Send Acknowledgement Packet + if (std::find(recievedPacks.begin(), recievedPacks.end(), id) != recievedPacks.end()) //acknowledgment was lost, do not repeat instructions + { + cont = false; + } + else + { + recievedPacks.push_back(id); + } + //Send Acknowledgement + clientSocket->Send(to_string(id).c_str(), to_string(id).length()); + } + + //If the packet was aquired then translate the data otherwise disregard + if (cont) + { + + size_t pos = 0; + size_t pos2 = 0; + std::string token; + cout << endl; + size_t tempPos = receivedMsg.find(del3); + string tempMsg = receivedMsg.substr(0, tempPos); + receivedMsg.erase(0, tempPos + del3.length()); + while ((pos = tempMsg.find(del1)) != std::string::npos) { + token = tempMsg.substr(0, pos); + //Getting new Unit + vector unitData; + while ((pos2 = token.find(del2)) != std::string::npos) { + //Getting units data + string token2 = token.substr(0, pos); + unitData.push_back(stoi(token2)); + cout << stoi(token2) << " "; + token.erase(0, pos2 + del2.length()); + } + //Add this unit to the data list + data.push_back(unitData); + tempMsg.erase(0, pos + del1.length()); + } + + //Unit Position Data Aquired + while ((pos2 = receivedMsg.find(del1)) != std::string::npos) { + string token2 = receivedMsg.substr(0, pos); + //Check deleted Units + deletedUnits.push_back(stoi(token2)); + receivedMsg.erase(0, pos2 + del1.length()); + } + + //All Data Aquired + + for (UINT i = 0; i < data.size(); i++) + { + //Update Unit location based on Unit ID + if (Game::getInstance()->unitWithID(data[i][0])) + { + Game::getInstance()->updateUnitLocation(data[i][0], data[i][2], data[i][3]); + } + //If its a new Unit place it with new ID + else + { + Game::getInstance()->placeUnit(data[i][0], data[i][1], data[i][2], data[i][3]); + } + } + //All Units updated/added + + //Delete units + for (UINT i = 0; i < deletedUnits.size(); i++) + { + if (Game::getInstance()->unitWithID(deletedUnits[i]) != nullptr) + { + cout << "deleting unit " << deletedUnits[i] << endl; + Game::getInstance()->deleteUnit(deletedUnits[i]); + //cout << "unit deleted " << deletedUnits[i] << endl; + } + else + { + cout << "there is no unit with id " << deletedUnits[i] << endl; + } + } + + //LOG("%s", receivedMsg.c_str()); + std::cout << ">"; + } + } + } + }); + //End of Recieve Thread + + + while (!quit) + { + runGame(); + + vector toDelte; + for (auto& it : unackPacks) { + // Resend packets that have been dropped + if (!it.second.second) + { + cout << "resending lost packet " << it.first << endl; + clientSocket->Send(it.second.first.c_str(), it.second.first.length()); + } + else if (it.second.second) + { + cout << "deleting acknowledged packet " << it.first << endl; + toDelte.push_back(it.first); + //unackPacks.erase(it.first); + } + } + + for (UINT i = 0; i < toDelte.size(); i++) + { + unackPacks.erase(toDelte[i]); + } + + if (Game::getInstance()->getWorldStateChanged()) + { + int id = rand() % 2000; + + while (unackPacks.find(id) != unackPacks.end()) + { + id = rand() % 2000; + } + + string msg = to_string(id) + " "; + Game::getInstance()->setWorldStateChanged(false); + vector> data = Game::getInstance()->getUnitData(); + //Send the game state + for (UINT i = 1; i < data.size(); i++) + { + msg += to_string(data[i][0]) + " " + to_string(data[i][1]) + " " + to_string(data[i][2]) + " " + to_string(data[i][3]) + " \n"; + } + + //Send unit deletions + msg += "END"; + vector data2 = Game::getInstance()->getUnitDeletion(); + for (UINT i = 1; i < data2.size(); i++) + { + msg += to_string(data2[i]) + " \n"; + } + //Attempt to send Unit data + unackPacks.emplace(id, std::make_pair(msg, false)); + if (rand() % 10 != 2) + { + clientSocket->Send(msg.c_str(), msg.length()); + } + } + } + clientSocket->~TCPSocket(); + receiveThread.join(); +} + +/// +/// End game +/// +/// Game Event Manager +/// Pointer performance tracker +void shutGame(GameListener* gameListener) +{ + Game::getInstance()->cleanUpInstance(); + + gameListener->cleanup(); + delete(gameListener); + + EventSystem::getInstance()->cleanupInstance(); + + + system("pause"); +} + +#if _WIN32 int main(int argc, const char** argv) { + cout << "0" << endl; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); #else @@ -17,9 +564,38 @@ int main(int argc, const char** argv) __argv = argv; #endif + GameListener* gameListener;// = new GameListener(); + SocketUtil::StaticInit(); + bool isServer = StringUtils::GetCommandLineArg(1) == "server"; + + //Init Game + EventSystem::initInstance(); + //Game Initted + + + //Performance Tracker created + Game::initInstance(); + //Create insance of game + gameListener = new GameListener(); + gameListener->init(); + //Create the Game Event Manager + + Game::getInstance()->setFrameRate(60.0); + + //Game Initted + if (isServer) + { + DoTcpServer(); + } + else + { + DoTcpClient(StringUtils::GetCommandLineArg(2)); + } + //Program success + shutGame(gameListener); SocketUtil::CleanUp(); return 0; -} +} \ 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 diff --git a/RoboCat/sendDataEvent.cpp b/RoboCat/sendDataEvent.cpp new file mode 100644 index 00000000..c30bbea8 --- /dev/null +++ b/RoboCat/sendDataEvent.cpp @@ -0,0 +1,10 @@ +#include "sendDataEvent.h" + +sendDataEvent::sendDataEvent() + :Event(10) +{ +} + +sendDataEvent::~sendDataEvent() +{ +} diff --git a/RoboCat/sendDataEvent.h b/RoboCat/sendDataEvent.h new file mode 100644 index 00000000..7dbeb668 --- /dev/null +++ b/RoboCat/sendDataEvent.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Event.h" + +class sendDataEvent : public Event +{ +public: + sendDataEvent(); + ~sendDataEvent(); +}; + diff --git a/RoboCat/x64/Debug/Chapter3.log b/RoboCat/x64/Debug/Chapter3.log new file mode 100644 index 00000000..064600bc --- /dev/null +++ b/RoboCat/x64/Debug/Chapter3.log @@ -0,0 +1,16 @@ + Main.cpp + MemoryBitStream.cpp + OutputWindow.cpp + SocketAddress.cpp +C:\Users\Gavin\source\repos\SocketDemo\RoboCat\Src\SocketAddress.cpp(9,114): error C2664: 'PCWSTR InetNtopW(INT,const void *,PWSTR,size_t)': cannot convert argument 3 from 'char [128]' to 'PWSTR' +C:\Users\Gavin\source\repos\SocketDemo\RoboCat\Src\SocketAddress.cpp(9,67): message : Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\Ws2tcpip.h(602,1): message : see declaration of 'InetNtopW' + SocketAddressFactory.cpp + SocketUtil.cpp + StringUtils.cpp + TCPSocket.cpp +C:\Users\Gavin\source\repos\SocketDemo\RoboCat\Src\TCPSocket.cpp(44,85): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +C:\Users\Gavin\source\repos\SocketDemo\RoboCat\Src\TCPSocket.cpp(55,83): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data + RoboCatPCH.cpp + UDPSocket.cpp + Generating Code... diff --git a/RoboCat/x64/Debug/SocketDemo.tlog/CL.command.1.tlog b/RoboCat/x64/Debug/SocketDemo.tlog/CL.command.1.tlog new file mode 100644 index 00000000..b268e186 Binary files /dev/null and b/RoboCat/x64/Debug/SocketDemo.tlog/CL.command.1.tlog differ diff --git a/RoboCat/x64/Debug/SocketDemo.tlog/CL.read.1.tlog b/RoboCat/x64/Debug/SocketDemo.tlog/CL.read.1.tlog new file mode 100644 index 00000000..e792bc60 Binary files /dev/null and b/RoboCat/x64/Debug/SocketDemo.tlog/CL.read.1.tlog differ diff --git a/RoboCat/x64/Debug/SocketDemo.tlog/CL.write.1.tlog b/RoboCat/x64/Debug/SocketDemo.tlog/CL.write.1.tlog new file mode 100644 index 00000000..35202a74 Binary files /dev/null and b/RoboCat/x64/Debug/SocketDemo.tlog/CL.write.1.tlog differ diff --git a/RoboCat/x64/Debug/SocketDemo.tlog/SocketDemo.lastbuildstate b/RoboCat/x64/Debug/SocketDemo.tlog/SocketDemo.lastbuildstate new file mode 100644 index 00000000..b037df16 --- /dev/null +++ b/RoboCat/x64/Debug/SocketDemo.tlog/SocketDemo.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v142:VCToolArchitecture=Native64Bit:VCToolsVersion=14.29.30133:VCServicingVersionCrtHeaders=14.29.30136:TargetPlatformVersion=10.0.19041.0: +Debug|x64|C:\Users\Gavin\source\repos\SocketDemo\| diff --git a/RoboCat/x64/Debug/SocketDemo.tlog/unsuccessfulbuild b/RoboCat/x64/Debug/SocketDemo.tlog/unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/SocketDemo.sln b/SocketDemo.sln index d4b486ba..0365a50c 100644 --- a/SocketDemo.sln +++ b/SocketDemo.sln @@ -1,9 +1,19 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32126.315 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chapter3", "RoboCat\Chapter3.vcxproj", "{B3B75176-8D81-4E7B-A5D0-C2E5423844D3}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SocketDemo", "RoboCat\Chapter3.vcxproj", "{B3B75176-8D81-4E7B-A5D0-C2E5423844D3}" + ProjectSection(ProjectDependencies) = postProject + {DB900E08-5331-46D6-B450-6775A2C7C856} = {DB900E08-5331-46D6-B450-6775A2C7C856} + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} = {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{04763FF9-6187-4AE4-9896-72C33BB941C9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsLib", "Game\GraphicsLib\GraphicsLib.vcxproj", "{4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeanLib", "Game\DeanLib\DeanLib.vcxproj", "{DB900E08-5331-46D6-B450-6775A2C7C856}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,8 +37,33 @@ Global {B3B75176-8D81-4E7B-A5D0-C2E5423844D3}.Release|Win32.Build.0 = Release|Win32 {B3B75176-8D81-4E7B-A5D0-C2E5423844D3}.Release|x64.ActiveCfg = Release|x64 {B3B75176-8D81-4E7B-A5D0-C2E5423844D3}.Release|x64.Build.0 = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|Win32.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|Win32.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Debug|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Profile|Win32.ActiveCfg = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Profile|Win32.Build.0 = Debug|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Profile|x64.ActiveCfg = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Profile|x64.Build.0 = Debug|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|Win32.ActiveCfg = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|Win32.Build.0 = Release|Win32 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.ActiveCfg = Release|x64 + {4B9AB2DA-44CB-4F3D-866F-FA7F345BD810}.Release|x64.Build.0 = Release|x64 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|Win32.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Debug|x64.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Profile|Win32.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Profile|Win32.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Profile|x64.ActiveCfg = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Profile|x64.Build.0 = Debug|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|Win32.ActiveCfg = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|Win32.Build.0 = Release|Win32 + {DB900E08-5331-46D6-B450-6775A2C7C856}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {01C7F7FF-2D28-47D8-B6CB-4B137B73DBE7} + EndGlobalSection EndGlobal diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 00000000..ca454e39 Binary files /dev/null and b/UpgradeLog.htm differ