|
CD3DGame implements the core application framework for a DirectX game. I based it largely off of the d3dapp class bundled with the DirectX SDK. It's a base class - to write a game with it, you have to create a derived class that actually implements the virtual functions (HandleInput(), Update(), Render(), etc) from CD3DGame. See the StarControl class for details on that. |
|
|
| Just a few useful macros here. CLAMP reassigns x, if necessary, whereas CLAMPED does not modify x and can be used in an expression. |
|
/* helper macros */ /* math constants */ |
|
/* error handling */ #define DEBUG_CALL( procCall ) \ |
|
GetString returns a string, given its ID in the string table resource. Switch to the 'Resources' pane in VC++ and find the string table resource. All important string constants should go here (such as paths into the game.dat file, in-game labels and messages, etc). IMPORTANT: Take a look at the implementation - for convenience, the strings that GetString returns are stored in a static array within the function. Because of that, the contents of the string it returns are temporary; if you're not planning on throwing it away immediately, copy the string to new memory. |
|
//----------------------------------------------------------------------------- |
|
//----------------------------------------------------------------------------- |
|
When you want to have the user interact with an interface widget, call SetShowCursor(TRUE) and monitor dxInput::MouseButtonClk(). For things like clicking buttons, where you need the absolute mouse position, use the windows input variables instead of dxInput. If you're not familiar with it, 'volatile' tells the compiler that the variable might be modified by more than one thread. Important for the network code... |
|
//----------------------------------------------------------------------------- BOOL m_bWindowed; |
|
Variables for mouse and keyboard input. These are updated by Windows, not DirectInput. The only time these should be used is for the mouse when you need absolute screen coordinates. |
|
BOOL
m_bKeyDown[256]; // Fallback input state from MsgProc() |
|
Some more member variables. Important ones are the fonts (peruse d3dfont.h to see how to render them), m_dFrameTime (we can use this to adjust the LOD of game objects at runtime), m_dxInputMgr (unlike the other member variables, you don't need protected access to CD3DGame to be able to access this instance of the input class; more on this in dxinput.html), and m_dxIniEngine (this is the INI file reader object for \cfg\Engine.ini - feel free to add new categories and constants to the file and read them using this object). m_dxFileMgr is the reader for the resource file (game.dat in the BIN directory). For those who don't know, a resource file is like a WAD file - it's a bundle that contains many other files arranged in virtual directories. Nukefile is a free library I found on the web. To use it, you first have to add files to game.dat, which is accomplished with the little utility I bundled in with the source code. To extract files, the easiest thing to do is use the ExtractFile function, which places the file in a temporary directory until the app closes, and returns a path to it. You can also load a file directly into memory. |
|
CD3DFont* m_pFontFW; // Fixed-width font SET_DEVOBJ m_setDevObjs; // List of loaded device objects DOUBLE m_dFrameTime; // Last frame time dxInput* m_dxInputMgr; // The DirectInput interface #ifndef NONUKEFILE |
|
You can ignore all but the last three functions. ShutDown immediately destroys the app, and spins in the message loop until it closes - it DOES NOT return. DisplayErrorMsg is handy - pass TRUE to the boolean parameter if you want the app to shut down after the message is displayed. DebugMsg shouldn't be used directly; call it using the debugging macros defined above. To see how the program actually gets up and running, look at StarControl.cpp. I placed WinMain (the windows entry point) at the top of the file. |
|
public: // Exposed functions // handles windows messages // initialize the CD3DGame // start the main game loop // stop the app // error handling |
|
This is the first set of functions that need to be overridden in the derived class. Just like GLUT... |
|
protected: // Overridable functions for the 3D scene created by the app virtual HRESULT InitGameObjects() { return S_OK; } virtual HRESULT FinalCleanup() { return S_OK; } |
|
// Device object management virtual HRESULT RegisterDeviceObject( dxDeviceObject* ); virtual HRESULT SetStateBlock(); |
|
DrawFPS and DrawMouseCursor get called every tick - if you want to display the framerate, flip m_bShowFPS. If you want to display the mouse cursor, call SetShowCursor(). ExtractFile, as described above, extracts a file from the game.dat file and stores it in a temporary directory. The one that takes a UINT is expecting an ID from the string table. |
|
protected: // Utilitiy functions VOID PageFlip(); // extract a file from the resource archive
|
|
HandleMessages() polls the event queue for the process and passes incoming events to their handlers. When you need to have the application wait for something to happen (network ACK, semaphore, etc), make sure you stick a call to this in your while loop to prevent the app from locking up. |
|
private: // Internal |
|
That's it! |