tag:blogger.com,1999:blog-95821442024-03-13T03:17:42.303-07:00Al's Game Programming BlogThis blog is a repository of the brain dumps of an obsessive video games programmer. He only learns by making mistakes. Please help by telling him why he is wrong.Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.comBlogger51125tag:blogger.com,1999:blog-9582144.post-1139175231442579212006-02-05T13:18:00.000-08:002006-02-05T19:22:08.770-08:00Tim Sweeney gives a presentation at POPL 2006Last month, Tim Sweeney of Epic Games (developers of the Unreal engine) gave a presentation titled, "The Next Mainstream Programming Language: A Game Developer's Perspective". Although I did not attend the POPL 2006 conference, I found reading the slides interesting. They can be opened with Open Office if you don't have Microsoft Powerpoint.On the opening slide, he argues that the programming Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com15tag:blogger.com,1999:blog-9582144.post-1131937164910677022005-11-13T18:33:00.000-08:002005-11-13T18:59:24.930-08:00How const is const?Here is some straightforward C++ code:int a[5];The variable "a" is declared as being an array of 5 integers. This code is equivalent:const int n = 5;int a[n];The variable "n" is a compile-time constant and can be used interchangeably with the constant 5. The address of a global variable is also a compile-time constant. Therefore, this is valid C++ as well:int b;const int n = reinterpret_cast<Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com8tag:blogger.com,1999:blog-9582144.post-1127690699816626762005-09-25T16:12:00.000-07:002005-09-25T19:06:59.876-07:00Using Python to drive Google Desktop SearchIf you haven't tried Google Desktop Search yet I suggest you install it immediately. It extends the Google search engine to your hard drive so you can use it to search your files, emails, etc. I find it really useful for searching through source code. It's much faster than Visual Studio or Explorer's search because it uses some kind of clever keyword index.This weekend I decided to learn Python. Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com4tag:blogger.com,1999:blog-9582144.post-1111909369128069022005-03-26T23:33:00.000-08:002005-03-26T23:42:49.130-08:00Virtual sizeofDo you ever wish you could do this:class Base{}; class Derived: public Base{ int x;}; Base *p = new Derived; size_t s = sizeof(*p); // s is sizeof(Derived)Of course it doesn't work because s becomes the size of Base rather than Derived. What you really want is a kind of "virtual sizeof". This is what I came up with:class Base{public: virtual size_t Size() const = 0;}; class Derived: public BaseAlastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com3tag:blogger.com,1999:blog-9582144.post-1111908013074582972005-03-26T22:50:00.000-08:002005-03-27T17:15:37.830-08:00I'm not deadIt's been 3 weeks since my last post. I'm not dead. I've been busy working on various projects. None of them are in a state that I can post anything concrete. Last week I learned two scripting languages: Ruby and Lua. The first thing I noticed was how much more productive I was using a scripting language than C# or C++. I think it was mostly the dynamic typing and certain language features like Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com2tag:blogger.com,1999:blog-9582144.post-1110080581289970242005-03-05T19:23:00.000-08:002005-03-05T23:20:19.640-08:00CDL prototype workingI just got my prototype CDL metacompiler working. It can compile the CDL class definition I posted previously and it outputs all the automatically generated schema and C++ serialization code. It's not even close to being production ready but I have taken it far enough to satisfy myself that it would be feasible for a game project. It was pretty straightforward to get working: just 18 hours.I Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com0tag:blogger.com,1999:blog-9582144.post-1109560930230739812005-02-27T18:52:00.000-08:002005-02-27T21:01:50.790-08:00Other applications for CDLMy main justification for CDL to this point has been as a tool to automatically generate a schema from an annotated C++ class definition, together with additional automatically generated C++ code to support the binding of objects to binary data cooked with the schema. As I see things, the only viable alternative (using C++ at least) is to automatically generate C++ code from a hand-written schemaAlastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com1tag:blogger.com,1999:blog-9582144.post-1109531630200833192005-02-27T10:38:00.000-08:002005-02-27T11:59:47.056-08:00Another CDL exampleThis is another example of CDL. I am posting it in response to Noel Llopis' comment on another thread. This is intended to demonstrate how CDL could allow the structure of the schema to differ from that of the member variables.// Orientation.cdl// Hand written annotated classCDL class Orientation{public: Orientation(): x(0), y(0), z(0), w(1) {} // Public API uses Euler angles float GetX() Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com2tag:blogger.com,1999:blog-9582144.post-1108952755158419052005-02-20T17:58:00.000-08:002005-02-20T18:25:55.163-08:00Puma C++ transformation libraryToday I looked at Puma. Puma is a library for applying transformations to C++ programs. It can do C++ lexical analysis, parsing and semantic analysis. The library provides an API for examining and modifying C++ abstract syntax trees. To support program transformation, it also allows a modified syntax tree to be "unparsed" back into C++ source code, which can then be compiled using a C++ Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com13tag:blogger.com,1999:blog-9582144.post-1108534933931849762005-02-15T22:00:00.000-08:002005-02-16T22:35:57.360-08:00Schema from program or program from schema?One of the goals of my C++ metaprogramming system is that it should be possible to generate a schema for game data directly from an annotated C++ program. This schema is important because it decouples the game engine from the tools that are used to process the game's data.There seem to be three options here. The first option is the one I am currently investigating and also the motivation for my CAlastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com6tag:blogger.com,1999:blog-9582144.post-1108501689733956622005-02-15T13:07:00.000-08:002005-02-15T23:43:31.290-08:00artefaktur C++ frameworkI found this existing C++ framework that supports reflection. Like my metaprogramming idea, this uses a C++ preprocessor to parse metadata out of C++ class definitions. I believe it focuses on using reflection to exploit metadata. I want to continue down the metaprogramming route. I think it fits better with C++.I also investigated C++0x. This is an attempt to standardize the next version of C++.Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com1tag:blogger.com,1999:blog-9582144.post-1108328638030466482005-02-13T12:55:00.000-08:002005-02-13T15:10:56.780-08:00CDL use casesThese are some use cases for my C++ metaprogramming framework. First some CDL:// Texture.h#ifndef GUARD_Texture_H#define GUARD_Texture_H #include "Object.h" // physical dependency on base class #include "StringPtr.h" // no physical dependency on referenced classes#include "ArrayPtr.h"#include "MipMapPtr.h" CDL class Texture: public Object{public: PROPERTY Ptr<String> GetName() const;Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com0tag:blogger.com,1999:blog-9582144.post-1108323865043151942005-02-13T11:14:00.000-08:002005-02-13T15:17:07.650-08:00C++ metaprogramming frameworkIn my previous post, I considered some ways of exploiting reflection in a C++ program. Specifically, I proposed the use of a C++ data definition language (DDL) from which metadata could be extracted in order to support reflection. In retrospect, I think the choice of the term DDL was a mistake. C++ classes are not just data after all. From now on I will use the term class definition language (CDLAlastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com7tag:blogger.com,1999:blog-9582144.post-1107113358103228872005-01-30T10:21:00.000-08:002005-01-30T13:47:02.376-08:00C++ data definition languageIn a previous post, I said I would consider some alternative ways of taking advantage of the benefits of C# (primarily reflection) on game console platforms. Two approaches spring to mind.
The first approach is to use an existing interpreted language with reflection support, such as Python. An interpreted language is appealing because, if the interpreter, debugger and other tools can be easily Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com5tag:blogger.com,1999:blog-9582144.post-1107034326616039232005-01-29T13:27:00.000-08:002005-01-29T15:29:02.590-08:00Contact detailsIn light of recent industry events, should anyone want to contact me directly over the next few weeks, I can be emailed at "apatrick at mail dot com".
Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com0tag:blogger.com,1999:blog-9582144.post-1106446706908645162005-01-22T15:31:00.000-08:002005-01-22T18:18:26.906-08:00First experience of test driven developmentI have been meaning to try Test Driven Development (TDD) for some time now. Until now I had been putting it off, mostly because I thought it would take quite a long time to learn and because I thought it would be a long time before I really "got it" and started seeing any real benefits. Having just written my first program using TDD, I am pleased to report that my learning time was almost nil andAlastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com2tag:blogger.com,1999:blog-9582144.post-1105926796416136632005-01-16T16:41:00.000-08:002005-01-16T18:09:56.196-08:00Review of the benefits of C# for games programmingI have just about reached the limits of what I can hope to achieve with my C# to C++ translator project. There is so much more I would like to do but it is getting to the stage where I cannot make significant progress in weekend time alone. I'm also extremely busy at work and have little energy left. Maybe I'll pick up where I left off in a few months.I did pretty well in the time available I Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com4tag:blogger.com,1999:blog-9582144.post-1105921407612181092005-01-16T15:32:00.000-08:002005-01-16T16:23:27.613-08:00Code coverage analysisCode coverage analysis is a way of verifying that every code path in a program is exercised at least once by a collection of test cases. Consider this simplified example:
public class MathUtils
{
public static int Sign(int x)
{
if (x<0)
{
return -1;
}
else if (x>0)
{
return 1;
}
else
{
return 0;
}
}
}
[TestFixture]
class Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com6tag:blogger.com,1999:blog-9582144.post-1105829912557753542005-01-15T14:52:00.000-08:002005-01-15T15:51:20.806-08:00Mono class library licensing termsI just checked out the licensing terms of the Mono .NET class library. This is Mono's implementation of classes like System.String, System.Collections.ArrayList, etc. It is just C# source code so, using my C# to C++ translator, I will be able to translate it to C++ just like any other C# program.
It is under the very unrestrictive MIT license. Specifically, it is allowable to use it in Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com0tag:blogger.com,1999:blog-9582144.post-1105825756590813112005-01-15T13:03:00.000-08:002005-01-15T18:19:29.880-08:00C# memory manager for video games console platformIn a previous post I described a fully automatic memory manager that was guaranteed not to leak memory. It was based on reference counting, weak references and compile time analysis. I plan to use this in the runtime for my C# to C++ translator. Now in this post I will look into a possible allocation strategy.
When designing a memory manager, there is an important trade-off to be made between Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com1tag:blogger.com,1999:blog-9582144.post-1105237696843317972005-01-08T17:19:00.000-08:002005-01-08T18:59:04.930-08:00Prototype pattern using reflectionThe prototype pattern is one of the originals described by the "Gang of Four" in their book "Design Patterns". The idea is that a class contains a virtual method that is overridden in each derived class to create a clone. Given a prototype object, it is then possible to create as many clones as needed by invoking the clone method.
An application of this pattern in video games would be to Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com7tag:blogger.com,1999:blog-9582144.post-1105220841742665162005-01-08T11:58:00.000-08:002005-01-10T08:30:06.066-08:00Automatically detect all memory leaks at compile time?Yesterday at work I spent a couple of hours tracking down a troublesome memory leak. Memory leaks are my third least favorite kind of bug (race conditions and dangling pointers are worse). They are also annoying because it is next to impossible to write unit tests that verify memory does not leak. If I refactor some code, how am I to know if I have introduced a memory leak? This leads me to my Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com2tag:blogger.com,1999:blog-9582144.post-1104901252627352922005-01-04T20:19:00.000-08:002005-01-05T07:51:33.596-08:00Improving code turnaround timeI have been using refactoring, as described in Martin Fowler's excellent book, for a couple of years now and found that it has improved my productivity and the quality of my code considerably. One of the basic requirements of refactoring is that you must be do it incrementally. That is, after each individual change, you must build and test your code, ideally using automated tests. I will call theAlastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com4tag:blogger.com,1999:blog-9582144.post-1104653470341445392005-01-01T23:42:00.000-08:002005-01-02T00:13:55.230-08:00Diagnostics tracesHere is a common and useful debugging technique:
void foo(int a, double b)
{
printf("Enters %s/%d foo(%d, %f)", __FILE__, __LINE__, a, b);
// do stuff
printf("Exits %s/%d foo(%d, %f)", __FILE__, __LINE__, a, b);
}Sometimes we need a picture of what the program is doing that cannot be determined by using debugging techniques like breakpoints or stepping through code. For example, we might Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com0tag:blogger.com,1999:blog-9582144.post-1104628694438170782005-01-01T16:59:00.000-08:002005-01-01T19:38:30.493-08:00Euclid's algorithmToday I worked on making the code generated by my translator a little less verbose. My strategy was to try and reconstruct the original C# expressions by analyzing the stack operations carried out by the IL assembly. This turned out to be quite straightforward. The main complication was aliasing. Unlike Java byte-code, MSIL byte-code permits variables to be aliased. I worked around this by only Alastair Patrickhttp://www.blogger.com/profile/08547818719982201304noreply@blogger.com1