Looking to do Multithreaded programming? In order to do that you're going to need a Mutex to prevent threads from accessing data at the same time! There are different techniques of preventing threads from accessing the same data, but they can't guarantee problems won't happen, it has to be implemented on the hardware side and exposed through the OS or what have you. Luckily, we can do this using some code from the Windows header files, using what's called Critical Section Objects, which works between threads on the same process, and is apparently a, "slightly faster, more efficient mechanism for mutual-exclusion synchronization." Sweeet!

Mutex_win32.h:

#ifndef w_Mutex_win32
#define w_Mutex_win32

#include <windows.h>

#include "../Definitions.h"

namespace _Warp
{
	class Mutex_win32
	{
	protected:
		CRITICAL_SECTION _critSection;

	public:
		Mutex_win32()
		{
			InitializeCriticalSection (&_critSection);
		}

		~Mutex_win32()
		{
			DeleteCriticalSection (&_critSection);
		}

		void Lock()
		{
			EnterCriticalSection (&_critSection);
		}
		void Unlock()
		{
			LeaveCriticalSection (&_critSection);
		}

		Bool TryLock()
		{
			return (Bool)TryEnterCriticalSection(& _critSection);
		}
	};
}
#endif

Now, threading problems can be hard to track down and debug, especially if you forget to Unlock the Mutex. So a Lock object is a way to help you clean up and unlock the Mutex when you're done. A Lock is created on the Stack in a local block of code, so when the program leaves the block of code the Lock gets deleted, the destructor gets called, and in the process the Mutex is automatically unlocked in the Lock destructor.

Lock.h:

#ifndef w_Lock
#define w_Lock

#include "../Data/Uncopyable.h"

#include "Mutex_win32.h"

namespace _Warp
{
	class Lock
		: private Uncopyable
	{
	protected:
		Mutex_win32* _pMutex;

	public:
		explicit Lock(Mutex_win32* pMutex);
		~Lock();
	};

	inline Lock::Lock(Mutex_win32* pMutex)
		: _pMutex( pMutex )
	{
		if(_pMutex != NULL)
		{
			_pMutex->Lock();
		}
	}

	inline Lock::~Lock()
	{
		if(_pMutex != NULL)
		{
			_pMutex->Unlock();
		}
	}
};
#endif

Here's an example of how to use a Lock and Mutex:

Mutex_win32* _pMessageListMutex = new Mutex_win32();//a mutex might typically exist in the header as a member variable
list<string> _messages = list<string>();// this 

void function()
{
	Lock lock = Lock(_pMessageListMutex);
	/* do stuff to the list */
}// when the program reaches here, the lock gets cleaned up and the _pMessageListMutex gets freed so another thread can access the _messages list without worrying about another thread accessing it at the same time

In case you didn't notice, the Lock class inherits from an "Uncopyable" class that doesn't allow the Lock to be copied or to be constructed from another Lock.  This helps prevent errors from happening, besides the fact a lock shouldn't be copied anyway; so this class ensures it can't be.  The Uncopyable class was inspired by the Boost Uncopyable class, though it wasn't the first site I ran across that showed something very similar.

Uncopyable.h:

#ifndef w_Uncopyable
#define w_Uncopyable

namespace _Warp
{
	// Inherit from this if you want a class to be unable to be copy-constructed.
	class Uncopyable
	{
	private:
		Uncopyable(const Uncopyable&);
		Uncopyable& operator=(const Uncopyable&);

	protected:
		Uncopyable(){}
		virtual ~Uncopyable(){}
	};
};
#endif

For those of you who don't know, the virtual destructor is required if any class inherits from Uncopyable, if you want it to properly be deleted. This should only be a problem if you store an object as an Uncopyable object, instead of it's own object type, and you try to delete it, the child's destructor will be properly called before the parent's destructor. Also, because the Copy constructor and copy operator aren't defined (besides the fact that they're private), you'll get a compiler error preventing you from doing anything you shouldn't be!

Both the Lock and Mutex class are pretty simple, so there isn't really much variation to them; I don't remember exactly which sites I used to lookup the Windows functions, otherwise I'd credit them for their help.  Either way, if you had trouble finding C++ Mutex and Lock classes, I hope you find these useful for your purposes!

You can download the project files here: Mutex, Lock, and necessary class files.

This is an improved Vector2 class I'm working on with suggestions from Leander Hasting, though I haven't touched upon all of them yet.  Beyond that, some of the critiques seem subjective to a point, and other professionals he pointed me to, make the same argument; and that is the argument of the use 0f non-member functions.  With intellisense working, I find using member functions to be the easiest way of doing things, as I think it is easier for other people to work with; as someone who's trying to write an engine, I understand the importance of including extra functions in a separate header file, though I think that can get messy.  So, with what is proposed you could do VectorUtil::len(vector), though having the VectorUtilthere is ugly, though without it there, how do you know that function even exists or where it's coming from?  So for starters, it's more useful to split the vector up like this, because everything doesn't need access to these functions, and it helps build times.  Though, in the end, when this engine is done, all of the information is most likely going to be included anyway;  lets say I want to add scripting support with my own version of intellisense, I want to make it as easy as possible for someone not used to my engine to be able to interactively see what they can do with a Vector by simply using "vector." and everything they have available to them pop up.  So, because the functions are accessing public members, they have no need to be member functions; so while some may claim using member functions breaks encapsulation, I think it makes it easier to open up a class to the user and what it can do.  Though it's interesting that intellisense in Visual Studio also shows private and protected functions you don't have access to...

Anyway, what I would like to do with my code is make it as easy as possible for anyone to use, I'm not worried that much about technicalities and hardcore programmers squirming over things I don't care about.  Though that makes me wonder, should I care about that, and perhaps just take it with a grain of salt?

Anyway, here's my Vector2 class in it's improved glory.

Vector2.h:

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */
#ifndef w_Vector2
#define w_Vector2

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

namespace _Warp
{
	typedef float Scalar;
	typedef int Bool;

	class Vector2
	{
	public:
		Scalar X;
		Scalar Y;

		Vector2();
		Vector2(Scalar x, Scalar y);

		Vector2& operator+=(const Vector2& pVector);
		Vector2& operator-=(const Vector2& pVector);
		Vector2& operator*=(Scalar num);
		Vector2& operator/=(Scalar num);

		Bool operator!=(const Vector2& vect) const;
		Bool operator==(const Vector2&; vect) const;

		friend Vector2 operator-(Vector2& vect);
		friend Vector2 operator+(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator-(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator*(const Vector2& vect1, Scalar value);
		friend Vector2 operator/(const Vector2& vect1, Scalar value);
		friend Vector2 operator*(const Vector2& vect1,const Vector2& vect2);
		friend Vector2 operator/(const Vector2& vect1,const Vector2& vect2);
	};

	inline Vector2::Vector2()
	{
	}

	inline Vector2::Vector2(Scalar x,Scalar y)
		: X( x )
		, Y( y )
	{
	}

	inline Bool Vector2::operator!=(const Vector2& vector) const
	{
		return X != vector.X || Y != vector.Y;
	}

	inline Bool Vector2::operator==(const Vector2& vect) const
	{
		return (*this != vect) == FALSE;
	}

	inline Vector2& Vector2::operator+=(const Vector2& pVector)
	{
		X += pVector.X;
		Y += pVector.Y;
		return *this;
	}

	inline Vector2& Vector2::operator-=(const Vector2& pVector)
	{
		X -= pVector.X;
		Y -= pVector.Y;
		return *this;
	}

	inline Vector2& Vector2::operator*=(Scalar num)
	{
		X *= num;
		Y *= num;
		return *this;
	}

	inline Vector2& Vector2::operator/=(Scalar num)
	{
		X /= num;
		Y /= num;
		return *this;
	}

	inline Vector2 operator+(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X + vect2.X,vect1.Y + vect2.Y);
	}

	inline Vector2 operator-(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X - vect2.X,vect1.Y - vect2.Y);
	}

	inline Vector2 operator-(Vector2& vect)
	{
		return vect * -1;
	}

	inline Vector2 operator*(const Vector2& vect1, Scalar value)
	{
		return Vector2(vect1.X * value,vect1.Y * value);
	}

	inline Vector2 operator/(const Vector2& vect1, Scalar value)
	{
		return Vector2(vect1.X / value,vect1.Y / value);
	}

	inline Vector2 operator*(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X * vect2.X,vect1.Y * vect2.Y);
	}

	inline Vector2 operator/(const Vector2& vect1,const Vector2& vect2)
	{
		return Vector2(vect1.X / vect2.X,vect1.Y / vect2.Y);
	}
}

#endif

VectorUtil.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_VectorUtil
#define w_VectorUtil

#include <cmath>

using std::sin;
using std::cos;
using std::sqrt;
using std::atan2;

#include "Vector2.h"

namespace _Warp
{
	class Vector2Util
	{
		static Scalar 	len(const Vector2& vect);
		static Scalar 	len2(const Vector2& vect);

		static Vector2& invert(Vector2& vect);
		static Vector2& normalize(Vector2& vect);
		static Vector2& clamp(Vector2& vect, Scalar value);
		static Vector2& setLength(Vector2& vect, Scalar value);

		static Vector2	polar		(Scalar x, Scalar y);
		static Vector2 	cartesian	(Scalar radius,	Scalar angle);
		static Scalar 	dot			(const Vector2& pVec1, const Vector2& pVec2);
		static Vector2 	rotate		(const Vector2& pVec, Scalar angle);
	};

	inline Scalar len(const Vector2& vect)
	{
		return sqrt(vect.X * vect.X + vect.Y * vect.Y);
	}

	inline Scalar len2(const Vector2& vect)
	{
		return vect.X * vect.X + vect.Y * vect.Y;
	}

	inline Vector2& invert(Vector2& vect)
	{
		return vect *= -1;
	}

	inline Vector2& normalize(Vector2& vect)
	{
		if(vect.X == 0 &amp;&amp; vect.Y == 0)
		{
			return vect;
		}

		Scalar length = len(vect);

		vect.X /= length;
		vect.Y /= length;
		return vect;
	}

	inline Vector2& clamp(Vector2& vect,Scalar value)
	{
		Scalar length = len2(vect);
		if(length &lt;= value * value)
		{
			return vect;
		}

		length = sqrt(length);

		vect.X *= value / length;
		vect.Y *= value / length;

		return vect;
	}

	inline Vector2& setLength(Vector2& vect, Scalar value)
	{
		if(vect.X == 0 &amp;&amp; vect.Y == 0)
		{
			return vect;
		}

		Scalar length = len(vect);

		vect.X *= value / length;
		vect.Y *= value / length;

		return vect;
	}

	inline Vector2 cartesian(Scalar radius,Scalar angle)
	{
		return Vector2(radius * cos(angle),radius * sin(angle));
	}

	inline Vector2 polar(Scalar x,Scalar y)
	{
		return Vector2(atan2(y,x),sqrt(x * x + y * y));
	}

	inline Scalar dot(const Vector2& pVec1,const Vector2& pVec2)
	{
		return pVec1.X * pVec2.X + pVec1.Y * pVec2.Y;
	}

	inline Vector2 rotate(const Vector2& pVec,Scalar angle)
	{
		Scalar cosResult = cos(angle);
		Scalar sinResult = sin(angle);

		//Essentially, apply a 2x2 rotation matrix to the vector
		Scalar newX = pVec.X * cosResult - pVec.Y * sinResult;
		Scalar newY = pVec.X * sinResult + pVec.Y * cosResult;

		return Vector2(newX,newY);
	}
}

#endif

Notes:

With this class, you can't do this:

Vector2 vect = 2;

This was possible with my old Vector2 class, and frankly should be an error.  If you are going to initialize the vars of a Vector2 at a later time, you can do this:

Vector2 vect = Vector2(Vector2::Uninitialized())

The reason for this is, doing this:

Vector2 vect = Vector2();

...creates a Vector2(0,0) by default. I could setup a default constructor and not use default values, however that could result in bugs from coders not properly initializing Vector2 objects. So, it is this reason the Uninitialized class is being used.

Feel free to use this improved Vector2 class, and if the c-style functions in VectorUtil bug you, feel free to make them member functions again in Vector2.

Download the Vector2 improved here: Vector2 class files.

[Update: As of 5/11/10 I noticed a typo, which I fixed, however I need to update the source files. I've also realized there are also a couple other utility functions I could "add", so will do so sometime soon; I got the idea from looking at another blog, however I realized he just named the functions to something easily understandable. For example, the dot and cross product; their names don't say anything about what the function really does, what the data represents. So, it seems useful to package up those functions to make it easier for programmers using this utility, and of course leaving the original functions in-tact (perhaps?) so other programmers looking for them won't be confused when they think they can't find them. So, more cool things to come! :) ]

It's a very simple class, but I wrote what I'm calling a Timer, it has similar functionality to a stop watch. The Basic timer class relies on the Windows QueryPerformanceFrequency, so here's the function necessary for my Timer class:

Time.h

#ifndef w_Time
#define w_Time

#include "../Definitions.h"

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>

namespace _Warp
{
	class Time
	{
	public:

		static Real64 HiResTime()
		{
			u64 ticks;
			u64 ticksPerSecond;
			Bool result = QueryPerformanceFrequency((LARGE_INTEGER*) &ticksPerSecond);
			if(result == 0)
			{
				return -1;
			}
			result = QueryPerformanceCounter((LARGE_INTEGER*) &ticks);
			if(result == 0)
			{
				return -1;
			}
			return (Real64) ticks / ticksPerSecond;
		}
	};
};

#endif

Timer.h

#ifndef w_Timer
#define w_Timer

#include "../Definitions.h"

namespace _Warp
{
	class Timer
	{
	protected:
		Real64 _start;

		Bool _running;

	public:
		Timer();

		void Start();
		void Stop();
		void Reset();

		Real64 Get_Microseconds() const;
		Real64 Get_Milliseconds() const;
		Real64 Get_Seconds() const;

		Bool IsRunning() const;
	};
};

#endif

Timer.cpp

#include "Timer.h"

#include "Time.h"

namespace _Warp
{
	Timer::Timer()
		: _start( 0 )
		, _running( FALSE )
	{
	}

	void Timer::Start()
	{
		// this allows the timer to continue from where it left off
		_start = Time::HiResTime() - _start;
		_running = TRUE;
	}

	void Timer::Stop()
	{
		if(_running == TRUE)
		{
			_start = Time::HiResTime() - _start;
			_running = FALSE;
		}
	}

	void Timer::Reset()
	{
		if(_running == TRUE)
		{
			_start = Time::HiResTime();
		}
		else
		{
			_start = 0;
		}
	}

	Real64 Timer::Get_Microseconds() const
	{
		if(_running == TRUE)
		{
			return (Time::HiResTime() - _start) * 1000000.0;
		}
		return _start * 1000000.0;
	}

	Real64 Timer::Get_Milliseconds() const
	{
		if(_running == TRUE)
		{
			return (Time::HiResTime() - _start) * 1000.0;
		}
		return _start * 1000.0;
	}

	Real64 Timer::Get_Seconds() const
	{
		if(_running == TRUE)
		{
			return Time::HiResTime() - _start;
		}
		return _start;
	}

	Bool Timer::IsRunning() const
	{
		return _running;
	}
};

Here is a sample of how to use my timer class:

Timer timer = Timer();
timer.Start();
/* do stuff here */
timer.Stop();
Real64 seconds = timer.Get_Seconds();
timer.Reset();//reset the timer so it's total count is back to zero seconds.

timer.Start();
/* time something else */
timer.Stop();
/* do something */
timer.Start();//continue the count from where the timer left off
/* time something again*/
timer.Stop();
seconds = timer.Get_Seconds();// this is the total count of seconds from the last two timing sessions since Reset wasn't called

You can find the blog on the Definition.h file here.

Or download all of the above files and Definition.h here: Timer project files.

This is a simple definitions file that I use in my game engine, though this version was dumbed down for a 2D game engine I'll be working on.

Definitions.h

#ifndef w_Definitions
#define w_Definitions

#ifndef NULL
#define NULL 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define NUKE(object)	{ if(object)	{ delete (object);		(object) = nullptr; } }
#define NUKE_ARRAY(object) { if(object) { delete[] (object);	(object) = nullptr; } }
#define RELEASE(object) { if(object)	{ (object)->Release();	(object) = nullptr; } }

namespace _Warp
{
	typedef signed char s8;
	typedef unsigned char u8;
	typedef signed short s16;
	typedef unsigned short u16;
	typedef signed int s32;
	typedef unsigned int u32;
	typedef signed long long s64;
	typedef unsigned long long u64;

	typedef unsigned int Bool;
	typedef u8 Byte;

	typedef float Real32;
	typedef double Real64;
};
#endif

These are the base data types I use everywhere in my game. Instead of using the 1 byte bool, I use a custom defined Bool which is the size of an integer; when compiled for a 32 bit system will coincide with 4 byte alignment, and compiled for a 64bit platform will coincide with 8 byte alignment. For more information on byte alignment, check out this wikipedia article.

Some of the macros are also useful for memory management, specifically NUKE, NUKE_ARRAY, and RELEASE. RELEASE is used on things like DirectX objects: RELEASE(_d3dDevice); basically, if you can't tell, any object that has a function called Release can be used with this macro. It checks to see if the object is valid, releases it, and sets the pointer to NULL. NUKE works on object you create using the 'new' operator, and properly sets the pointer to NULL. For example, cleaning up a Vector3:

Vector3* pVect = new Vector3(0,1,0);
/* other code here */
NUKE(pVect); // pVect gets cleaned up and set to NULL, aka, it is now nuked. ;p

And NUKE_ARRAY is used similarly on an array that was dynamically allocated, using new.

Definitions.zip

The last two years of my life at RIT leaves something to be desired, as a result I've been itching to get out of here and go somewhere else that will help re-ignite my passion for learning and programming.

Nothing bad about RIT in particular, it's just how school systems are, requiring you to take a whole bunch of classes that have nothing to do with your major.  I'm paying money to go to this school, and I don't think it's fair that I'm forced to take classes I don't want to take.  I realize they're supposed to help make me more well-rounded, but why do I have to take so many of them??  I just know I could've gotten a better programming experience if I went to a different school, though that's what I'm hoping for by going to graduate school.

So, in trying to spark my passion for programming and making games, I'm thinking of going to Digipen in Washington state, or Southern Methodist University: Guildhall in Texas.  I'm also looking to get a job for the next 6 months.


Overall, I know I want to try to develop a really cool game in my free time, and try to market it myself as an indie developer to try to make some money, and to help myself get my name out there to make it easier to be hired from a company.  You know, good resume material.  I'm also doing it to learn more about game programming, so it's an educational pursuit as well.  I already have ideas in mind, though they're technically challenging and will take some time.  However, I have thought about making a 3d fan version of ZZT, I just don't know if I'd have any lawsuit kind of stuff to worry about; if I did do such a thing, I know I probably couldn't sell it, but I'd encourage people to donate money if they appreciate the work. Anyway, just a thought, as I would love to see ZZT become almost mmo like material, or at least have online content sharing similar to Little Big Planet or what have you.  One thing that would also psych me out, is if my game supported importing standard .zzt games; though as the engine is 3d, I've been considering taking it into the 3d realm, especially considering the popularity of Minecraft.  The other games I want to make are technically challenging because they require some 3d physics stuff, obviously a 3d battle system with somewhat realistic targeting and reactions, and from there it's necessary to have a sophisticated animation system with something like rag doll support.  I also reaally want to mess around with graphics and making things look cool and pretty!


Anyway, I'll be posting more code stuff soon, like a modified Vector2 class after the early somewhat naive version being critiqued by the Leander Hasty, lead programmer at 1st Playable Productions.  I plan on putting up a Matrix_4x4 implementation, in which I first learned and started using the c++ "union" feature, allowing me to store and access data in a way that works with DirectX and OpenGL, or however I wanted; though I have to make tweaks to it based off of the recommendations of Leander, and rename a few things here and there.  I also plan on writing a basic tutorial explaining rotation matrices and what they actually represent, as classes and books I have read had failed to explain them in an easy coherent way.

Oh, as a side note, I had a lot of fun the other night working on a threaded server to setup a basic protocol for a simulated game environment; I hadn't worked with threads before in C++, so I'm eager to add support for them in my 3D engine, Warp.  Also on that note, I'll be adding a lot more on this engine, and making a project page for it with helper classes for you to feel free to use in your own projects.  I'll also mention all the various books I've been reading, as well as the open source game engines I've looked at, to try to inspire my design to create a cross-platform 3d game engine.  So the basic idea for my Warp Engine: it's a game engine that abstracts the hardware and software API's so you can write a game that works across multiple platforms without having to change much; the way to do this is through the use of interfaces and components implemented by a platform by platform basis.  Oh, and another thing I would like to look into is adding support for processors with SIMD instructions so my Vector3 and Matrix4x4 class can be more efficient.  Basically, there are too many things I want to do and to learn!! (:

I could ramble on for almost forever, so feel free to leave any thoughts if you might have them!

Archive