2006-02-28

XInput

This post is related to the comments by AC in the previous post regarding XInput. I thought it might be beneficial for everyone if I just made a post out of it.

In case you haven't read the comments, here's a synopsis. AC mentioned that the XBOX 360 wired controller works with the December release of DirectX 9c, which includes XInput, a new controller API that is essentially the same as the XBOX 360 API.

I was curious as to whether or not the API would work with other controllers or just the XBOX 360 controller.

According to MSDN :

"XInput is an API that allows applications to receive input from the Xbox 360 Controller for Windows. This document describes the differences between XInput and DirectInput implementations of the Xbox 360 Controller and how you can support XInput devices and legacy DirectInput devices at the same time."

"By supporting XInput only, your game will not work with legacy DirectInput devices. XInput will not recognize these devices."

So even if you use XInput, you still have to have a DirectInput implementation, unless you only want to support the XBOX 360 controller (or future XInput enabled devices).

I like the fact that the API is the same as, or at least similar to, the console version, making XBOX 360 porting a lot easier. Plus the API is so much cleaner than DirectInput. I believe that this is one of the goals of XNA, to have an API that is common to all devices, and to simplify cross-platform development.

2006-02-25

Winter Break

So I'm on winter break for the next week. No class. Relaxation. Coding.

I plan on doing as much coding as I can this week. I'm still trying to determine if I want to leave the engine alone and work on game specific stuff, or work on engine stuff. I think I've decided against switching to the virtual implementation that I posted earlier. After AC mentioned the Next-Gen impact it scared me off of virtual stuff a little bit, again. I've been thinking of either leaving it as is or doing what Scott Meyers refers to as the "is-implemented-in-terms-of" model, by allowing the Common class to have a Machine class pointer to the machines implementation. Neither solution seems as elegant as the virtual model did. That model just seems so clean and elegant, I just wish it didn't have the speed trade off that it does. And in gaming code, speed is top priority. If this was just a desktop application the speed issue wouldn't bother me.

On the game front I want to start creating level data. Everything needed for a level (collision information, sprites, etc..) will be bundled into a chunk file. I've already implemented a chunk file system in the engine. It's currently in use by fonts and textures.

Here's a brief description of how a chunk file works. Any binary data I use starts with the same chunk header. It specifies what type of data I'm pointing to, how big it is, and the offset to where it begins. The engine can then parse any binary file I have without knowing what the data it's pointing to is because the initial bytes of any file are all the same. If it doesn't know how to process a certain type of data it can ignore it.

What I need to add is what I call a Package chunk. If a file has more than one chunk in it, then it is considered a package and must have the Package chunk as its first chunk. This will contain a list of all the chunks in the file.

So I need to start by getting Packages working. I then plan to work on a game module for loading in the collision information for a level, drawing lines to represent the collision areas, and get the camera to move through the level with boundaries of where it can and can't move to. Then get my place holder character (a box) to run around the level, jump, collide with the collision objects, and make the camera follow the character. Hopefully I can get all of this done this week. Some of these pieces are already in place or started, but I'd like to get it all put together if possible.

2006-02-13

Engine Update: Inheritance

So the plan is to rewrite parts of the engine with a new inheritance order. The existing implementation is as follows:

/*
* A class defining all of the machine specific variables and
* operations that can only be done at this level. Should contain
* little or no code that can be shared cross-platform. (eg. The
* DirectX Windows version of this file does anything that is
* specific to DirectX or Windows).
*/

class MachineClass
{
private:
MachineType m_machine_var; // Stores machine specific data.
SharedType m_shared_var; // Stores common data that
// machine needs access to.
// [I never liked having to do this.]


public:
MachineClass();
~MachineClass();

void Func1( int in_params )
{
// do some stuff specific to this platform.
...
}
};


/*
* This class implements anything that can be shared cross-platform.
*/

class CommonClass : public MachineClass
{
public:
CommonClass();
~CommonClass();

void Func1( int in_params )
{
MachineClass::Func1( in_params );

// do anything that can be shared cross-platform here or
// before the call to Func1, whichever is more appropriate.

...
}

void Func2()
{
// Do something that is shared cross-platform.
...
}
};


Anyone who has worked with me in the past will notice a similarity to the implementation by my former employer. I never loved this implementation, but I decided to stick with what I knew. After all I was used to it and liked the idea that without anything being virtual there wasn't any overhead associated with the function calls. However I still never quite liked the way this felt. It always seemed overly cautious in terms of sacrificing the benefits of C++ for the sake of a perceived boost in performance. Of course it was our first C++ engine, implemented by mostly C coders, and we never could all agree on implementation specifics anyway.

As I look at it now, I'm not sure that this approach is what I want, so I'm attempting to implement everything in a much more C++, Object Oriented manner. This will add a little overhead due to the virtual functions, but the benefits gained will far outway any decrease in performance. Plus, most of these are large classes with only a few function calls per frame. These aren't classes that are called repeatedly. So here's the proposed new implementation.

/*
* This class defines the interface and implements anything that
* can be shared cross-platform. This class will be shared by all
* platforms.
*/

class CommonClass
{
private:
SharedType m_shared_var; // Now it can be declared here,
// but used by the derived class.


public:
CommonClass();
virtual ~CommonClass();

virtual void Func1( int in_params )
{
// do anything that can be shared cross-platform here.
...
}

void Func2();

const SharedType& GetSharedData() const;
{
return m_shared_var;
}

void SetSharedData( const SharedType& shared_data )
{
m_shared_data = shared_data;
}
};

/*
* A class defining all of the machine specific variables and
* operations that can only be done at this level. Should contain
* little or no code that can be shared cross-platform. (eg. The
* DirectX Windows version of this file does anything that is
* specific to DirectX or Windows).
*/

class MachineClass : public CommonClass
{
private:
MachineType m_machine_var; // Stores machine specific data.

public:
MachineClass();
virtual ~MachineClass();

virtual void Func1( int in_params )
{
// If neccesary call down to the base class to run
// the common code.

CommonClass::Func1( in_params );

// do some stuff specific to this platform.
...
}
};


So basically it boils down to switching the order of the inheritance chain. With this model the Common class specifies the interface that is to be shared by all platforms, and anything that needs to be done that is platform specific is done by defining the function in the derived Machine class. Much nicer.


Pros & Cons

PRO
--> This allows me to define as many different machine implementations as I want to. The Common class will behave as a Factory and create classes based on the type I desire. For my purposes this will be based on the graphics API mostly. On Windows I can implement a Directx version and an OpenGL version of every machine class and decide which one to use at runtime.
--> The file for the Common class can now contain all relevant data associated with it. In the previous implementation I was defining structures in a different file so that the Machine class could declare them. This meant that common data actually existed at the Machine level, just because the machine needed access to it. I didn't want the machine calling UP to the Common level because that just seemed wrong. But I never liked the way I had to implement it. Now this isn't an issue.

CON
--> All of these calls were not virtual previously which meant that the class had a smaller memory footprint and there wasn't the added overhead to the function calls. Plus inlining wasn't an issue.


The old implementation also had some potential issues if used improperly. For example if someone tried to use a pointer to a Machine class, things would have been bad. No function could call up to the derived class, and if you tried to delete a Machine pointer, but had allocated a Common class, there would have been a memory leak. These problems were apparent to me and I knew not to use the class in this way, but a good engine should be fool proof and usable by anyone, not just the person writing it ^_^.

2006-02-12

Effective C++

For Christmas I received Effective C++: Third Edition by Scott Meyers and I've been reading it in between studying for class and going to class. I'm a little more than half way through it now and it makes me want to rewrite so many parts of my engine ^_^. So when I think about coding lately my internal debate is whether to spend some time rewriting the engine or leave things as they are and work on game related stuff. I haven't really decided. My desire is to rewrite things, but my practical side says to just move forward and get something that looks like a game running.

Well, I haven't really coded much in a while. I was too busy last weekend and I just never got around to doing much coding this weekend, though I did spend time on project related tasks. I looked at UML a bit in case I redesign some of the engine I might use some UML diagrams while designing it. I investigated boost.org, which is mentioned in the Effective C++ book. This lead me to STLport, a free port of STL which I now intend to use. The only coding I did do was related to compiling the engine as a DLL, instead of a static LIB. It was a DLL at one time, then I decide against it, and now I'm going back to making it a DLL (multiple DLLs actually), so the framework was already set up to handle it.

Another hang up I've had lately is not wanting to start anything big because I have such little time to work on it. Once my brain is in coding space I find it hard to just stop and switch to doing homework. Once I get started I just want to keep going until the job is done and focus all my efforts on that one task. So I'm hesitant to start any big tasks.

My application to the University of Michigan has finally been submitted. I spent most of the day on Friday writing the final essay I needed in order to submit my application. That has been taking up some of my time as well. Now that it's all done I hope to be able to dedicate Fridays to coding again.

I guess that's it for now. Time to do some Calculus homework. I plan on making a post related to the changes I'm thinking about making to the engine. I'll talk about what the current design is like and the changes I intend to make. I look forward to hearing any feedback and/or suggestions. For now I better hit the books.

Welcome to a dream of what could be

If you haven't checked out the game Cloud, I highly recommend it. This is the tagline to the game:

"Have you ever wanted to fly among the clouds? To see the sky only where birds soar? Welcome to a dream of what could be. Welcome to Cloud."

Gamasutra has a Q&A article with the creators of the game. From the article:

"Compared with films, the emotional experiences that video games encompass lack variety. Although there are thousands of games and a number of defined genres, you can pretty much cover 95% of the mainstream games with adjectives like 'addicting, stimulating, and competitive'. But is 'addiction' all what we want? Does every game have to contain 'competition'.

Mature mediums like film have proven that they can offer a wide range of emotions and content that appeal to a broader audience. We think that games can appeal to a much broader range of emotions and attract very different types of players, too."


Will our industry eventually mature to the level of movies, in the sense that it can appeal to nearly all people, not just "gamers"? I think it can, but getting there may not be easy and may take more time than I'd personally like it too. Obstacles in the path: the generational gap (this will disappear with time), the limited genre of video games that exist within the mainstream consciousness (this will decrease with the disappearance of the generation gap, but can never be eliminated completely in any industry), the current publishing models (limited funding for games outside of the proven successful genres), the PC as the only platform available to independent developers (the next generation of consoles could change this with online distribution straight to the console), and the user experience or interface to the game itself (I think the Revolution controller is a step in the right direction to opening up the video game experience to a larger market.)

Also read "Death to the Game Industry: Long Live Games" by Greg Costikyan.

What are your thoughts?


I originally published this post on 02.04.2006, but when I came to the blog today it seems to have disappeared. Not sure what happened. Luckily I found a cached version on Google Desktop and salvaged it.