The first thing you'll need to do before setting up your project is download the HGE library. Take some time to analyze its licensing options and then get the binaries, arranging them in the directory structure of your preference. This tutorial will follow the structure below:
project +- Debug +- lib +- hge | +- include | +- lib | +- bc | +- gcc | +- vc +- qaf +- include +- lib +- vc7
You will now need to configure the project properties.
A common source of confusion and frustration comes from the misplacement of resource files in respect to the working directory, so you might as well get that out of the way right now. Click on Debugging, then change the Working Directory field to $(OutDir)
. This will make MS Visual Studio look for resource files in the same folder as the executable.
Under the C/C++ folder, click on General. Add the include paths to HGE and Qaf in the Additional Include Directories field. Now click on Language and change the Enable Run-Time Type Info field to Yes
.
Now open the Linker folder and click on General. Under Additional Library Directories, add the vc
directory from HGE and the vc7
directory from Qaf. Click on Input and in the Additional Dependencies field, add the following items:
hge.lib
hgehelp.lib
qafd.lib
for the debug version of Qaf, qaf.lib
for the release versiond3dx8.lib
dinput8.lib
dxguid.lib
dxerr8.lib
The Direct3DX library has a weird requirement: In the Ignore Specific Library field, add libci.lib
; if you don't do that, the program will fail to compile.
That's all. Click OK in the project properties dialog.
You now need to copy the necessary DLLs into the game's working directory. Look for the following files and place them inside Debug
:
hge.dll
bass.dll
Finally, you need to copy a few Qaf resources into the game's working directory. Look in the main Qaf directory for the following files:
qafCFont.fnt
qafCFont.png
qafWater.png
Copy all of them into the Debug
directory of your project.
With the directory structure set up, it's time to write some code.
The first thing to do is to bring the Qaf namespace into the global scope:
using namespace qaf;
In the frame function, we'll just invoke Qaf's game loop:
HGE * hge = NULL; // The frame function: bool frameFunction () { // Perform Qaf's game loop: Environment::update( hge->Timer_GetDelta() ); if ( hge->Input_GetKeyState( HGEK_ESCAPE ) ) return true; return false; }
The "prologue function" is a callback used to notify your program that Qaf is about to begin its rendering operations. Here, we're just going to clear the screen and print some text with the debug console:
void prologueFunc () { // Clear the screen: hge->Gfx_Clear( 0 ); // Output text: Environment::cout << "Hello, world!\n"; Environment::cout << hge->Timer_GetFPS() << " FPS\n"; }
In the main function, you must first set up HGE...
// Application entry point: int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { hge = hgeCreate( HGE_VERSION ); hge->System_SetState( HGE_FRAMEFUNC, frameFunction ); hge->System_SetState( HGE_FPS, HGEFPS_UNLIMITED ); hge->System_SetState( HGE_SCREENWIDTH, 640 ); hge->System_SetState( HGE_SCREENHEIGHT, 480 ); hge->System_SetState( HGE_WINDOWED, true ); if ( !hge->System_Initiate() ) MessageBox( NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL );
...And then initialize Qaf:
Environment::initialize( false, true );
Here, we're telling Qaf not to create a backbuffer (the first parameter) and that we need to use the debug facilities (the second parameter). Don't worry too much about these; they will be explained in more detail in other tutorials.
Then we tell Qaf which function it should use as the prologue callback:
// Set the prologue function:
Environment::setPrologueCallback( prologueFunc );
When that's done, just start the game loop:
if ( !hge->System_Start() ) { MessageBox( NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL ); }
After the game loop is finished, you simply shut down Qaf and HGE:
Environment::shutdown();
hge->System_Shutdown();
hge->Release();
return 0;
}
See the full source code for this tutorial in the file: tutorials/tutorial01.cpp