Game Programming, Etc.

Games, programming, and related topics — by John Giors

Archive for the ‘Programming’ Category

#ifdef vs #if (part 1)

Posted by jgiors on 2009-03-27

In C/C++, it is common to compile some sections of code conditionally, e.g. debugging code, new untested features, cross-platform support, etc. The most common way to conditionally compile code is to use the #define preprocessor directive, then bracket conditionally compiled code with either #ifdef or #if.

Here is a simple #ifdef example:

#define DEBUG_SYSTEMX  //remove this #define to disable (e.g. comment-out this line).
//...
#ifdef DEBUG_SYSTEMX
    //... system x debugging code ...
#endif

And, here is a simple #if example:

#define NEW_FEATURE  1  //change 1 to 0 to disable
//...
#if NEW_FEATURE
    //... new feature code ...
#endif

Both of the above accomplish the same thing (conditional compilation), but they have different implications, e.g. the following will cause a compiler error when DEBUG_SYSTEMX is defined:

#if DEBUG_SYSTEMX  //BAD! #if WHEN IT SHOULD BE #ifdef
    // ... system x debugging code ...
#endif

However, when DEBUG_SYSTEMX is not defined, the code will be compiled out because the preprocessor treats undefined macros as 0 in conditional tests (which just so happens to match expectation).

The following would not work as intended, either:

#ifdef NEW_FEATURE  //BAD! #ifdef WHEN IT SHOULD BE #if
    // ... new feature code ...
#endif

Because NEW_FEATURE is always defined (to either 1 or 0), #ifdef NEW_FEATURE is always true, and the supposedly “conditional” code is always compiled.

So, both cases (#ifdef and #if) have problems if you accidentally use the incorrect test.

Of the two problems, using #ifdef when it should be #if appears to be the more serious error, since it can result in unintended code being included in a build, and no compiler errors or warnings will be generated (unless the conditional code happens to depend on other code which gets compiled out).

However, using #if when it should be #ifdef does the correct thing when the macro is undefined, and it generates a compiler error when the macro is defined (making it simpler to track down).

In this regard, #ifdef appears superior, but there are other considerations which should be taken into account. I’ll delve into some of those considerations (and cases you can’t do much about) in following posts.

Posted in C Preprocessor series, Programming | 2 Comments »

Concurrent programming (part 1)

Posted by jgiors on 2008-06-09

Intro

This is the first in a series of “thought pieces” about concurrent programming, especially as it relates to realtime applications. The motivation is for use in games, but this series is not game-specific.

The concurrent programming debate

There is a lot of interest (and griping) these days about the problems of writing efficient bug-free concurrent code (especially in the context of multicore systems). If you’re reading this, you probably already know why it has become a hot topic, so I’ll skip the explanation.

In any case, many people seem to feel the same way as guru Donald Knuth, author of the highly regarded The Art of Computer Programming series. This is what he said in a recent interview.

…I might as well flame a bit about my personal unhappiness with the current trend toward multicore architecture. To me, it looks more or less like the hardware designers have run out of ideas, and that they’re trying to pass the blame for the future demise of Moore’s Law to the software writers by giving us machines that work faster only on a few key benchmarks!

However, some people feel differently. Contrast Knuth’s statement with the following quote [from a lecture given in 1977] of another guru, John Backus, famous for being the “Backus” in BNF (Backus Normal Form, aka Backus Naur Form) formal language specification:

Surely there must be a less primitive way of making big changes in the [data] store than by pushing vast numbers of words back and forth through the von Neumann bottleneck. Not only is this tube a literal bottleneck for the data traffic of a problem, but, more importantly, it is an intellectual bottleneck that has kept us tied to word-at-a-time thinking instead of encouraging us to think in terms of the larger conceptual units of the task at hand. Thus programming is basically planning and detailing the enormous traffic of words through the von Neumann bottleneck, and much of that traffic concerns not significant data itself but where to find it.

To be fair, Backus was talking about changes in programming paradigms (specifically, proposing the use of functional programming), not parallel processing, but his point that there must be better methods of programming that transcend “word-at-a-time thinking” still seems relevant today.

Is the debate moot?

It may seem that debating concurrency is pointless. After all, we’ve started down the multicore path, and it seems like there is no turning back. That is probably true. For the foreseeable future, hardware will continue to increase in concurrency.

However, it is conceivable that software might remain procedural/imperative (e.g. if someone solves the long-standing problem of automating parallelization of sequential code). In addition, deciding how to approach the problem of concurrency depends on how we perceive the advantages and disadvantages of mimicking sequential code.

So, I do not think the debate is entirely moot. It is largely moot for hardware, but not for software, especially insofar as it affects our perception.

What’s my take on concurrency?

I agree with John Backus’s sentiment about the state of programming. A lot has changed in the 30+ years since his lecture, but even now, the status-quo of programming languages and methodologies feels limited by the intellectual “von Neumann bottleneck”.

In fact, I believe concurrent hardware will lead us to languages and methodologies which more naturally express solutions to realtime application problems. After all, realtime applications are about simulating large numbers of simultaneous activities. Simulation is naturally concurrent. All this time, we’ve been trying to simulate concurrency with sequential programs.

But, if simulation is naturally concurrent, why is concurrent programming so difficult?

The problem is that we don’t yet have adequate languages, tools, and methodologies for dealing with processor concurrency. Once those are developed, concurrency will be liberating. We will finally be able to write realtime applications the way we always wanted to (but didn’t know how).

Fortunately, the development of those languages, tools, and methodologies will be expedited by the fact that no one can ignore concurrency any longer.

[to be continued....]

Posted in Concurrent programming series, Programming | 1 Comment »

Your prototype is your final product (part 1)

Posted by jgiors on 2008-05-14

About 5 years ago, I worked at a division of Brooks Automation which built semiconductor wafer-sorting robots. My most interesting project was creating an experimental image-processing algorithm to detect a reference notch on a silicon wafer (which is used as a reference position for etching — we used it to locate ID numbers and barcodes). It was a challenging project — the reference notch is a rather small feature that only occupies a few pixels in a wafer image.

I was excited to demonstrate that the project should work in principle, so I threw together a prototype as quickly as I could. I made it very clear to everyone (including management) that this would be a prototype only, that it was unsuitable for mass-distribution, and that I would need some time after the demonstration to rewrite the code.

So, after about 3 weeks and with the help of some hardware tweaks (to provide a high-contrast image) I got it to detect the notch location about 90% of the time. Not bad for a first pass, but clearly it would need a lot of work to get that up to production quality (somewhere above 99%).

But, there was a problem…I had used a lot of “rapid prototyping” techniques (and hacking) to get things done as quickly as possible. I had used smart pointers instead of proper memory management, and as a consequence, there was a lot of memory waste (holding on to unnecessary images in the image processing chain) and thrashing/fragmentation (caused by allocation/deallocation of image buffers which could have been reused). The algorithm worked, but it was slow. I don’t recall exactly, but I think it took about 3 seconds to process an image.

But I thought “Not to worry, with some additional time to rewrite proper memory management routines, plus optimizations, that will easily reduce to half a second or less.”

The next day, my boss told me that we would use the code as-is.

I explained that the code was not ready for production, that I needed time to rewrite. I explained about the memory management problems and how optimization would require a different code structure. I also reminded him again that I had been upfront about the need to spend extra time for a rewrite (I had reminded him almost daily because I anticipated such a problem). He still wouldn’t budge and insisted that I continue with the current code base.

That’s when I learned the lesson which became the title of this post: Your prototype is your final product.

It’s a good thing to remember. Whenever you work on code (or engineer any product), what you think of as a prototype is likely to be seen as a final product by management. Once management sees visible results, they want it right away. And, in many cases, they just don’t understand the value of improving things that are “under the hood”. After all, what they see seems just fine to them, so what value could there possibly be in improvements?

[to be continued...]

Posted in Programming, Tech, Your prototype is your final product | Leave a Comment »

The last bug

Posted by jgiors on 2007-03-26

Coworker: Hey, John. How’s that code going?

Me: Well, it’s looking pretty good. I just fixed the last bug we know about … And you know what that means, right?

Coworker: It’s done?

Me: Well, no … Not quite.

Coworker: What’s it mean, then?

Me: It means there’s a lot we don’t know.

Posted in Humor, Programming | Leave a Comment »

String hash identifiers

Posted by jgiors on 2006-05-24

In the games industry, it is common practice to use hashes of strings as identifiers for objects. String hash identifiers are a useful compromise between the differences in human and computer "comprehension" — humans understand and remember string identifiers better than arbitrary numeric quantities, while computers operate most effectively with numbers.

CRC is one of the most common hashes, but there are other options, such as FNV. I prefer FNV because it is even simpler than CRC and doesn't require a lookup table as the typical CRC implementation does.

The advantages of using hashes are:

  • Hash values are always the same data size no matter how long a string is.
  • A primitive data type (typically a 32-bit unsigned int) can hold the hash.
  • Equality/inequality comparison is fast.
  • Less memory space is required than for strings.
  • They make good indices into hash tables.

Like all techniques, string hash identifiers have disadvantages. Because a hash is just an arbitrary number with no intrinsic meaning, the only way to find the string a hash originated from is to look it up in a hash-to-string table. And that means you have to create a hash-to-string table if you want "reversibility". If the string was hashed without storing it in a lookup table, it may not be possible to determine the original string (though putting a conditional breakpoint in the code often works).

It is also necessary to be on the lookout for hash collisions (two different strings which hash to the same value). They are reasonably rare, but the data sets of many games are getting large enough that a few collisions will occur during the course of a project. Collisions can lead to obscure bugs which are hard to track down. Often, this can be caught in debug builds by checking for duplicate strings when inserting hashes into lookup tables. When a problematic collision is found, it can be fixed by renaming one of the items.

Even so, the advantages of string hash identifiers typically outweigh the disadvantages. I have worked on several projects that use this technique, and the consensus is that it has been worthwhile.

I'll be writing more on this topic soon…

Posted in Game programming, Programming | 1 Comment »

SDL_pfont project kickoff

Posted by jgiors on 2006-04-18

INTRO

If you haven't heard of it yet, SDL is a cross-platform 2D graphics library, which also includes a few other features, like mouse/keyboard input.

WHY MAKE ANOTHER SDL FONT SYSTEM?

There are many libraries that run on top of SDL. Among them are several font libraries. I have taken a look at all the ones I could find, but they seem to share the following drawbacks:

  1. They include other libraries. Typically, they will at minimum require SDL_image , which then includes Zlib. It is also common to require some other special library (e.g., SDL_ttf requires FreeType).
  2. The format is not very efficient to draw. Most font formats require pixel-by-pixel processing. It would be nice to just make one rectangular blit per glyph.

Please don't get me wrong. I'm not criticizing these libraries. Several of them are very good at what they do, e.g., SDL_ttf is good at letting you write code that uses TrueType fonts quickly and easily. But there should be a better option for games programming, where simplicity and speed take precedence.

That is why I'm beginning work on SDL_pfont. It addresses both of the above issues by splitting the project into:

  1. A simple proportional font rendering system.
  2. A tool that processes a source image to produce a font.

I plan to release SDL_pfont as open source (assuming I feel comfortable with the resulting code). Here are the requirements I'd like SDL_pfont to meet:

FONT RENDERING SYSTEM REQUIREMENTS

  • ANSI C interface
  • Simple data structures
  • Does not require any libraries except SDL (and a few standard C routines).
  • Uses BMP format for texel data (since SDL supports BMP natively)
  • Font is stored in a disk format matching the memory format

TOOL REQUIREMENTS

  • ANSI C preferred (I might use some simple "C++ is better C" constructs).
  • Command-line utility
  • A plain-text configuration file defines the expected actions
  • Process a source BMP image to produce:
    • An output image containing the font glyphs
    • An output file containing the font data (in the target's native format)

CONCLUSION

And, that's it for now. I'll post updates as the project continues.

Posted in Open Source, Programming, SDL, SDL_pfont, Shareware | Leave a Comment »

Batch file timestamp creation

Posted by jgiors on 2006-04-15

I've been looking for a good way to generate timestamps in batch files. I created this sample (Windows XP/2000 only) based on a comment posted about an article appearing in Windows IT Pro magazine.

Posted in Programming, Tech, Windoze | Leave a Comment »

Curl

Posted by jgiors on 2006-04-04

Curl is an open source command line utility that downloads files of many types using URL syntax (e.g., ftp://, https://, etc.).  There is also a code library version (libCurl).  It was mentioned by someone on the SDL mailing list.

Posted in Open Source, Programming | Leave a Comment »

Steering behaviors

Posted by jgiors on 2006-03-27

I've seen this steering behaviors article before, but I stumbled across it today and thought I should save a link to it.

Posted in Games, Programming | Leave a Comment »

Test-driven development

Posted by jgiors on 2006-03-23

This Test-Driven Development (TDD) paper was presented yesterday at GDC (the Game Developers Conference). Not that I was present to see it…[Why do I miss the conference so often? *sigh*]

The idea of TDD is to program in this sequence:

  1. Write test case(s).
  2. Write code.
  3. Refactor code.
  4. Iterate.

It's similar to typical "unit testing", but on a broader scale. I'm not sure what to make of it yet, but it's intriguing to say the least.

Posted in Programming | Leave a Comment »

Reading published source code

Posted by jgiors on 2006-03-22

Reading published source code can be a productive way to learn programming techniques, especially for someone learning how to program.  But, to be honest, I haven't read through that much published source code.  I've downloaded id's source code for Doom and Quake games and spent a little time browsing them (the code is surprisingly clean), and I have occasionally looked at other published source, but only infrequently.

With a bit of a "shame on me" attitude, I thought to myself "Why didn't I spend more time learning from published source code?".  It seems that I passed up a really good opportunity.

But, on a little more introspection, I realized there was a bona fide reason I hadn't taken that opportunity:

Read the rest of this entry »

Posted in Programming | Leave a Comment »

Windows XP environment variables

Posted by jgiors on 2006-03-21

I just found out that Windows XP stores environment variables in the registry under the key “HKEY_CURRENT_USER\Environment”.  This means that variables can be changed from a batch file by calling regedit.

That’s useful because a batch file runs in it’s own virtual space.  If you use a command like “SET MYVAR=MYVALUE”, the environment variable will disappear when the batch file’s console window is closed.  Regedit solves the problem.

There is a caveat, however…it appears that the environment vars do not take effect until the operating system is explicitly notified that the environment vars have changed.  Rebooting should work, but is obviously inconvenient.  If I ever get a chance to experiment with this, I’ll post more at that time.

Posted in Programming, Windoze | Leave a Comment »

Compressed memory caching

Posted by jgiors on 2006-03-07

I found this article which proposes storing virtual memory pages in compressed memory.  I am mostly interested in the techniques used for memory compression–they appear to be simple and effective.

Posted in Programming | Leave a Comment »

HTML tags

Posted by jgiors on 2006-03-03

I just found this HTML Code Tutorial which seems to have some good information about HTML tags.

Posted in Programming | Leave a Comment »

Hex-grid map programming

Posted by jgiors on 2006-02-24

It looks like I might need a hex-grid map for an upcoming project. Here is the best programming reference I found so far.

Posted in Games, Programming | Leave a Comment »

OpenAL

Posted by jgiors on 2006-02-22

Since my last post was about open-source audio compression, it is befitting that this post is for an open-source audio lib, OpenAL.

Posted in Games, Programming | Leave a Comment »

Vorbis audio format

Posted by jgiors on 2006-02-22

Ogg Vorbis is an audio compression format with open source encoders and decoders.  Might be useful someday.

Posted in Games, Programming | Leave a Comment »

Texture atlases

Posted by jgiors on 2006-02-20

Here is a good article on texture atlases, which are large textures that pack together many small textures, reducing the number of context switches during rendering. The article covers the principles, the downsides (e.g., texture tiling is not possible), and techniques to help automate atlas creation.

Posted in Games, Programming | Leave a Comment »

zziplib

Posted by jgiors on 2006-02-10

I just found the zziplib zip-file library on SourceForge.  It has some nice features, like searching both a physical directory structure and a zip file.  The physical contents has priority over the zip file.  That can be very useful during product development.

Posted in Programming | Leave a Comment »

Bugzilla

Posted by jgiors on 2006-02-09

A week or two ago, I was discussing bug-tracking software with my coworkers, and today I stumbled across Bugzilla.  I haven't evaluated it yet, but it looks promising.

Posted in Applications, Management, Open Source, Programming | Leave a Comment »