Qe Reference

12
QE Reference Joe Linhoff Overview QE stands for the quarter engine. Development Environment DirectX & OpenGL QE uses OpenGL for graphics and DirectX for input, sounds, and other operations on Windows. For best results, update your OpenGL drivers (from your video card manufacturer's website) and install the latest DirectX (search for dxwebsetup.exe on Microsoft's site). Microsoft Visual Studio C++ Express Edition 2008 All the solutions are built using Express Edition 2008. Directories (solution root) -- your application starter -- starter kit with hello world Directories in the tree (and some of the files in those directories) lib -- library files bin -- executables qeblue.dll -- qe freeglut.dll -- glut-like gl utility toolkit inc -- qe include files qe.h -- the main interface file for the engine qec.h -- engine class definitions for C++ qebase.h -- base types Files config.h -- a user created file that defines how the solution builds qeStartup.c -- startup file for environment, not a user file .h files are added from the inc directory as needed Hello World // Copyright (C) 2007 Joe Linhoff, All Rights Reserved // e_hello.c #include "config.h" #if BUILD_HELLO // compile this app #include "qe.h" // qeMain() // JFL 05 Jan 07 int qeMain(int argc,chr *argv[])

description

 

Transcript of Qe Reference

Page 1: Qe Reference

QE ReferenceJoe Linhoff

OverviewQE stands for the quarter engine.

Development Environment

DirectX & OpenGLQE uses OpenGL for graphics and DirectX for input, sounds, and other operations on Windows. For best results, update your OpenGL drivers (from your video card manufacturer's website) and install the latest DirectX (search for dxwebsetup.exe on Microsoft's site).

Microsoft Visual Studio C++ Express Edition 2008All the solutions are built using Express Edition 2008.

Directories● (solution root) -- your application● starter -- starter kit with hello world

Directories in the tree (and some of the files in those directories)● lib -- library files● bin -- executables

○ qeblue.dll -- qe○ freeglut.dll -- glut-like gl utility toolkit

● inc -- qe include files○ qe.h -- the main interface file for the engine○ qec.h -- engine class definitions for C++○ qebase.h -- base types

Files● config.h -- a user created file that defines how the solution builds● qeStartup.c -- startup file for environment, not a user file● .h files are added from the inc directory as needed

Hello World// Copyright (C) 2007 Joe Linhoff, All Rights Reserved// e_hello.c#include "config.h"#if BUILD_HELLO // compile this app#include "qe.h"

// qeMain()// JFL 05 Jan 07int qeMain(int argc,chr *argv[])

Page 2: Qe Reference

{ // print hello world & version information qePrintf("%s / %s / %s\n",__FILE__,glGetString(GL_VERSION),qeVersion()); qePrintf("Hello World\n");

// turn control over to the engine until the user closes the program qeForever();

return 0;} // qeMain()

#endif // compile this app// EOF

Console and Log FileThe function qePrintf() follows most of the same formatting rules from printf(). In addition, all the messages printed are added to the log file. The log file is qelog.txt in your project's root directory. Use qeLogf() to send messages to the log file and not to the screen.

Reference

QE_API int qeForever(void); // does not return until closedQE_API chr *qeVersion(void); // get versionQE_API int qePrintf(chr *fmt,...); ///< print a messageQE_API int qeLogf(chr *fmt,...); ///< log a message

Base Types, Definitions, Macros

Base TypesThe file qebase.h contains the base type definitions for the engine.

base type definition and usebit smallest unit available, use 1 or 0chr 8 bit character for ASCII strings and internal namingchar environment defined characterint8 8 bit signed integer, MIN_INT8..MAX_INT8uns8 8 bit unsigned integer, 0..MAX_UNS8int16 16 bit signed integer, MIN_INT16..MAX_INT16uns16 16 bit unsigned integer, 0..MAX_UNS16int32 32 bit signed integer, MIN_INT32..MAX_INT32uns32 32 bit unsigned integer, 0..MAX_UNS32int environment defined integer, MIN_INT..MAX_INTuns unsigned version of environmentally defined integer, 0..MAX_UNSflt32 32 bit floatflt64 64 bit floatfloat environment defined float

Page 3: Qe Reference

int64 64 bit signed integeruns64 64 bit unsigned integer

Definesdefine definition notes, usage

PI 3.1415..TWOPI (2.0*PI)EPSILON 0.00001NUL 0L, a null pointer

Macrosdefine definition notes, usage

BRK() debugger breakpoint when DEBUG is defined during compileQE_DEGTORAD(_deg_) convert degree to radiansQE_RADTODEG(_rad_) convert radians to degreesNUM(_a_) number of elements in a static arrayPTR_ADD(_p_,_i_) add _i_ bytes to pointer _p_PTR_SUB(_p_,_i_) subtract _i_ bytes from pointer _p_C1(_a_) combine a single 8 bit valueC2(_a_,_b_) combine two 8 bit values, used for character-based constantsC3(_a_,_b_,_c_) combine three 8 bit values, used for character-based

constantsC4(_a_,_b_,_c_,_d_) combine four 8 bit values, used for character-based

constantsSET2(_d_,_s1_,_s2_) set array, i.e. _d_[0]=_s1_, _d_[1]=_s2_SET3(_d_,_s1_,_s2_,_s3_) set array, i.e. _d_[0]=_s1_, _d_[1]=_s2_SET4(_d_,_s1_,_s2_,_s3_,_s4_) set array, i.e. _d_[0]=_s1_, _d_[1]=_s2_CPY2(_d_,_s_) copy array entries from source _s_ to destination _d_CPY3(_d_,_s_) copy array entries from source _s_ to destination _d_CPY4(_d_,_s_) copy array entries from source _s_ to destination _d_

Function PointersTypedefs for function pointers are defined such that the first letter signals the return type and the next letters signal the parameter types: v = void, i = int, u = uns, p = pointer, a = variable argument. The partial table below shows a few examples.

typedefs definition notes, usagefnc_vv void function(void)fnc_iv int function(void)fnc_ii int function(int)

Page 4: Qe Reference

fnc_ipi int function(pointer,int)fnc_ipa int function(pointer,...)

ControlQE presents a single list to the user. In qeMain(), the application setups a list of functions and objects and then passes control to QE with qeForever(). Each game loop, QE performs various internal operations, and then begins processing the application-created list. Because the engine processes this list, it is called the engine list.

Function ObjectsThe function qeObjAddFnc() adds a C function with the signature int function(void) to the engine object list. This function will be called when it's node is processed. If the function returns a negative number, the node is removed from the engine's list and the function is not called again.

// Copyright (C) 2006-2008 Joe Linhoff, All Rights Reserved// e_simplefunction.c#include "config.h" // include the 'config' file first#if BUILD_SIMPLEFUNCTION // compile this app#include "qe.h"

// JFL 12 Aug 06int fncEveryLoop(void){ qePrintf("Frame %d time %f\n",qeLoopFrame(),qeTimeFrame()); return 0; // function must return a value, 0 indicates success} // fncEveryLoop()

// qeMain()// JFL 05 Aug 06int qeMain(int argc,chr *argv[]){ qePrintf("%s / %s / %s\n", __FILE__,glGetString(GL_VERSION),qeVersion());

// add a function to the engine's object loop if(!qeObjAddFnc(fncEveryLoop)) BRK();

// turn control over to qe until the user closes the program qeForever();

return 0;} // qeMain()

#endif // compile this app// EOF

Extended OperationsMany functions have a variable argument interface which starts with a string parameter. The

Page 5: Qe Reference

string parameter specifies the remaining arguments. For example, to specify the name for the function node added above, use qeObjAddFncSP() as follows.

// add a simple C function, static name, not copied if(!qeObjAddFncSP(fncEveryLoop,"N","f-everyLoop")) BRK();

// add a simple C function, dynamic name, copied if(!qeObjAddFncSP(fncEveryLoop,"n",name)) BRK();

F8 ConsoleQE has a built in console. Press F8 to toggle the console input on/off. Type the command and hit enter. Press F9 to toggle the background color and clear the console screen.

Commands● list -- lists the engine objects● step -- single step the engine, forward & backward arrows to step● run -- exit single step mode

Break MacroWhen DEBUG is defined, the BRK() macro expands to a debugger breakpoint. When DEBUG is not defined, or defined to be zero, the BRK() macro expands into a null statement.

NamesInternally, names are truncated to 11 characters and are case sensitive.

QE Update Base ClassThe preferred way to add a C++ object to the engine list is by deriving from the base class qeUpdateBase. This base class is defined in qec.h. Objects inheriting from qeUpdateBase are linked into the engine list and sorted against each other using the sort value. The gameid must be greater than zero and should be unique among all engine objects. Id value 1 is usually reserved for underdefined objects.

// Copyright (C) 2006-2008 Joe Linhoff, All Rights Reserved// e_simpleclass.c#include "config.h" // include the 'config' file first#if BUILD_SIMPLECLASS // compile this app#include "qec.h"

///////////////////////////////////////////////////////////////////////////////// Plane

class Plane : public qeUpdateBase {public: Plane::Plane(chr *name); int draw(void); // override virtual void final(void); // override virtual}; // class Plane

Page 6: Qe Reference

// JFL 11 Nov 07Plane::Plane(chr *name) : qeUpdateBase(name,0,1) // name, sort, gameid{} // Plane::Plane()

// JFL 11 Nov 07int Plane::draw(void){ qefnDrawGrid(10,1); qefnDrawAxes(1); return 0;} // Plane::draw()

// JFL 11 Nov 07void Plane::final(void){ delete this;} // Plane::final()

// qeMain()// JFL 05 Aug 06int qeMain(int argc,chr *argv[]){ qePrintf("%s / %s / %s\n", __FILE__,glGetString(GL_VERSION),qeVersion());

new Plane("plane1");

// turn control over to qe until the user closes the program qeForever();

return 0;} // qeMain()

#endif // compile this app// EOF

Deriving from qeUpdateBase defines and adds nodes for:● control() -- application definable● update() -- application definable● draw() -- application definable● final() -- must delete this;

QE base classThe qe base class overrides the new and delete operators to provide integration with the engine without adding memory overhead to your objects.

Reference

QE_API int qeForever(void); // does not return until closedQE_API uns qeLoopFrame(void); ///< loop count since resetQE_API float qeTimeFrame(void); ///< game time for the frameQE_API qeObj* qeObjAddFnc(fnc_iv fnc); // add C function objQE_API qeObj* qeObjAddFncSP(ptr adr,chr *sp,...); // add C func w/sp

Page 7: Qe Reference

BRK();class qeUpdateBase

Input

Button InputButton counts are used to report the current state of each button. Odd button counts signal the button is currently down. The keyboard is initially setup as buttons.

// JFL 21 Sep 06int fncEveryLoop(void){ uns upCount;

// read the button count for the up button upCount=qeInpButton(QEINPBUTTON_UP); // print all the values qePrintf("upCount=%d\n",upCount);

return 0; // function must return a value, 0 indicates success} // fncEveryLoop()

Default Key to Button MappingsZ - QEINPUTBUTTON_A up - QEINPUTBUTTON_UP pageup - QEINPUTBUTTON_UP2X - QEINPUTBUTTON_B down - QEINPUTBUTTON_DOWN pagedown - QEINPUTBUTTON_DOWN2C - QEINPUTBUTTON_X left - QEINPUTBUTTON_LEFTV - QEINPUTBUTTON_Y right - QEINPUTBUTTON_RIGHT

Remapping The Keyboard ButtonsTo remap the keys to different buttons, or to map multiple keys to the same button, use qeInpOp(QEINPOP_SETKEYMAP,gameKeymap) where the gameKeymap is the remapping table. This mapping table replaces the default table.

int gameKeymap[] = { // remap QEINPBUTTON_ to keys QEINPBUTTON_UP,'W',0, QEINPBUTTON_LEFT,'A',0, QEINPBUTTON_RIGHT,'D',0, QEINPBUTTON_DOWN,'S',0, QEINPBUTTON_A,'Z',0, QEINPBUTTON_B,'X',0, QEINPBUTTON_X,'C',0, QEINPBUTTON_Y,'V',0, QEINPBUTTON_START,'1','\r',0, // multiple mappings GAMEINPBUTTON_SPECIAL,'G','H','8',0, // multiple mappings 0 // term}; // gameKeymap[]

.. remap the keys in the setup ..

Page 8: Qe Reference

// remap the keys -- gameKeymap must remain valid while it is mapped qeInpOp(QEINPOP_SETKEYMAP,gameKeymap);

The Keyboard As A KeyboardInstead of treating the keyboard as a set of buttons, keys can also be captured into a buffer. Setup a buffer for QE to fill with keystrokes between frames, and then empty that buffer each frame.

// Copyright (C) 2006-2008 Joe Linhoff, All Rights Reserved// e_keyboard.cc#include "config.h"#if BUILD_KEYBOARD // compile this app#include "qe.h"

struct { // create local storage record uns keyBuf[32];} game;

// JFL 12 Aug 06// JFL 24 Sep 06int fncEveryLoop(void){ chr buf[32];

// copy the chrs typed out of the keyBuf and into 'buf' buf[0]=0; // force a terminating 0 -- will be replaced if chrs are copied qeInpOp(QEINPOP_CPYCHRBUF,buf,sizeof(buf));

// print all the values captured this loop qePrintf("'%s'\n",buf);

return 0; // function must return a value, 0 indicates success} // fncEveryLoop()

// qeMain()// JFL 05 Aug 06int qeMain(int argc,chr *argv[]){ MEMZ(game); // zero structure // print information qePrintf("%s / %s / %s\n",__FILE__,qeVersion(),glGetString(GL_VERSION));

// add a function to the engine's object loop if(!qeObjAddFnc(fncEveryLoop)) qePrintf("** qeObjAddFnc failed\n");

// setup the keyBuf to record keys as they are typed -- must remain valid qeInpKeyBuf(game.keyBuf,sizeof(game.keyBuf));

// turn control over to engine until the user closes the program qeForever();

return 0;} // qeMain()

#endif // compile this app

Page 9: Qe Reference

// EOF

Turn off keyboard button mappings with qeInpOp(QEINPOP_KEYBOARDMAPPINGS_OFF). And turn them back on with qeInpOp(QEINPOP_KEYBOARDMAPPINGS_ON).

JoysticksQE supports DirectX joysticks, Xbox360 joysticks, and Wii-motes. Use qeInpJoyNum() to find the current number of joysticks attached. Buttons and axes are then read using qeInpJoyButton() and qeInpJoyAxis(). The axis value ranges from QEINP_JOYAXIS_MIN to QEINP_JOYAXIS_MAX.

int fncEveryLoop(void){ uns b1,b2,b3,b4; int xyLeft[2]; int xyRight[2];

// read joystick buttons and axes b1=qeInpJoyButton(0,QEJOYBUTTON_A); b2=qeInpJoyButton(0,QEJOYBUTTON_X); b3=qeInpJoyButton(0,QEJOYBUTTON_LSHOULDER); b4=qeInpJoyButton(0,QEJOYBUTTON_LTHUMB); xyLeft[0]=qeInpJoyAxis(0,QEJOYAXIS_LEFT_X); xyLeft[1]=qeInpJoyAxis(0,QEJOYAXIS_LEFT_Y); xyRight[0]=qeInpJoyAxis(0,QEJOYAXIS_RIGHT_X); xyRight[1]=qeInpJoyAxis(0,QEJOYAXIS_RIGHT_Y);

// print the values qePrintf("number of joysticks=%d A=%d X=%d LS=%d LT=%d (%d, %d) (%d, %d)\n", qeInpJoyNum(),b1,b2,b3,b4,xyLeft[0],xyLeft[1],xyRight[0],xyRight[1]);

return 0; // function must return a value, 0 indicates success} // fncEveryLoop()

ReferenceQE_API uns qeInpButton(uns inpb); // QEINPBUTTON_QE_API int qeInpOp(uns op,...); // QEINPOP_QE_API uns qeInpJoyNum(void); // joysticks attached -- valid after qeOpen()QE_API int qeInpJoyAxis(uns joy,uns axis); // get, use QEJOYAXIS_QE_API uns qeInpJoyButton(uns joy,uns button); // get, use QEJOYBUTTON_

Sounds

Supported FormatsA limited number of .wav formats are currently supported.

ChannelsSounds play on software defined channels. There are currently 8 channels, which means you may play up to 8 sounds at the same time. A sound can range from a short pop to an

Page 10: Qe Reference

endlessly looping song. The game engine manages the mixing of the currently playing channels.

Loading And Playing SoundsRegister sounds with qeSndNew(). Play a sound with qeSndPlay(). To pre-load a sounds, use qeSndLoad().

QE_API int qeSndNew(chr *name,uns flags,uns tProtect,chr *path);QE_API int qeSndPlay(chr *name); // returns play id on success

The name parameter is the name of the sound and will be used to play or manipulate the loaded sound. The flags parameter contains track and priority information as well as other information. The tProtect parameter is a millisecond time parameter. And path is the file path to the sound file.

Channel Assignment AlgorithmWhen qeSndPlay() is called, the engine:

1. Looks through all the channels indicated in the channel mask for an empty (no sound currently playing) channel. If there is an empty channel, the engine starts the sound on that channel.

2. If there is not an empty channel, the engine looks through the channels indicated in the channel mask for a channel with a sound that it can stop playing and replace with the new sound.

If the new sound's priority is higher than a currently playing sound, the oldest, currently playing sound is replaced.

If there are no open channels, and the new sound's priority is lower than all the currently playing sounds, the new sound will not be played.

When the new sound's priority matches currently playing sounds, the oldest sound that is not protected will be replaced.

Age of a sound is determined by the time after a sound's protection expires.

A Typical Channel PlanEvery game has its own sound requirements. You must design a channel plan for how each game will use channels. Here is a simple example:

ch0 ch1 ch2 ch3 ch4 ch5 ch6 ch7

background announcer, world player weapons,

Page 11: Qe Reference

music music extras

effects, reactions

critical reactions, effects

Reference

QE_API int qeSndNew(chr *name,uns flags,uns tProtect,chr *path);QE_API int qeSndPlay(chr *name); // returns play id on success

Options

Turning Options On And OffQE is intended to be configurable. Use qeOptionTurnOff() or qeOptionTurnOn() to turn options on or off. Set options before qeForever() or qeOpen().

#define M_QEOPTION_CLEARSCREEN 0x000001 // clear screen every loop#define M_QEOPTION_AUTOCAM 0x000002 // add first (arcball) camera#define M_QEOPTION_DRAWCONSOLE 0x000100 // draw console#define M_QEOPTION_INITGL 0x000200 // init OpenGL#define M_QEOPTION_DRAWMODE 0x000400 // black on white#define M_QEOPTION_FIRSTLIGHT 0x000800 // add first light#define M_QEOPTION_LOGPRINTF 0x002000 // qePrintf() output also to log#define M_QEOPTION_CHECKLOGSIZE 0x004000 // check & delete log if too big#define M_QEOPTION_INERNALSLEEP 0x008000 // sleep inside the engine loop#define M_QEOPTION_CLEARSTENCIL 0x010000 // clear stencil buffer every loop#define M_QEOPTION_PAGEFLIP 0x010000 // flip pages

For example, to request the engine to no add the default camera or first light, and to clear the stencil buffer when it clears the screen:

// qeMain()// JFL 05 Jan 07int qeMain(int argc,chr *argv[]){ qeOptionTurnOff(M_QEOPTION_AUTOCAM|M_QEOPTION_FIRSTLIGHT); qeOptionTurnOn(M_QEOPTION_CLEARSTENCIL);

qePrintf("%s / %s / %s\n",__FILE__,glGetString(GL_VERSION),qeVersion());

...

Window Size, Full ScreenUse qeWindowSize() to change the window size. Use qeGetWindowSize() to get the current window size.

float w,h;

if(qeGetWindowSize(&w,&h)>=0)

Page 12: Qe Reference

; // success

Fullscreen mode is managed with qeFullscreen().