Archive for the ‘programming’ Category

h1

threading the memory management and future dev plans

July 2, 2009

So, I finally got the memory management system threaded and defeated the only race condition, which could be found on the close down because of the order it waited for shit in. I fixed it with a shut down event that would poke when both mutexes were released in a timeout waiting loop so there was no wrong order to wait for them in. Anyway, I’m not here to show you that, but instead my threading library. It’s very bare bones, and only has a Win32 implementation for now, but could easily be implemented in another threading library, and I will do so with pthreads sometime in the future.

But I want to show it. I will show it now. SHOWING!

It makes use of factories and singletons, but those should be obvious in terms of their functionality. Factory inherits Factory<Singleton > as well. I might change this if it becomes more efficient to create multiple factory instances for different creation modes (i.e.) each has a different set of creation parameters.

threading.h
#ifndef THREADING_H
#define THREADING_H

#include
#include
#include
#include
#include
#include

#include “dlmalloc_object.h”
#include “factory.h”

namespace SpaceSim
{
class WaitingObject: public DLMallocAlloced
{
protected:
static std::list *wobjs;
public:
WaitingObject();
~WaitingObject();

static bool WaitForAll(std::list *objs = NULL);

virtual bool Wait() = 0;
};

class Mutex: public WaitingObject
{
public:
static Mutex *Create(bool is_global = false, unsigned long spincount = 0x80000400);

virtual bool Lock() = 0;
virtual void Unlock() = 0;

virtual unsigned long SpinCount() const = 0;
};

class GlobalMutex: public Mutex
{
protected:
HANDLE mutex;
public:
GlobalMutex();
~GlobalMutex();

virtual bool Lock();
virtual void Unlock();

virtual bool Wait();

virtual unsigned long SpinCount() const;
};

class LocalMutex: public Mutex
{
protected:
unsigned long spincount;
CRITICAL_SECTION mutex;

public:
LocalMutex(unsigned long spincount);
~LocalMutex();

virtual bool Lock();
virtual void Unlock();

virtual bool Wait();

virtual unsigned long SpinCount() const;
};

class Event: public WaitingObject
{
protected:
HANDLE event;

public:
static Event *Create();

Event();
~Event();

bool Wait();
void Poke();
void Reset();
};

typedef int (*ThreadMainProc)(void *args);
typedef unsigned long ThreadID;

class Thread: public WaitingObject
{
protected:
void *args;
HANDLE thread;
ThreadMainProc proc;
bool is_running;

public:
static Thread *Create(ThreadMainProc main_proc, void *args);
static ThreadID GetID();

Thread(ThreadMainProc main_proc, void *args);
~Thread();

bool Run();
bool Break();
bool Wait();

bool IsRunning() const;
};
};

#endif

threading.cpp
#include “threading.h”
#include “logger.h”

namespace SpaceSim
{
std::list *WaitingObject::wobjs = NULL;

WaitingObject::WaitingObject()
{
if (!wobjs)
wobjs = new std::list;

wobjs->push_back(this);
}

WaitingObject::~WaitingObject()
{
wobjs->remove(this);

if (wobjs->empty())
{
delete wobjs;
wobjs = NULL;
}
}

bool WaitingObject::WaitForAll(std::list *objs)
{
bool success = true;
if ((!objs) || objs->empty())
objs = wobjs;

std::list::iterator it;
for (it = objs->begin(); it != objs->end(); ++it)
success = success && (*it)->Wait();

return success;
}

class MutexFactoryParameters: public FactoryParameters
{
public:
bool is_global;
unsigned long spincount;

MutexFactoryParameters(bool is_global = false, unsigned long spincount = 0x80000400):
is_global(is_global), spincount(spincount) {}
};

template<> class Factory: public Singleton >
{
public:
virtual Mutex *Create(const FactoryParameters &params)
{
const MutexFactoryParameters &mparams = param_cast(params);

if (mparams.is_global)
return new GlobalMutex();
else
return new LocalMutex(mparams.spincount);
}
};

Mutex *Mutex::Create(bool is_global, unsigned long spincount)
{
return Factory::GetSingleton().Create(MutexFactoryParameters(is_global, spincount));
}

GlobalMutex::GlobalMutex()
{
static unsigned long mtctr = 0;
char name[256], cvbuf[16];

ltoa(mtctr++, cvbuf, 16);
strcpy(name, “SPACESIM_MUTEX_0x”);
strcat(name, cvbuf);

assert(mutex = CreateMutex(NULL, FALSE, name));
}

GlobalMutex::~GlobalMutex()
{
CloseHandle(mutex);
}

bool GlobalMutex::Lock()
{
return WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0;
}

void GlobalMutex::Unlock()
{
ReleaseMutex(mutex);
}

bool GlobalMutex::Wait()
{
bool ls = Lock();
Unlock();
return ls;
}

unsigned long GlobalMutex::SpinCount() const {return 0;}

LocalMutex::LocalMutex(unsigned long spincount): spincount(spincount)
{
assert(InitializeCriticalSectionAndSpinCount(&mutex, spincount));
}

LocalMutex::~LocalMutex()
{
DeleteCriticalSection(&mutex);
}

bool LocalMutex::Lock()
{
EnterCriticalSection(&mutex);

return true;
}

void LocalMutex::Unlock()
{
LeaveCriticalSection(&mutex);
}

bool LocalMutex::Wait()
{
bool ls = Lock();
Unlock();
return ls;
}

unsigned long LocalMutex::SpinCount() const {return spincount;}

Event *Event::Create()
{
return Factory::GetSingleton().Create(FactoryParameters());
}

Event::Event()
{
static unsigned long evctr = 0;
char name[256], cvbuf[16];

ltoa(evctr++, cvbuf, 16);
strcpy(name, “SPACESIM_EVENT_0x”);
strcat(name, cvbuf);

assert(event = CreateEvent(NULL, TRUE, FALSE, name));
}

Event::~Event()
{
CloseHandle(event);
}

bool Event::Wait()
{
return WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0;
}

void Event::Poke()
{
SetEvent(event);
}

void Event::Reset()
{
ResetEvent(event);
}

class ThreadFactoryParameters: public FactoryParameters
{
public:
void *args;
ThreadMainProc proc;

ThreadFactoryParameters(ThreadMainProc proc, void *args): proc(proc), args(args) {}
};

template<> class Factory: public Singleton >
{
public:
virtual Thread *Create(const FactoryParameters &params)
{
const ThreadFactoryParameters &mparams = param_cast(params);

return new Thread(mparams.proc, mparams.args);
}
};

Thread *Thread::Create(ThreadMainProc main_proc, void *args)
{
return Factory::GetSingleton().Create(ThreadFactoryParameters(main_proc, args));
}

struct proc_attribs
{
ThreadMainProc proc;
void *args;
Event *mevent;
};

static DWORD WINAPI __ThreadMainProc(LPVOID param)
{
proc_attribs &pa = *((proc_attribs *)param);

ThreadMainProc proc = pa.proc;
void *args = pa.args;

pa.mevent->Poke();

return proc(args);
}

ThreadID Thread::GetID() {return GetCurrentThreadId();}

Thread::Thread(ThreadMainProc main_proc, void *args): proc(main_proc), args(args) {}

Thread::~Thread()
{
if (is_running) Break();
}

bool Thread::Run()
{
if (is_running) return false;

DWORD temp;

proc_attribs pa;
pa.args = args;
pa.proc = proc;
pa.mevent = Event::Create();

thread = CreateThread(NULL, 0,
__ThreadMainProc, (void *)&pa, 0, &temp);

is_running = (bool)thread;

pa.mevent->Wait();
return is_running;
}

bool Thread::Break()
{
if (!is_running) return false;

bool success = CloseHandle(thread);
is_running = !success;
return success;
}

bool Thread::Wait()
{
if (!is_running) return false;

bool success = (WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0);
return success && Break();
}

bool Thread::IsRunning() const {return is_running;}
};

Now, for stuff more interesting to the consumer who buys the final game (yes… the game will be sold, and I don’t care if people see snippets of the code). The Actor and StaticObject classes will extend the SceneObject class, and all that good stuff will be Lua bound. Actors will be partly virtual and will have to have trigger functions such as being told where to go by the controller filled in. This would be in certain implementations, especially ships and the like. Anyway, that about says it and all that good stuff. I’m making tracks, and it is AWESOME.

h1

reference counter based memory management + bitching about life

June 8, 2009

The bitching about life part comes first.  I believe the DCFC song “No Sunlight” sums up my rant in that regard nicely, so I won’t waste the space here.  Okay I’m done with that.

Now, on to the not depressing stuff.  I was thinking of ways I could potentially speed up memory management with threads.  I was basically thinking along these lines:  I should queue my object deletions so that I can delete them on the side while the next iteration is in progress.  So I came up with an interesting system.  I haven’t implemented the threading yet, but I have seperated object deletion from the main loop entirely and it’s just tacked on the end for now.

Basically I implemented a reference counter object management system.  Each ManagedObject has a grab() and drop() method, used to count references.  When the number of references reaches zero, the drop() method calls the queue_deletion() method in the ObjectManager singleton.  The ObjectManager also keeps track of ManagedObject’s that are still kicking, so that they can be cleaned up at the very end if they weren’t properly dropped.  This should keep memory leaks from being as bad, though that doesn’t mean I won’t bust my ass trying to find all of them.  So the current code for updating is as follows:

void Engine::RunMainLoop(double timestep)
{
while (running)
{
if (!Update(timestep)) running = false;
if (!Render()) running = false;
ObjectManager::Singleton().CleanUp();
}
}

The ObjectManager deletes all things queued for deletion in CleanUp(). What I could do is simply start a cleanup thread that cleans up every second or so. For the threaded version it will lock the mutex for the queue to copy it over to a private queue and clear the public one so that it can be used again while the cleanup iterator goes through and deletes everything added previously. If you want the full classes, I shall have t3h c0dez in an article on custom memory management for C++ classes shortly.

EDIT: Okay, article’s up. It’s called “C++ custom memory management primer”. Link under My Articles in the sidebar.

h1

OGRE integration

June 6, 2009

Well, I’m beginning to integrate OGRE, and lemme tell you… it’s growing on me. I also find that it can actually be quite slim when you leave out the utility components and do most things yourself. I just want it’s fantastic material system. I’m beginning to figure out just how unbelievably moddable this can make the game as well. In addition to loading an Actor file for every ship, that actor file will reference an OGRE material and mesh file, which is also fully moddable. I’ve also mastered the material abstraction system. For example, you can create a base class material called ship_material that implements normal mapping and paralax mapping over a main texture with all textures referenced by alias, then extend it with set_texture_alias on each ship, so none of that fancy shit has to be replicated, just say which textures to use and reference the .mesh in the Actor file. bam! I love modularity.

h1

Continuum Engine

June 3, 2009

That’s the name I have for it now.  It’s a badass name, no?

Anyway, I’ve got 3demon engine working as a rendering engine for now, but I still hate the Irrlicht style shadows it uses.  It IS a branch of Irrlicht.  They’re just so… broken.  They don’t even have a consistent appearance across subsystems.  OpenGL has a different volume method from D3D9 in it.  I want something like OGRE, but I absolutely hate the way it’s organized.

Does anyone have an idea as to what I should do?  I don’t want to use my own rendering engine because I’d like the focus of this project to be on the game itself this time, not every little technical thing to support it.  I will give OGRE a shot, and if that’s how it has to be, so be it.  But do you absolutely HAVE to use the ReferenceApp layer?  That, I put to you, is TERRIBLE API design.

h1

homeworld 2 like engine and other happenstance

May 27, 2009

So if you’ve never played Homeworld 2, then too bad for you because you missed out.  Big time.  That being said, when attempting a mod of it, I was immediately inspired by how unbelievably modular and streamlined it was.  It’s a space combat simulation with incredible levels of detail and realism, and it was modded in to a naval combat sim with the same level of detail, and graphics to make it look like it’s own game.  This is with no actual access to the engine source code.  So I’m like:  DAYUM SON.

I am attempting to create a modular engine of the likes.  You could also compare this engine to the Cortex Command engine, but CC is a totally different beast, because of it’s focus on pixel graphics and physics.

I’ve had one false start already, because I hadn’t thought the iterface through entirely.  Abstracting a camera as an actor makes sense, but only if you can unify it under the controller class, which would be a horrible mess.  Also, in order to get the root entity crap to work, and still have a new entity add itself to the singleton engine, I had to derive an otherwise worthless class to do this, in order to keep GetSingleton() from locking up the first time it’s called.

In other words, a disaster of bad code.  I’ve taken a few lessons in engine design away from it though, and I will start a new one, hopefully with less fail.  I’m drawing up a new inheritance tree right now.

And in terms of life, it’s being something of a bitch and something of a thing which is awesome.  I let slip about how I’m a rollercoaster of genetic disorders that will crash and burn before my time, and Travis just said, “well, we’ll make it a time ’till then, brother.”  Which I found extremely heart warming but also extremely sad.  Sigh.  It bugs me that I still can’t tell if I’ll be leaving anything behind, and it’s a loss for someone no matter what the case.

You should all check out Inhuman Comic, because it’s more baller than your mom’s genetalia.  OOOOO BURN.

That’s about it for now.

h1

first post in a long while + some erosion progress

March 15, 2009

Well apparently school takes up time.  So it’s been a while.  But here goes:

I got all A’s on my midterms, so fuck YES!  I feel happy about that.  Good times.  I have been spending an increasing amount of time with other people as well.  I know, crazy right?  It’s me.  Apparently some people don’t hate my guts, and I seem to have met some in person.  They are decidedly cool.  Hence that last post about Travis’ birthday.  So, yeah.

What else?  Oh, making progress on the Qix clone, Erosion.  Here you go:

It has a game state machine with GAME OVER and gameplay states and whatnot.  It has much better graphics now, I implemented bloom with my old shader framework and improved the color scheme.  You can die, and I’ve even got gamepad working with rumble on collisions and all.  You will also notice that I replaced the simple bouncing bar with a bar with a thruster in a damped system that actually semi-tries to follow you.  Enjoy this clip:

h1

tesselation + travis’ b-day

February 23, 2009

Both are filled with good times.  My good man Travis turned 17 on Thursday.  Yesterday we had had a b-day party at Ian’s place, and it was a fucking good time is what it was.  I can’t handle big parties, I hate ’em, but it was really just a few close friends just hanging out.  Which is my favorite.  I can’t handle too many people, or else I do an Asperger’s freakout.  I played some guitar, explained some autonoma theory, talked about stuff, then got blitzed and turned in to a sentemental cartoon of a wino.  I’d say my +20 liver of steel diety level holy liquor containment was definitely called upon.  I rarely drink so much.  But anyway.  I also recorded some hilarious footage, but I was told posting it would be in bad taste, so no drunken antics for you.

But here are two pictures:

Travis recites a random Lord of the Rings passage to Cat in the spirit of awesome.

Travis recites a random Lord of the Rings passage to Cat in the spirit of awesome.

SHR3DZ0RZ

You know what else totally shreds?  Tesselation algorithms!  Check this shit out:

  1. Walk around loop and record all x and y values in respective lists.  O(n) [iterate through nodes and copy values to lists]
  2. Remove duplicate x and y values, treating the lists independently.  O(n) [iterate through lists, remove and continue only]
  3. Divide the space in to tiles using the x and y values from the nodes as seperate lists.  O(1) [create tile array]
  4. Scan the tiles left to right, top to bottom.  Anywhere possible: Grow a rectangle right and down for each iteration until as much space as possible is full.  Repeat until all scanned.  O(amortize(n))

Conclusion: this is a good-ass algorithm!  BAM!

h1

qix meets physics!

February 11, 2009

I’m currently working on a clone of Qix called Erosion.  It was assigned to me by Dr. Liow.

So, after getting the very basic bare bones of Erosion’s logic working, it struck me what would be about the coolest twist to Qix ever!  If I integrated physics!  Tada!!!  Fucking A!  It just so happens I’ve cooked up a little physics engine you all probably know about.  Soooooo, here you go, alpha test 1.  And hey, I was apparently listening to Opeth while coding, and it was picked up by the video recorder during the test! \m/

Bitching, yo.

h1

epic viking swordfather stew + qix progress

February 9, 2009

So, I got back from Ian’s earlier today, and let me tell you.  Best time I’ve had in quite a long while.  We lit a fire in the backyard as evidenced in this terrible cellphone picture:

FIRE IS PRETTY NARM

FIRE IS PRETTY NARM

From left to right: Travis or Chris (can’t tell from this shitty picture), Cat, Caroline, and Ian.  Then, we made some kickass Viking stew for our kickass Viking selves, and we were filled with the passion of the swordfathers to once again pillage and burn!  But instead we just fell asleep in front of “Aliens”.

Also, as it turns out, Ian is quite a fine musician.  He offered to maybe jam with me sometime!  How cool is that?

But, hey!  Progress on Qix!  I will show you once I have the filled area tesselator working.  The movement and drawing and topology works perfectly, and all that remains is scoring and badguys.  Trucking RIGHT ALONG BITCHES!  🙂

h1

spelunky! + projects + GOGGLES OF DEATH

January 31, 2009

So, I came across a great indie game called Spelunky!  It’s unbelievable.  Imagine every rogue type game you’ve ever played, then imagine that the micromanagement components were replaced by fast paced platforming.  Now imagine that it’s all wrapped up in an awesome Indiana Jones cliche with hilarity abounds!  That’s Spelunky.  It is by a gentleman by the name of Derek Yu.

It has the idol on a pedestal with boulder trap deal, it has the damsel in distress deal, it has crossbow mask traps, spike traps, and monsters.  You can throw ropes and climb on them, you have bombs, you can visit shops to get things, stuff like that.  You can even kill the shop keeper or the damsel if you really want to!  Anything and everything can be done to anything and everything.  Rogue game like concepts and flexibility, platformer fun, Jones ancient cave defiling humor.  Did I mention there’s old school chiptune tracker music in it?  GOOD music.

What else?  Well, Dr. Liow gave me some side projects, because he rightly figured that my classes are too boring.  One, a topological solver.  Two, a Qix clone.  I’m making progress on both.  We’ll see how it goes.

The one you guys would probably like is the Qix clone.  If you don’t know about Qix, it’s an old game that introduced the fill it in concept.  You basically fill in the area around a bouncing Qix (laser line thingy) without being hit by the Qix while out in the open.  You must capture a supermajority of the area around it.  There are sparx on your inside loop (the only place you can move on aside from drawing new areas) forcing you to go out in the open.  They will always hit you if you don’t venture out, because you are on a loop, and one travels clockwise and the other travels counterclockwise.  This wiki should shed more light on the specifics for you.

I’ve designed a reversible linked satellite list to solve the topology problems of this evolving loop structure with nodes linking in from outside.  It actually iterates and traces the structure keeping track of old values, so we never go backwards.  This means the topology of the list is NOT effected by switching the nodes.  This allows us to have a much looser and more dynamic linkage structure, essentially freeing us from explicit directionality.  This not only allows reversal of a satellite list in constant time, but it also means that it becomes completely unnecessary to calculate a path for the sparx to get on to the main path.  They just launch two iterators, the first to find the main loop wins, then two iterators are launched from there to find the clockwise / counter clockwise relationship on the loop for you.  This important as the order of the links on the nodes is arbitrary with this structure!  Tasty data structures abound, I love it.

Lastly, at the roller rink on eighties night, there are many interesting people.  Among them is a girl who wears traditional costumes with goggles.  All the time.  And she got an UPGRADE!  The old welding goggles were cool and all, but she now has a pair of GERMAN DRIVING GOGGLES WOOO!  And she built in some crazy awesome magnifiers that look all evil geniusy.  And in the discoed out light show, they’re even cooler!  Observe:

MWAHAHAHAHAHA

MWAHAHAHAHAHA

I’ve got a history paper to write, and I need to have my programming assignments (my actual for credit ones) done by Monday.  So I’ll catch you all later.