Hard Reset

My buddies at Flying Wild Hog have announced their first project recently. It’s a dynamic cyberpunk FPS with character progression elements. Make sure to check out the teaser: Been a long time since I’ve been to Poland so had no chance to play it, but after talking with people who did and knowing the team behind it – I expect good stuff. Old comments Branimir Karadzic 2011-07-19 18:47:27 It looks pretty cool!

Flattening trees

Trees are one of the most popular structures in game development. Your skeletal hierarchy, your attachments – all this can be represented using trees. They lend nicely to short & clean code, especially with recursive functions – you typically perform your operation on a root, then call the same function for all children. Problem is – it’s not always the most effective way of doing things. Consider the most canonic form of tree traversal:

Hidden enemy

Consider the following piece of code: void FindFrames(const S* seq, float d, UINT& outFrameA) { const UINT n= static_cast<UINT>(seq->fd.size()); outFrameA = 0; while(outFrameA + 1 < n && seq->fd[outFrameA + 1] < d) { ++outFrameA; } } Looks innocent, right? Well, it was slow enough to show up quite high in the profiler… It might seem surprising at first, but if you’ve done some console programming in the past, you can probably recognized our old foe - load-hit-store here.

Demoscene tribute - Camorra

Camorra was a Polish demoscene group. They might have not gained same level recognition as Sunflower/Pulse, but they sure were one of the best squads in the first years of Polish PC scene. Camorra actually won the first Polish PC party - General Probe 1995. Sadly, couldn’t find this winning demo (Gust) anywhere. Let’s start with Gustation then. It’s their 64k intro from CAF 1995, took 2nd place behind Why by Adrar Design:

Riddle

Normally, I try to avoid C++ bashing, so trendy nowadays. It is what it is, but we’ve to use it anyway. Today, however I encountered a funny bug that made me wonder a little bit. Consider the following snippet:

Conditional breakpoints on steroids

Imagine a situation where you’re debugging some problem and need to set a breakpoint in function that’s called very often from many points in your application (like operator[] in your array class for example). Thing is, you’re only interested in one particular codepath, as that’s where things go wrong, calls from other places are fine. If you simply set a breakpoint in line that interests you, it’ll trigger hundreds of times every frame, making it tricky to find the moment that’s interesting for us.

A little bit of fun

This recent tweet: "SomeEnum blah : 8;" Added new enum elements so max value is now >127. GUESS WHAT HAPPENS. — Fabian Giesen (@rygorous) April 1, 2011 from Ryg reminded me of another old story related to bitfields in C++. Consider the following piece of code: typedef char BOOL; ... // Some other file struct SomeStruct { BOOL m_something : 1; BOOL m_isVisible : 1; BOOL m_somethingElse : 1; BOOL m_someOtherStuff : 5; .

Cruncher - Google code project

Remember Cruncher#? That’s my little tool for extracting structure layout information from PDB files. It’s pretty much done and I rarely modify it, but from time to time something irritates me enough to force me to get back to it. Recently I’ve added simple, but useful feature. If you double click member variable, it’ll automatically jump to it’s type definition (if it can find it, it must be another UDT). Example:

GDC 2011

Not sure if it has much sense in the era of Twitter (everyone who’s interested can easily find links there), but let’s try. Some of GDC2k11 proceedings: Networking for Physics Programmers 2011, Glenn Fiedler (SCEA). PDF version here. Crash Analysis and Forensic Debugging, Elan Ruskin (Valve). Normal Offset Shadows, Daniel Holbert (High Moon Studios). Thanks, Ignacio! NVIDIA Game Technology Theater videos + some slides. Found by Guille.

vector constructor iterator

As promised, today a little bit about mysterious ‘vector constructor iterator’. Essentially, it’s a function generated by MSVC to initialize arrays of UDTs. Unfortunately, sometimes compiler gets confused and tends to spit out superflous code. Consider the following example, taken almost as-is from certain engine (names hidden/changed to protect innocent):

Attack of dynamic initializers

Recently, I’ve been looking a little bit what’s taking space in our executables and found an interesting ‘feature’ of MSVC. It has troubles with expanding floating-point constants that rely on another constants (…that rely on another constant, yes it requires 2 levels of indirection to break). Consider the following example:

Retro Pinball

As you might know, our CEO is the author of the classic Epic Pinball (coded 100% in assembler, obviously :). I’ve spent long hours playing the original, especially the Deep Sea table. Recently, our company in cooperation with Big Blue Bubble, created an Iphone/Ipad version of this game. I don’t have an Iphone, but played it a little bit at the office and it’s just as entertaining as it was, especially the ‘table feeling’ is really well preserved.

Compile time log2

Been working on some wrappers over data containers allowing to move code to SPU easier recently and found myself in need of a compile-time log2 (for shifts, so integers only). Luckily, it’s pretty straightforward to achieve using some template voodoo and boils down to using fact that log2(x) == log2(x / 2) + 1:

Reflection in C++ – metadata

About a year ago I published a few articles on my experiments with C++ reflection system. It extracts all the type information from PDB files. Nice thing - it’s all automatic and requires none to very little source code changes. One thing I didn’t like was problem with adding metadata to our types/fields. It’s mostly for editing purposes, but wouldn’t it be nice to have at least a help/description string for fields?

TMplayer to MicroDVD converter

One of my Christmas presents (that I bought myself) was WD TV Live Plus media streamer. I left my projector back in Warsaw (sniff) and I was tired of watching stuff on my 15” laptop. WD TV is a pretty neat little machine, it effortlessly plays every video I throw at it. The only problem I had was that it seemed to struggle with TMPlayer subtitle format which is very popular in Poland for some reason.

Quick iteration, insertion, look-up, removal

Wouldn’t it be nice to get all four of those with some container type? Sadly, it seems quite tricky. Vector gives the most efficient iteration and pretty good insertion (at tail), but is more problematic when it comes to look-up & removal. Intrusive linked lists are pretty good here, but pointer chasing may hurt during iteration. Hash map falls somewhere in the middle, but again - iteration will most probably be slower than vector (we have to skip over empty buckets).

DIG 2010

On Thursday/Friday we had DIG conference here in London. I was quite surprised there is something like that and even more surprise when I found out it’s actually quite big, with DE & other local companies, local universities, hordes of students and interesting lectures. I come from a country where game development is still considered exotic, not very serious career choice. It’s a refreshing change to participate in gaming event organized with so huge support from the city, with London mayor attending.

MemTracer - episode IV

(I’m seriously running out of subtitle ideas). Some years ago I started to toy with an memory tracing/debugging tool idea. First proof-of-concept implementation has been created in few days and while it worked with a very simple test app, it required major overhaul before integrating with any real-world program. Somewhere in February 2008 I had a new version, that proved itself very useful during my adventure with enhanced version of certain PC RPG (as it later turned out, it was by far the most memory stressing project’).

Declaration matching

I encountered an interesting problem today. Consider the following piece of code: namespace Test { struct Lol {}; struct Cat {}; struct Foo { virtual void Do(Lol&); virtual void Do(Cat&); }; struct Bar : public Foo { virtual void Do(Lol&); void DoSomethingElse() { Cat cat; Do(cat); } }; } Question: what happens when you execute Bar::DoSomethingElse? Answer: nothing, as trying to compile this piece of code will result in the following error: ‘Test::Bar::Do’ : cannot convert parameter 1 from ‘Test::Cat’ to ‘Test::Lol &’.

Some more benchmarks

Gave tr1::unordered_map a try, it seems to do perfectly average, nothing spectacular, nothing awful, except for predict_grow with 4 byte objects, where it’s almost 10x slower than the next implementation (that’s not an anomaly, it happens every time). I also found a bug in RDE where I overoptimized it a little bit - could result in a crash when searching for item that’s just been removed. It slowed fetch by about 3%, however later I found a way to remove some branches and sped it up by ~6% again, so final version is even faster.