From f9158592e1478b2013afc7041d9ed041cf2d2f4a Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 13 Jan 2014 19:47:58 +1000 Subject: Update Irrlicht to 1.8.1. Include actual change markers this time. lol --- libraries/irrlicht-1.8/doc/html/example021.html | 2180 ----------------------- 1 file changed, 2180 deletions(-) delete mode 100644 libraries/irrlicht-1.8/doc/html/example021.html (limited to 'libraries/irrlicht-1.8/doc/html/example021.html') diff --git a/libraries/irrlicht-1.8/doc/html/example021.html b/libraries/irrlicht-1.8/doc/html/example021.html deleted file mode 100644 index 12b7073..0000000 --- a/libraries/irrlicht-1.8/doc/html/example021.html +++ /dev/null @@ -1,2180 +0,0 @@ - - -
- -This Tutorial shows how to load different Quake 3 maps.
-Features:
-You can download the Quake III Arena demo ( copyright id software ) at the following location: ftp://ftp.idsoftware.com/idstuff/quake3/win32/q3ademo.exe
-Copyright 2006-2011 Burningwater, Thomas Alten
-#include "driverChoice.h" -#include <irrlicht.h> -#include "q3factory.h" -#include "sound.h" -
Game Data is used to hold Data which is needed to drive the game
-struct GameData -{ - GameData ( const path &startupDir) : - retVal(0), StartupDir(startupDir), createExDevice(0), Device(0) - { - setDefault (); - } - - void setDefault (); - s32 save ( const path &filename ); - s32 load ( const path &filename ); - - s32 debugState; - s32 gravityState; - s32 flyTroughState; - s32 wireFrame; - s32 guiActive; - s32 guiInputActive; - f32 GammaValue; - s32 retVal; - s32 sound; - - path StartupDir; - stringw CurrentMapName; - array<path> CurrentArchiveList; - - vector3df PlayerPosition; - vector3df PlayerRotation; - - tQ3EntityList Variable; - - Q3LevelLoadParameter loadParam; - SIrrlichtCreationParameters deviceParam; - funcptr_createDeviceEx createExDevice; - IrrlichtDevice *Device; -}; -
set default settings
-void GameData::setDefault () -{ - debugState = EDS_OFF; - gravityState = 1; - flyTroughState = 0; - wireFrame = 0; - guiActive = 1; - guiInputActive = 0; - GammaValue = 1.f; - - // default deviceParam; -#if defined ( _IRR_WINDOWS_ ) - deviceParam.DriverType = EDT_DIRECT3D9; -#else - deviceParam.DriverType = EDT_OPENGL; -#endif - deviceParam.WindowSize.Width = 800; - deviceParam.WindowSize.Height = 600; - deviceParam.Fullscreen = false; - deviceParam.Bits = 24; - deviceParam.ZBufferBits = 16; - deviceParam.Vsync = false; - deviceParam.AntiAlias = false; - - // default Quake3 loadParam - loadParam.defaultLightMapMaterial = EMT_LIGHTMAP; - loadParam.defaultModulate = EMFN_MODULATE_1X; - loadParam.defaultFilter = EMF_ANISOTROPIC_FILTER; - loadParam.verbose = 2; - loadParam.mergeShaderBuffer = 1; // merge meshbuffers with same material - loadParam.cleanUnResolvedMeshes = 1; // should unresolved meshes be cleaned. otherwise blue texture - loadParam.loadAllShaders = 1; // load all scripts in the script directory - loadParam.loadSkyShader = 0; // load sky Shader - loadParam.alpharef = 1; - - sound = 0; - - CurrentMapName = ""; - CurrentArchiveList.clear (); - - // Explorer Media directory - CurrentArchiveList.push_back ( StartupDir + "../../media/" ); - - // Add the original quake3 files before you load your custom map - // Most mods are using the original shaders, models&items&weapons - CurrentArchiveList.push_back("/q/baseq3/"); - - CurrentArchiveList.push_back(StartupDir + "../../media/map-20kdm2.pk3"); -} -
Load the current game State from a typical quake3 cfg file
-s32 GameData::load ( const path &filename ) -{ - if (!Device) - return 0; - - // the quake3 mesh loader can also handle *.shader and *.cfg file - IQ3LevelMesh* mesh = (IQ3LevelMesh*) Device->getSceneManager()->getMesh ( filename ); - if (!mesh) - return 0; - - tQ3EntityList &entityList = mesh->getEntityList (); - - stringc s; - u32 pos; - - for ( u32 e = 0; e != entityList.size (); ++e ) - { - //dumpShader ( s, &entityList[e], false ); - //printf ( s.c_str () ); - - for ( u32 g = 0; g != entityList[e].getGroupSize (); ++g ) - { - const SVarGroup *group = entityList[e].getGroup ( g ); - - for ( u32 index = 0; index < group->Variable.size (); ++index ) - { - const SVariable &v = group->Variable[index]; - pos = 0; - if ( v.name == "playerposition" ) - { - PlayerPosition = getAsVector3df ( v.content, pos ); - } - else - if ( v.name == "playerrotation" ) - { - PlayerRotation = getAsVector3df ( v.content, pos ); - } - } - } - } - - return 1; -} -
Store the current game State in a quake3 configuration file
-s32 GameData::save ( const path &filename ) -{ - return 0; - if (!Device) - return 0; - - c8 buf[128]; - u32 i; - - // Store current Archive for restart - CurrentArchiveList.clear(); - IFileSystem *fs = Device->getFileSystem(); - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - CurrentArchiveList.push_back ( fs->getFileArchive(i)->getFileList()->getPath() ); - } - - // Store Player Position and Rotation - ICameraSceneNode * camera = Device->getSceneManager()->getActiveCamera (); - if ( camera ) - { - PlayerPosition = camera->getPosition (); - PlayerRotation = camera->getRotation (); - } - - IWriteFile *file = fs->createAndWriteFile ( filename ); - if (!file) - return 0; - - snprintf ( buf, 128, "playerposition %.f %.f %.f\nplayerrotation %.f %.f %.f\n", - PlayerPosition.X, PlayerPosition.Z, PlayerPosition.Y, - PlayerRotation.X, PlayerRotation.Z, PlayerRotation.Y); - file->write ( buf, (s32) strlen ( buf ) ); - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - snprintf ( buf, 128, "archive %s\n",stringc ( fs->getFileArchive(i)->getFileList()->getPath() ).c_str () ); - file->write ( buf, (s32) strlen ( buf ) ); - } - - file->drop (); - return 1; -} -
Representing a player
-struct Q3Player : public IAnimationEndCallBack -{ - Q3Player () - : Device(0), MapParent(0), Mesh(0), WeaponNode(0), StartPositionCurrent(0) - { - animation[0] = 0; - memset(Anim, 0, sizeof(TimeFire)*4); - } - - virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node); - - void create ( IrrlichtDevice *device, - IQ3LevelMesh* mesh, - ISceneNode *mapNode, - IMetaTriangleSelector *meta - ); - void shutdown (); - void setAnim ( const c8 *name ); - void respawn (); - void setpos ( const vector3df &pos, const vector3df& rotation ); - - ISceneNodeAnimatorCollisionResponse * cam() { return camCollisionResponse ( Device ); } - - IrrlichtDevice *Device; - ISceneNode* MapParent; - IQ3LevelMesh* Mesh; - IAnimatedMeshSceneNode* WeaponNode; - s32 StartPositionCurrent; - TimeFire Anim[4]; - c8 animation[64]; - c8 buf[64]; -}; -
End player
-void Q3Player::shutdown () -{ - setAnim ( 0 ); - - dropElement (WeaponNode); - - if ( Device ) - { - ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); - dropElement ( camera ); - Device = 0; - } - - MapParent = 0; - Mesh = 0; -} -
create a new player
-void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode *mapNode, IMetaTriangleSelector *meta ) -{ - setTimeFire ( Anim + 0, 200, FIRED ); - setTimeFire ( Anim + 1, 5000 ); - - if (!device) - return; - // load FPS weapon to Camera - Device = device; - Mesh = mesh; - MapParent = mapNode; - - ISceneManager *smgr = device->getSceneManager (); - IVideoDriver * driver = device->getVideoDriver(); - - ICameraSceneNode* camera = 0; - - SKeyMap keyMap[10]; - keyMap[0].Action = EKA_MOVE_FORWARD; - keyMap[0].KeyCode = KEY_UP; - keyMap[1].Action = EKA_MOVE_FORWARD; - keyMap[1].KeyCode = KEY_KEY_W; - - keyMap[2].Action = EKA_MOVE_BACKWARD; - keyMap[2].KeyCode = KEY_DOWN; - keyMap[3].Action = EKA_MOVE_BACKWARD; - keyMap[3].KeyCode = KEY_KEY_S; - - keyMap[4].Action = EKA_STRAFE_LEFT; - keyMap[4].KeyCode = KEY_LEFT; - keyMap[5].Action = EKA_STRAFE_LEFT; - keyMap[5].KeyCode = KEY_KEY_A; - - keyMap[6].Action = EKA_STRAFE_RIGHT; - keyMap[6].KeyCode = KEY_RIGHT; - keyMap[7].Action = EKA_STRAFE_RIGHT; - keyMap[7].KeyCode = KEY_KEY_D; - - keyMap[8].Action = EKA_JUMP_UP; - keyMap[8].KeyCode = KEY_KEY_J; - - keyMap[9].Action = EKA_CROUCH; - keyMap[9].KeyCode = KEY_KEY_C; - - camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 0.6f); - camera->setName ( "First Person Camera" ); - //camera->setFOV ( 100.f * core::DEGTORAD ); - camera->setFarValue( 20000.f ); - - IAnimatedMeshMD2* weaponMesh = (IAnimatedMeshMD2*) smgr->getMesh("gun.md2"); - if ( 0 == weaponMesh ) - return; - - if ( weaponMesh->getMeshType() == EAMT_MD2 ) - { - s32 count = weaponMesh->getAnimationCount(); - for ( s32 i = 0; i != count; ++i ) - { - snprintf ( buf, 64, "Animation: %s", weaponMesh->getAnimationName(i) ); - device->getLogger()->log(buf, ELL_INFORMATION); - } - } - - WeaponNode = smgr->addAnimatedMeshSceneNode( - weaponMesh, - smgr->getActiveCamera(), - 10, - vector3df( 0, 0, 0), - vector3df(-90,-90,90) - ); - WeaponNode->setMaterialFlag(EMF_LIGHTING, false); - WeaponNode->setMaterialTexture(0, driver->getTexture( "gun.jpg")); - WeaponNode->setLoopMode ( false ); - WeaponNode->setName ( "tommi the gun man" ); - - //create a collision auto response animator - ISceneNodeAnimator* anim = - smgr->createCollisionResponseAnimator( meta, camera, - vector3df(30,45,30), - getGravity ( "earth" ), - vector3df(0,40,0), - 0.0005f - ); - - camera->addAnimator( anim ); - anim->drop(); - - if ( meta ) - { - meta->drop (); - } - - respawn (); - setAnim ( "idle" ); -} -
so we need a good starting Position in the level. we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch"
-void Q3Player::respawn () -{ - if (!Device) - return; - ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); - - Device->getLogger()->log( "respawn" ); - - if ( StartPositionCurrent >= Q3StartPosition ( - Mesh, camera,StartPositionCurrent++, - cam ()->getEllipsoidTranslation() ) - ) - { - StartPositionCurrent = 0; - } -} -
set Player position from saved coordinates
-void Q3Player::setpos ( const vector3df &pos, const vector3df &rotation ) -{ - if (!Device) - return; - Device->getLogger()->log( "setpos" ); - - ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); - if ( camera ) - { - camera->setPosition ( pos ); - camera->setRotation ( rotation ); - camera->OnAnimate ( 0 ); - } -} -
set the Animation of the player and weapon
-void Q3Player::setAnim ( const c8 *name ) -{ - if ( name ) - { - snprintf ( animation, 64, "%s", name ); - if ( WeaponNode ) - { - WeaponNode->setAnimationEndCallback ( this ); - WeaponNode->setMD2Animation ( animation ); - } - } - else - { - animation[0] = 0; - if ( WeaponNode ) - { - WeaponNode->setAnimationEndCallback ( 0 ); - } - } -} - - -// Callback -void Q3Player::OnAnimationEnd(IAnimatedMeshSceneNode* node) -{ - setAnim ( 0 ); -} -
GUI Elements
-struct GUI -{ - GUI () - { - memset ( this, 0, sizeof ( *this ) ); - } - - void drop() - { - dropElement ( Window ); - dropElement ( Logo ); - } - - IGUIComboBox* VideoDriver; - IGUIComboBox* VideoMode; - IGUICheckBox* FullScreen; - IGUICheckBox* Bit32; - IGUIScrollBar* MultiSample; - IGUIButton* SetVideoMode; - - IGUIScrollBar* Tesselation; - IGUIScrollBar* Gamma; - IGUICheckBox* Collision; - IGUICheckBox* Visible_Map; - IGUICheckBox* Visible_Shader; - IGUICheckBox* Visible_Fog; - IGUICheckBox* Visible_Unresolved; - IGUICheckBox* Visible_Skydome; - IGUIButton* Respawn; - - IGUITable* ArchiveList; - IGUIButton* ArchiveAdd; - IGUIButton* ArchiveRemove; - IGUIFileOpenDialog* ArchiveFileOpen; - IGUIButton* ArchiveUp; - IGUIButton* ArchiveDown; - - IGUIListBox* MapList; - IGUITreeView* SceneTree; - IGUIStaticText* StatusLine; - IGUIImage* Logo; - IGUIWindow* Window; -}; -
CQuake3EventHandler controls the game
-class CQuake3EventHandler : public IEventReceiver -{ -public: - - CQuake3EventHandler( GameData *gameData ); - virtual ~CQuake3EventHandler (); - - void Animate(); - void Render(); - - void AddArchive ( const path& archiveName ); - void LoadMap ( const stringw& mapName, s32 collision ); - void CreatePlayers(); - void AddSky( u32 dome, const c8 *texture ); - Q3Player *GetPlayer ( u32 index ) { return &Player[index]; } - - void CreateGUI(); - void SetGUIActive( s32 command); - - bool OnEvent(const SEvent& eve); - - -private: - - GameData *Game; - - IQ3LevelMesh* Mesh; - ISceneNode* MapParent; - ISceneNode* ShaderParent; - ISceneNode* ItemParent; - ISceneNode* UnresolvedParent; - ISceneNode* BulletParent; - ISceneNode* FogParent; - ISceneNode * SkyNode; - IMetaTriangleSelector *Meta; - - c8 buf[256]; - - Q3Player Player[2]; - - struct SParticleImpact - { - u32 when; - vector3df pos; - vector3df outVector; - }; - array<SParticleImpact> Impacts; - void useItem( Q3Player * player); - void createParticleImpacts( u32 now ); - - void createTextures (); - void addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent); - - GUI gui; - void dropMap (); -}; -
Constructor
-CQuake3EventHandler::CQuake3EventHandler( GameData *game ) -: Game(game), Mesh(0), MapParent(0), ShaderParent(0), ItemParent(0), UnresolvedParent(0), - BulletParent(0), FogParent(0), SkyNode(0), Meta(0) -{ - buf[0]=0; - // Also use 16 Bit Textures for 16 Bit RenderDevice - if ( Game->deviceParam.Bits == 16 ) - { - game->Device->getVideoDriver()->setTextureCreationFlag(ETCF_ALWAYS_16_BIT, true); - } - - // Quake3 Shader controls Z-Writing - game->Device->getSceneManager()->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); - - // create internal textures - createTextures (); - - sound_init ( game->Device ); - - Game->Device->setEventReceiver ( this ); -} - - -// destructor -CQuake3EventHandler::~CQuake3EventHandler () -{ - Player[0].shutdown (); - sound_shutdown (); - - Game->save( "explorer.cfg" ); - - Game->Device->drop(); -} - - -// create runtime textures smog, fog -void CQuake3EventHandler::createTextures() -{ - IVideoDriver * driver = Game->Device->getVideoDriver(); - - dimension2du dim(64, 64); - - video::IImage* image; - u32 i; - u32 x; - u32 y; - u32 * data; - for ( i = 0; i != 8; ++i ) - { - image = driver->createImage ( video::ECF_A8R8G8B8, dim); - data = (u32*) image->lock (); - for ( y = 0; y != dim.Height; ++y ) - { - for ( x = 0; x != dim.Width; ++x ) - { - data [x] = 0xFFFFFFFF; - } - data = (u32*) ( (u8*) data + image->getPitch() ); - } - image->unlock(); - snprintf ( buf, 64, "smoke_%02d", i ); - driver->addTexture( buf, image ); - image->drop (); - } - - // fog - for ( i = 0; i != 1; ++i ) - { - image = driver->createImage ( video::ECF_A8R8G8B8, dim); - data = (u32*) image->lock (); - for ( y = 0; y != dim.Height; ++y ) - { - for ( x = 0; x != dim.Width; ++x ) - { - data [x] = 0xFFFFFFFF; - } - data = (u32*) ( (u8*) data + image->getPitch() ); - } - image->unlock(); - snprintf ( buf, 64, "fog_%02d", i ); - driver->addTexture( buf, image ); - image->drop (); - } -} -
create the GUI
-void CQuake3EventHandler::CreateGUI() -{ - - IGUIEnvironment *env = Game->Device->getGUIEnvironment(); - IVideoDriver * driver = Game->Device->getVideoDriver(); - - gui.drop(); - - // set skin font - IGUIFont* font = env->getFont("fontlucida.png"); - if (font) - env->getSkin()->setFont(font); - env->getSkin()->setColor ( EGDC_BUTTON_TEXT, video::SColor(240,0xAA,0xAA,0xAA) ); - env->getSkin()->setColor ( EGDC_3D_HIGH_LIGHT, video::SColor(240,0x22,0x22,0x22) ); - env->getSkin()->setColor ( EGDC_3D_FACE, video::SColor(240,0x44,0x44,0x44) ); - env->getSkin()->setColor ( EGDC_EDITABLE, video::SColor(240,0x44,0x44,0x44) ); - env->getSkin()->setColor ( EGDC_FOCUSED_EDITABLE, video::SColor(240,0x54,0x54,0x54) ); - env->getSkin()->setColor ( EGDC_WINDOW, video::SColor(240,0x66,0x66,0x66) ); - - // minimal gui size 800x600 - dimension2d<u32> dim ( 800, 600 ); - dimension2d<u32> vdim ( Game->Device->getVideoDriver()->getScreenSize() ); - - if ( vdim.Height >= dim.Height && vdim.Width >= dim.Width ) - { - //dim = vdim; - } - else - { - } - - gui.Window = env->addWindow ( rect<s32> ( 0, 0, dim.Width, dim.Height ), false, L"Quake3 Explorer" ); - gui.Window->setToolTipText ( L"Quake3Explorer. Loads and show various BSP File Format and Shaders." ); - gui.Window->getCloseButton()->setToolTipText ( L"Quit Quake3 Explorer" ); - - // add a status line help text - gui.StatusLine = env->addStaticText( 0, rect<s32>( 5,dim.Height - 30,dim.Width - 5,dim.Height - 10), - false, false, gui.Window, -1, true - ); - - - env->addStaticText ( L"VideoDriver:", rect<s32>( dim.Width - 400, 24, dim.Width - 310, 40 ),false, false, gui.Window, -1, false ); - gui.VideoDriver = env->addComboBox(rect<s32>( dim.Width - 300, 24, dim.Width - 10, 40 ),gui.Window); - gui.VideoDriver->addItem(L"Direct3D 9.0c", EDT_DIRECT3D9 ); - gui.VideoDriver->addItem(L"Direct3D 8.1", EDT_DIRECT3D8 ); - gui.VideoDriver->addItem(L"OpenGL 1.5", EDT_OPENGL); - gui.VideoDriver->addItem(L"Software Renderer", EDT_SOFTWARE); - gui.VideoDriver->addItem(L"Burning's Video (TM) Thomas Alten", EDT_BURNINGSVIDEO); - gui.VideoDriver->setSelected ( gui.VideoDriver->getIndexForItemData ( Game->deviceParam.DriverType ) ); - gui.VideoDriver->setToolTipText ( L"Use a VideoDriver" ); - - env->addStaticText ( L"VideoMode:", rect<s32>( dim.Width - 400, 44, dim.Width - 310, 60 ),false, false, gui.Window, -1, false ); - gui.VideoMode = env->addComboBox(rect<s32>( dim.Width - 300, 44, dim.Width - 10, 60 ),gui.Window); - gui.VideoMode->setToolTipText ( L"Supported Screenmodes" ); - IVideoModeList *modeList = Game->Device->getVideoModeList(); - if ( modeList ) - { - s32 i; - for ( i = 0; i != modeList->getVideoModeCount (); ++i ) - { - u16 d = modeList->getVideoModeDepth ( i ); - if ( d < 16 ) - continue; - - u16 w = modeList->getVideoModeResolution ( i ).Width; - u16 h = modeList->getVideoModeResolution ( i ).Height; - u32 val = w << 16 | h; - - if ( gui.VideoMode->getIndexForItemData ( val ) >= 0 ) - continue; - - f32 aspect = (f32) w / (f32) h; - const c8 *a = ""; - if ( core::equals ( aspect, 1.3333333333f ) ) a = "4:3"; - else if ( core::equals ( aspect, 1.6666666f ) ) a = "15:9 widescreen"; - else if ( core::equals ( aspect, 1.7777777f ) ) a = "16:9 widescreen"; - else if ( core::equals ( aspect, 1.6f ) ) a = "16:10 widescreen"; - else if ( core::equals ( aspect, 2.133333f ) ) a = "20:9 widescreen"; - - snprintf ( buf, sizeof ( buf ), "%d x %d, %s",w, h, a ); - gui.VideoMode->addItem ( stringw ( buf ).c_str(), val ); - } - } - gui.VideoMode->setSelected ( gui.VideoMode->getIndexForItemData ( - Game->deviceParam.WindowSize.Width << 16 | - Game->deviceParam.WindowSize.Height ) ); - - gui.FullScreen = env->addCheckBox ( Game->deviceParam.Fullscreen, rect<s32>( dim.Width - 400, 64, dim.Width - 300, 80 ), gui.Window,-1, L"Fullscreen" ); - gui.FullScreen->setToolTipText ( L"Set Fullscreen or Window Mode" ); - - gui.Bit32 = env->addCheckBox ( Game->deviceParam.Bits == 32, rect<s32>( dim.Width - 300, 64, dim.Width - 240, 80 ), gui.Window,-1, L"32Bit" ); - gui.Bit32->setToolTipText ( L"Use 16 or 32 Bit" ); - - env->addStaticText ( L"MultiSample:", rect<s32>( dim.Width - 235, 64, dim.Width - 150, 80 ),false, false, gui.Window, -1, false ); - gui.MultiSample = env->addScrollBar( true, rect<s32>( dim.Width - 150, 64, dim.Width - 70, 80 ), gui.Window,-1 ); - gui.MultiSample->setMin ( 0 ); - gui.MultiSample->setMax ( 8 ); - gui.MultiSample->setSmallStep ( 1 ); - gui.MultiSample->setLargeStep ( 1 ); - gui.MultiSample->setPos ( Game->deviceParam.AntiAlias ); - gui.MultiSample->setToolTipText ( L"Set the MultiSample (disable, 1x, 2x, 4x, 8x )" ); - - gui.SetVideoMode = env->addButton (rect<s32>( dim.Width - 60, 64, dim.Width - 10, 80 ), gui.Window, -1,L"set" ); - gui.SetVideoMode->setToolTipText ( L"Set Video Mode with current values" ); - - env->addStaticText ( L"Gamma:", rect<s32>( dim.Width - 400, 104, dim.Width - 310, 120 ),false, false, gui.Window, -1, false ); - gui.Gamma = env->addScrollBar( true, rect<s32>( dim.Width - 300, 104, dim.Width - 10, 120 ), gui.Window,-1 ); - gui.Gamma->setMin ( 50 ); - gui.Gamma->setMax ( 350 ); - gui.Gamma->setSmallStep ( 1 ); - gui.Gamma->setLargeStep ( 10 ); - gui.Gamma->setPos ( core::floor32 ( Game->GammaValue * 100.f ) ); - gui.Gamma->setToolTipText ( L"Adjust Gamma Ramp ( 0.5 - 3.5)" ); - Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); - - - env->addStaticText ( L"Tesselation:", rect<s32>( dim.Width - 400, 124, dim.Width - 310, 140 ),false, false, gui.Window, -1, false ); - gui.Tesselation = env->addScrollBar( true, rect<s32>( dim.Width - 300, 124, dim.Width - 10, 140 ), gui.Window,-1 ); - gui.Tesselation->setMin ( 2 ); - gui.Tesselation->setMax ( 12 ); - gui.Tesselation->setSmallStep ( 1 ); - gui.Tesselation->setLargeStep ( 1 ); - gui.Tesselation->setPos ( Game->loadParam.patchTesselation ); - gui.Tesselation->setToolTipText ( L"How smooth should curved surfaces be rendered" ); - - gui.Collision = env->addCheckBox ( true, rect<s32>( dim.Width - 400, 150, dim.Width - 300, 166 ), gui.Window,-1, L"Collision" ); - gui.Collision->setToolTipText ( L"Set collision on or off ( flythrough ). \nPress F7 on your Keyboard" ); - gui.Visible_Map = env->addCheckBox ( true, rect<s32>( dim.Width - 300, 150, dim.Width - 240, 166 ), gui.Window,-1, L"Map" ); - gui.Visible_Map->setToolTipText ( L"Show or not show the static part the Level. \nPress F3 on your Keyboard" ); - gui.Visible_Shader = env->addCheckBox ( true, rect<s32>( dim.Width - 240, 150, dim.Width - 170, 166 ), gui.Window,-1, L"Shader" ); - gui.Visible_Shader->setToolTipText ( L"Show or not show the Shader Nodes. \nPress F4 on your Keyboard" ); - gui.Visible_Fog = env->addCheckBox ( true, rect<s32>( dim.Width - 170, 150, dim.Width - 110, 166 ), gui.Window,-1, L"Fog" ); - gui.Visible_Fog->setToolTipText ( L"Show or not show the Fog Nodes. \nPress F5 on your Keyboard" ); - gui.Visible_Unresolved = env->addCheckBox ( true, rect<s32>( dim.Width - 110, 150, dim.Width - 10, 166 ), gui.Window,-1, L"Unresolved" ); - gui.Visible_Unresolved->setToolTipText ( L"Show the or not show the Nodes the Engine can't handle. \nPress F6 on your Keyboard" ); - gui.Visible_Skydome = env->addCheckBox ( true, rect<s32>( dim.Width - 110, 180, dim.Width - 10, 196 ), gui.Window,-1, L"Skydome" ); - gui.Visible_Skydome->setToolTipText ( L"Show the or not show the Skydome." ); - - //Respawn = env->addButton ( rect<s32>( dim.Width - 260, 90, dim.Width - 10, 106 ), 0,-1, L"Respawn" ); - - env->addStaticText ( L"Archives:", rect<s32>( 5, dim.Height - 530, dim.Width - 600,dim.Height - 514 ),false, false, gui.Window, -1, false ); - - gui.ArchiveAdd = env->addButton ( rect<s32>( dim.Width - 725, dim.Height - 530, dim.Width - 665, dim.Height - 514 ), gui.Window,-1, L"add" ); - gui.ArchiveAdd->setToolTipText ( L"Add an archive, usually packed zip-archives (*.pk3) to the Filesystem" ); - gui.ArchiveRemove = env->addButton ( rect<s32>( dim.Width - 660, dim.Height - 530, dim.Width - 600, dim.Height - 514 ), gui.Window,-1, L"del" ); - gui.ArchiveRemove->setToolTipText ( L"Remove the selected archive from the FileSystem." ); - gui.ArchiveUp = env->addButton ( rect<s32>( dim.Width - 575, dim.Height - 530, dim.Width - 515, dim.Height - 514 ), gui.Window,-1, L"up" ); - gui.ArchiveUp->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive up" ); - gui.ArchiveDown = env->addButton ( rect<s32>( dim.Width - 510, dim.Height - 530, dim.Width - 440, dim.Height - 514 ), gui.Window,-1, L"down" ); - gui.ArchiveDown->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive down" ); - - - gui.ArchiveList = env->addTable ( rect<s32>( 5,dim.Height - 510, dim.Width - 450,dim.Height - 410 ), gui.Window ); - gui.ArchiveList->addColumn ( L"Type", 0 ); - gui.ArchiveList->addColumn ( L"Real File Path", 1 ); - gui.ArchiveList->setColumnWidth ( 0, 60 ); - gui.ArchiveList->setColumnWidth ( 1, 284 ); - gui.ArchiveList->setToolTipText ( L"Show the attached Archives" ); - - - env->addStaticText ( L"Maps:", rect<s32>( 5, dim.Height - 400, dim.Width - 450,dim.Height - 380 ),false, false, gui.Window, -1, false ); - gui.MapList = env->addListBox ( rect<s32>( 5,dim.Height - 380, dim.Width - 450,dim.Height - 40 ), gui.Window, -1, true ); - gui.MapList->setToolTipText ( L"Show the current Maps in all Archives.\n Double-Click the Map to start the level" ); - - - // create a visible Scene Tree - env->addStaticText ( L"Scenegraph:", rect<s32>( dim.Width - 400, dim.Height - 400, dim.Width - 5,dim.Height - 380 ),false, false, gui.Window, -1, false ); - gui.SceneTree = env->addTreeView( rect<s32>( dim.Width - 400, dim.Height - 380, dim.Width - 5, dim.Height - 40 ), - gui.Window, -1, true, true, false ); - gui.SceneTree->setToolTipText ( L"Show the current Scenegraph" ); - gui.SceneTree->getRoot()->clearChildren(); - addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); - - - IGUIImageList* imageList = env->createImageList( driver->getTexture ( "iconlist.png" ), - dimension2di( 32, 32 ), true ); - - if ( imageList ) - { - gui.SceneTree->setImageList( imageList ); - imageList->drop (); - } - - - // load the engine logo - gui.Logo = env->addImage( driver->getTexture("irrlichtlogo3.png"), position2d<s32>(5, 16 ), true, 0 ); - gui.Logo->setToolTipText ( L"The great Irrlicht Engine" ); - - AddArchive ( "" ); -} -
Add an Archive to the FileSystems and updates the GUI
-void CQuake3EventHandler::AddArchive ( const path& archiveName ) -{ - IFileSystem *fs = Game->Device->getFileSystem(); - u32 i; - - if ( archiveName.size () ) - { - bool exists = false; - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - if ( fs->getFileArchive(i)->getFileList()->getPath() == archiveName ) - { - exists = true; - break; - } - } - - if (!exists) - { - fs->addFileArchive(archiveName, true, false); - } - } - - // store the current archives in game data - // show the attached Archive in proper order - if ( gui.ArchiveList ) - { - gui.ArchiveList->clearRows(); - - for ( i = 0; i != fs->getFileArchiveCount(); ++i ) - { - IFileArchive * archive = fs->getFileArchive ( i ); - - u32 index = gui.ArchiveList->addRow(i); - - core::stringw typeName; - switch(archive->getType()) - { - case io::EFAT_ZIP: - typeName = "ZIP"; - break; - case io::EFAT_GZIP: - typeName = "gzip"; - break; - case io::EFAT_FOLDER: - typeName = "Mount"; - break; - case io::EFAT_PAK: - typeName = "PAK"; - break; - case io::EFAT_TAR: - typeName = "TAR"; - break; - default: - typeName = "archive"; - } - - gui.ArchiveList->setCellText ( index, 0, typeName ); - gui.ArchiveList->setCellText ( index, 1, archive->getFileList()->getPath() ); - } - } - - - // browse the archives for maps - if ( gui.MapList ) - { - gui.MapList->clear(); - - IGUISpriteBank *bank = Game->Device->getGUIEnvironment()->getSpriteBank("sprite_q3map"); - if ( 0 == bank ) - bank = Game->Device->getGUIEnvironment()->addEmptySpriteBank("sprite_q3map"); - - SGUISprite sprite; - SGUISpriteFrame frame; - core::rect<s32> r; - - bank->getSprites().clear(); - bank->getPositions().clear (); - gui.MapList->setSpriteBank ( bank ); - - u32 g = 0; - core::stringw s; - - // browse the attached file system - fs->setFileListSystem ( FILESYSTEM_VIRTUAL ); - fs->changeWorkingDirectoryTo ( "/maps/" ); - IFileList *fileList = fs->createFileList (); - fs->setFileListSystem ( FILESYSTEM_NATIVE ); - - for ( i=0; i< fileList->getFileCount(); ++i) - { - s = fileList->getFullFileName(i); - if ( s.find ( ".bsp" ) >= 0 ) - { - // get level screenshot. reformat texture to 128x128 - path c ( s ); - deletePathFromFilename ( c ); - cutFilenameExtension ( c, c ); - c = path ( "levelshots/" ) + c; - - dimension2du dim ( 128, 128 ); - IVideoDriver * driver = Game->Device->getVideoDriver(); - IImage* image = 0; - ITexture *tex = 0; - path filename; - - filename = c + ".jpg"; - if ( fs->existFile ( filename ) ) - image = driver->createImageFromFile( filename ); - if ( 0 == image ) - { - filename = c + ".tga"; - if ( fs->existFile ( filename ) ) - image = driver->createImageFromFile( filename ); - } - - if ( image ) - { - IImage* filter = driver->createImage ( video::ECF_R8G8B8, dim ); - image->copyToScalingBoxFilter ( filter, 0 ); - image->drop (); - image = filter; - } - - if ( image ) - { - tex = driver->addTexture ( filename, image ); - image->drop (); - } - - - bank->setTexture ( g, tex ); - - r.LowerRightCorner.X = dim.Width; - r.LowerRightCorner.Y = dim.Height; - gui.MapList->setItemHeight ( r.LowerRightCorner.Y + 4 ); - frame.rectNumber = bank->getPositions().size(); - frame.textureNumber = g; - - bank->getPositions().push_back(r); - - sprite.Frames.set_used ( 0 ); - sprite.Frames.push_back(frame); - sprite.frameTime = 0; - bank->getSprites().push_back(sprite); - - gui.MapList->addItem ( s.c_str (), g ); - g += 1; - } - } - fileList->drop (); - - gui.MapList->setSelected ( -1 ); - IGUIScrollBar * bar = (IGUIScrollBar*)gui.MapList->getElementFromId( 0 ); - if ( bar ) - bar->setPos ( 0 ); - - } - -} -
clears the Map in Memory
-void CQuake3EventHandler::dropMap () -{ - IVideoDriver * driver = Game->Device->getVideoDriver(); - - driver->removeAllHardwareBuffers (); - driver->removeAllTextures (); - - Player[0].shutdown (); - - - dropElement ( ItemParent ); - dropElement ( ShaderParent ); - dropElement ( UnresolvedParent ); - dropElement ( FogParent ); - dropElement ( BulletParent ); - - - Impacts.clear(); - - if ( Meta ) - { - Meta = 0; - } - - dropElement ( MapParent ); - dropElement ( SkyNode ); - - // clean out meshes, because textures are invalid - // TODO: better texture handling;-) - IMeshCache *cache = Game->Device->getSceneManager ()->getMeshCache(); - cache->clear (); - Mesh = 0; -} -
Load new map
-void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision ) -{ - if ( 0 == mapName.size() ) - return; - - dropMap (); - - IFileSystem *fs = Game->Device->getFileSystem(); - ISceneManager *smgr = Game->Device->getSceneManager (); - - IReadFile* file = fs->createMemoryReadFile(&Game->loadParam, - sizeof(Game->loadParam), L"levelparameter.cfg", false); - - // load cfg file - smgr->getMesh( file ); - file->drop (); - - // load the actual map - Mesh = (IQ3LevelMesh*) smgr->getMesh(mapName); - if ( 0 == Mesh ) - return; -
add the geometry mesh to the Scene ( polygon & patches ) The Geometry mesh is optimised for faster drawing
-IMesh *geometry = Mesh->getMesh(E_Q3_MESH_GEOMETRY); - if ( 0 == geometry || geometry->getMeshBufferCount() == 0) - return; - - Game->CurrentMapName = mapName; - - //create a collision list - Meta = 0; - - ITriangleSelector * selector = 0; - if (collision) - Meta = smgr->createMetaTriangleSelector(); - - //IMeshBuffer *b0 = geometry->getMeshBuffer(0); - //s32 minimalNodes = b0 ? core::s32_max ( 2048, b0->getVertexCount() / 32 ) : 2048; - s32 minimalNodes = 2048; - - MapParent = smgr->addOctreeSceneNode(geometry, 0, -1, minimalNodes); - MapParent->setName ( mapName ); - if ( Meta ) - { - selector = smgr->createOctreeTriangleSelector( geometry,MapParent, minimalNodes); - //selector = smgr->createTriangleSelector ( geometry, MapParent ); - Meta->addTriangleSelector( selector); - selector->drop (); - } - - // logical parent for the items - ItemParent = smgr->addEmptySceneNode(); - if ( ItemParent ) - ItemParent->setName ( "Item Container" ); - - ShaderParent = smgr->addEmptySceneNode(); - if ( ShaderParent ) - ShaderParent->setName ( "Shader Container" ); - - UnresolvedParent = smgr->addEmptySceneNode(); - if ( UnresolvedParent ) - UnresolvedParent->setName ( "Unresolved Container" ); - - FogParent = smgr->addEmptySceneNode(); - if ( FogParent ) - FogParent->setName ( "Fog Container" ); - - // logical parent for the bullets - BulletParent = smgr->addEmptySceneNode(); - if ( BulletParent ) - BulletParent->setName ( "Bullet Container" ); -
now construct SceneNodes for each Shader The Objects are stored in the quake mesh E_Q3_MESH_ITEMS and the Shader ID is stored in the MaterialParameters mostly dark looking skulls and moving lava.. or green flashing tubes?
-Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_ITEMS,ShaderParent, Meta, false ); - Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_FOG,FogParent, 0, false ); - Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_UNRESOLVED,UnresolvedParent, Meta, true ); -
Now construct Models from Entity List
- Q3ModelFactory ( Game->loadParam, Game->Device, Mesh, ItemParent, false );
-}
-
Adds a SceneNode with an icon to the Scene Tree
-void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent) -{ - IGUITreeViewNode* node; - wchar_t msg[128]; - - s32 imageIndex; - list<ISceneNode*>::ConstIterator it = parent->getChildren().begin(); - for (; it != parent->getChildren().end(); ++it) - { - switch ( (*it)->getType () ) - { - case ESNT_Q3SHADER_SCENE_NODE: imageIndex = 0; break; - case ESNT_CAMERA: imageIndex = 1; break; - case ESNT_EMPTY: imageIndex = 2; break; - case ESNT_MESH: imageIndex = 3; break; - case ESNT_OCTREE: imageIndex = 3; break; - case ESNT_ANIMATED_MESH: imageIndex = 4; break; - case ESNT_SKY_BOX: imageIndex = 5; break; - case ESNT_BILLBOARD: imageIndex = 6; break; - case ESNT_PARTICLE_SYSTEM: imageIndex = 7; break; - case ESNT_TEXT: imageIndex = 8; break; - default:imageIndex = -1; break; - } - - if ( imageIndex < 0 ) - { - swprintf ( msg, 128, L"%hs,%hs", - Game->Device->getSceneManager ()->getSceneNodeTypeName ( (*it)->getType () ), - (*it)->getName() - ); - } - else - { - swprintf ( msg, 128, L"%hs",(*it)->getName() ); - } - - node = nodeParent->addChildBack( msg, 0, imageIndex ); - - // Add all Animators - list<ISceneNodeAnimator*>::ConstIterator ait = (*it)->getAnimators().begin(); - for (; ait != (*it)->getAnimators().end(); ++ait) - { - imageIndex = -1; - swprintf ( msg, 128, L"%hs", - Game->Device->getSceneManager ()->getAnimatorTypeName ( (*ait)->getType () ) - ); - - switch ( (*ait)->getType () ) - { - case ESNAT_FLY_CIRCLE: - case ESNAT_FLY_STRAIGHT: - case ESNAT_FOLLOW_SPLINE: - case ESNAT_ROTATION: - case ESNAT_TEXTURE: - case ESNAT_DELETION: - case ESNAT_COLLISION_RESPONSE: - case ESNAT_CAMERA_FPS: - case ESNAT_CAMERA_MAYA: - default: - break; - } - node->addChildBack( msg, 0, imageIndex ); - } - - addSceneTreeItem ( *it, node ); - } -} - - -// Adds life! -void CQuake3EventHandler::CreatePlayers() -{ - Player[0].create ( Game->Device, Mesh, MapParent, Meta ); -} - - -// Adds a skydome to the scene -void CQuake3EventHandler::AddSky( u32 dome, const c8 *texture) -{ - ISceneManager *smgr = Game->Device->getSceneManager (); - IVideoDriver * driver = Game->Device->getVideoDriver(); - - bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); - driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); - - if ( 0 == dome ) - { - // irrlicht order - //static const c8*p[] = { "ft", "lf", "bk", "rt", "up", "dn" }; - // quake3 order - static const c8*p[] = { "ft", "rt", "bk", "lf", "up", "dn" }; - - u32 i = 0; - snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); - SkyNode = smgr->addSkyBoxSceneNode( driver->getTexture ( buf ), 0, 0, 0, 0, 0 ); - - if (SkyNode) - { - for ( i = 0; i < 6; ++i ) - { - snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); - SkyNode->getMaterial(i).setTexture ( 0, driver->getTexture ( buf ) ); - } - } - } - else - if ( 1 == dome ) - { - snprintf ( buf, 64, "%s.jpg", texture ); - SkyNode = smgr->addSkyDomeSceneNode( - driver->getTexture( buf ), 32,32, - 1.f, 1.f, 1000.f, 0, 11); - } - else - if ( 2 == dome ) - { - snprintf ( buf, 64, "%s.jpg", texture ); - SkyNode = smgr->addSkyDomeSceneNode( - driver->getTexture( buf ), 16,8, - 0.95f, 2.f, 1000.f, 0, 11); - } - - if (SkyNode) - SkyNode->setName("Skydome"); - //SkyNode->getMaterial(0).ZBuffer = video::EMDF_DEPTH_LESS_EQUAL; - - driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); -} - - -// enable GUI elements -void CQuake3EventHandler::SetGUIActive( s32 command) -{ - bool inputState = false; - - ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); - - switch ( command ) - { - case 0: Game->guiActive = 0; inputState = !Game->guiActive; break; - case 1: Game->guiActive = 1; inputState = !Game->guiActive;;break; - case 2: Game->guiActive ^= 1; inputState = !Game->guiActive;break; - case 3: - if ( camera ) - inputState = !camera->isInputReceiverEnabled(); - break; - } - - if ( camera ) - { - camera->setInputReceiverEnabled ( inputState ); - Game->Device->getCursorControl()->setVisible( !inputState ); - } - - if ( gui.Window ) - { - gui.Window->setVisible ( Game->guiActive != 0 ); - } - - if ( Game->guiActive && - gui.SceneTree && Game->Device->getGUIEnvironment()->getFocus() != gui.SceneTree - ) - { - gui.SceneTree->getRoot()->clearChildren(); - addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); - } - - Game->Device->getGUIEnvironment()->setFocus ( Game->guiActive ? gui.Window: 0 ); -} -
Handle game input
-bool CQuake3EventHandler::OnEvent(const SEvent& eve) -{ - if ( eve.EventType == EET_LOG_TEXT_EVENT ) - { - return false; - } - - if ( Game->guiActive && eve.EventType == EET_GUI_EVENT ) - { - if ( eve.GUIEvent.Caller == gui.MapList && eve.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN ) - { - s32 selected = gui.MapList->getSelected(); - if ( selected >= 0 ) - { - stringw loadMap = gui.MapList->getListItem ( selected ); - if ( 0 == MapParent || loadMap != Game->CurrentMapName ) - { - printf ( "Loading map %ls\n", loadMap.c_str() ); - LoadMap ( loadMap , 1 ); - if ( 0 == Game->loadParam.loadSkyShader ) - { - AddSky ( 1, "skydome2" ); - } - CreatePlayers (); - CreateGUI (); - SetGUIActive ( 0 ); - return true; - } - } - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveRemove && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - Game->Device->getFileSystem()->removeFileArchive( gui.ArchiveList->getSelected() ); - Game->CurrentMapName = ""; - AddArchive ( "" ); - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveAdd && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - if ( 0 == gui.ArchiveFileOpen ) - { - Game->Device->getFileSystem()->setFileListSystem ( FILESYSTEM_NATIVE ); - gui.ArchiveFileOpen = Game->Device->getGUIEnvironment()->addFileOpenDialog ( L"Add Game Archive" , false,gui.Window ); - } - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_SELECTED ) - { - AddArchive ( gui.ArchiveFileOpen->getFileName() ); - gui.ArchiveFileOpen = 0; - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_DIRECTORY_SELECTED ) - { - AddArchive ( gui.ArchiveFileOpen->getDirectoryName() ); - } - else - if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED ) - { - gui.ArchiveFileOpen = 0; - } - else - if ( ( eve.GUIEvent.Caller == gui.ArchiveUp || eve.GUIEvent.Caller == gui.ArchiveDown ) && - eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - s32 rel = eve.GUIEvent.Caller == gui.ArchiveUp ? -1 : 1; - if ( Game->Device->getFileSystem()->moveFileArchive ( gui.ArchiveList->getSelected (), rel ) ) - { - s32 newIndex = core::s32_clamp ( gui.ArchiveList->getSelected() + rel, 0, gui.ArchiveList->getRowCount() - 1 ); - AddArchive ( "" ); - gui.ArchiveList->setSelected ( newIndex ); - Game->CurrentMapName = ""; - } - } - else - if ( eve.GUIEvent.Caller == gui.VideoDriver && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) - { - Game->deviceParam.DriverType = (E_DRIVER_TYPE) gui.VideoDriver->getItemData ( gui.VideoDriver->getSelected() ); - } - else - if ( eve.GUIEvent.Caller == gui.VideoMode && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) - { - u32 val = gui.VideoMode->getItemData ( gui.VideoMode->getSelected() ); - Game->deviceParam.WindowSize.Width = val >> 16; - Game->deviceParam.WindowSize.Height = val & 0xFFFF; - } - else - if ( eve.GUIEvent.Caller == gui.FullScreen && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - Game->deviceParam.Fullscreen = gui.FullScreen->isChecked(); - } - else - if ( eve.GUIEvent.Caller == gui.Bit32 && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - Game->deviceParam.Bits = gui.Bit32->isChecked() ? 32 : 16; - } - else - if ( eve.GUIEvent.Caller == gui.MultiSample && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) - { - Game->deviceParam.AntiAlias = gui.MultiSample->getPos(); - } - else - if ( eve.GUIEvent.Caller == gui.Tesselation && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) - { - Game->loadParam.patchTesselation = gui.Tesselation->getPos (); - } - else - if ( eve.GUIEvent.Caller == gui.Gamma && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) - { - Game->GammaValue = gui.Gamma->getPos () * 0.01f; - Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); - } - else - if ( eve.GUIEvent.Caller == gui.SetVideoMode && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - Game->retVal = 2; - Game->Device->closeDevice(); - } - else - if ( eve.GUIEvent.Caller == gui.Window && eve.GUIEvent.EventType == gui::EGET_ELEMENT_CLOSED ) - { - Game->Device->closeDevice(); - } - else - if ( eve.GUIEvent.Caller == gui.Collision && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - // set fly through active - Game->flyTroughState ^= 1; - Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); - - printf ( "collision %d\n", Game->flyTroughState == 0 ); - } - else - if ( eve.GUIEvent.Caller == gui.Visible_Map && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - bool v = gui.Visible_Map->isChecked(); - - if ( MapParent ) - { - printf ( "static node set visible %d\n",v ); - MapParent->setVisible ( v ); - } - } - else - if ( eve.GUIEvent.Caller == gui.Visible_Shader && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - bool v = gui.Visible_Shader->isChecked(); - - if ( ShaderParent ) - { - printf ( "shader node set visible %d\n",v ); - ShaderParent->setVisible ( v ); - } - } - else - if ( eve.GUIEvent.Caller == gui.Visible_Skydome && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) - { - if ( SkyNode ) - { - bool v = !SkyNode->isVisible(); - printf ( "skynode set visible %d\n",v ); - SkyNode->setVisible ( v ); - } - } - else - if ( eve.GUIEvent.Caller == gui.Respawn && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) - { - Player[0].respawn (); - } - - return false; - } - - // fire - if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_SPACE && - eve.KeyInput.PressedDown == false) || - (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) - ) - { - ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); - if ( camera && camera->isInputReceiverEnabled () ) - { - useItem( Player + 0 ); - } - } - - // gui active - if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_F1 && - eve.KeyInput.PressedDown == false) || - (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) - ) - { - SetGUIActive ( 2 ); - } - - // check if user presses the key - if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.PressedDown == false) - { - // Escape toggles camera Input - if ( eve.KeyInput.Key == irr::KEY_ESCAPE ) - { - SetGUIActive ( 3 ); - } - else - if (eve.KeyInput.Key == KEY_F11) - { - // screenshot are taken without gamma! - IImage* image = Game->Device->getVideoDriver()->createScreenShot(); - if (image) - { - core::vector3df pos; - core::vector3df rot; - ICameraSceneNode * cam = Game->Device->getSceneManager()->getActiveCamera (); - if ( cam ) - { - pos = cam->getPosition (); - rot = cam->getRotation (); - } - - static const c8 *dName[] = { "null", "software", "burning", - "d3d8", "d3d9", "opengl" }; - - snprintf(buf, 256, "%s_%ls_%.0f_%.0f_%.0f_%.0f_%.0f_%.0f.jpg", - dName[Game->Device->getVideoDriver()->getDriverType()], - Game->CurrentMapName.c_str(), - pos.X, pos.Y, pos.Z, - rot.X, rot.Y, rot.Z - ); - path filename ( buf ); - filename.replace ( '/', '_' ); - printf ( "screenshot : %s\n", filename.c_str() ); - Game->Device->getVideoDriver()->writeImageToFile(image, filename, 100 ); - image->drop(); - } - } - else - if (eve.KeyInput.Key == KEY_F9) - { - s32 value = EDS_OFF; - - Game->debugState = ( Game->debugState + 1 ) & 3; - - switch ( Game->debugState ) - { - case 1: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL; break; - case 2: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_SKELETON; break; - } -
set debug map data on/off debugState = debugState == EDS_OFF ? EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL: EDS_OFF;
-if ( ItemParent ) - { - list<ISceneNode*>::ConstIterator it = ItemParent->getChildren().begin(); - for (; it != ItemParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( ShaderParent ) - { - list<ISceneNode*>::ConstIterator it = ShaderParent->getChildren().begin(); - for (; it != ShaderParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( UnresolvedParent ) - { - list<ISceneNode*>::ConstIterator it = UnresolvedParent->getChildren().begin(); - for (; it != UnresolvedParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( FogParent ) - { - list<ISceneNode*>::ConstIterator it = FogParent->getChildren().begin(); - for (; it != FogParent->getChildren().end(); ++it) - { - (*it)->setDebugDataVisible ( value ); - } - } - - if ( SkyNode ) - { - SkyNode->setDebugDataVisible ( value ); - } - - } - else - if (eve.KeyInput.Key == KEY_F8) - { - // set gravity on/off - Game->gravityState ^= 1; - Player[0].cam()->setGravity ( getGravity ( Game->gravityState ? "earth" : "none" ) ); - printf ( "gravity %s\n", Game->gravityState ? "earth" : "none" ); - } - else - if (eve.KeyInput.Key == KEY_F7) - { - // set fly through active - Game->flyTroughState ^= 1; - Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); - if ( gui.Collision ) - gui.Collision->setChecked ( Game->flyTroughState == 0 ); - - printf ( "collision %d\n", Game->flyTroughState == 0 ); - } - else - if (eve.KeyInput.Key == KEY_F2) - { - Player[0].respawn (); - } - else - if (eve.KeyInput.Key == KEY_F3) - { - if ( MapParent ) - { - bool v = !MapParent->isVisible (); - printf ( "static node set visible %d\n",v ); - MapParent->setVisible ( v ); - if ( gui.Visible_Map ) - gui.Visible_Map->setChecked ( v ); - } - } - else - if (eve.KeyInput.Key == KEY_F4) - { - if ( ShaderParent ) - { - bool v = !ShaderParent->isVisible (); - printf ( "shader node set visible %d\n",v ); - ShaderParent->setVisible ( v ); - if ( gui.Visible_Shader ) - gui.Visible_Shader->setChecked ( v ); - } - } - else - if (eve.KeyInput.Key == KEY_F5) - { - if ( FogParent ) - { - bool v = !FogParent->isVisible (); - printf ( "fog node set visible %d\n",v ); - FogParent->setVisible ( v ); - if ( gui.Visible_Fog ) - gui.Visible_Fog->setChecked ( v ); - } - - } - else - if (eve.KeyInput.Key == KEY_F6) - { - if ( UnresolvedParent ) - { - bool v = !UnresolvedParent->isVisible (); - printf ( "unresolved node set visible %d\n",v ); - UnresolvedParent->setVisible ( v ); - if ( gui.Visible_Unresolved ) - gui.Visible_Unresolved->setChecked ( v ); - } - } - } - - // check if user presses the key C ( for crouch) - if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_KEY_C ) - { - // crouch - ISceneNodeAnimatorCollisionResponse *anim = Player[0].cam (); - if ( anim && 0 == Game->flyTroughState ) - { - if ( false == eve.KeyInput.PressedDown ) - { - // stand up - anim->setEllipsoidRadius ( vector3df(30,45,30) ); - anim->setEllipsoidTranslation ( vector3df(0,40,0)); - - } - else - { - // on your knees - anim->setEllipsoidRadius ( vector3df(30,20,30) ); - anim->setEllipsoidTranslation ( vector3df(0,20,0)); - } - return true; - } - } - return false; -} -
useItem
-void CQuake3EventHandler::useItem( Q3Player * player) -{ - ISceneManager* smgr = Game->Device->getSceneManager(); - ICameraSceneNode* camera = smgr->getActiveCamera(); - - if (!camera) - return; - - SParticleImpact imp; - imp.when = 0; - - // get line of camera - - vector3df start = camera->getPosition(); - - if ( player->WeaponNode ) - { - start.X += 0.f; - start.Y += 0.f; - start.Z += 0.f; - } - - vector3df end = (camera->getTarget() - start); - end.normalize(); - start += end*20.0f; - - end = start + (end * camera->getFarValue()); - - triangle3df triangle; - line3d<f32> line(start, end); - - // get intersection point with map - scene::ISceneNode* hitNode; - if (smgr->getSceneCollisionManager()->getCollisionPoint( - line, Meta, end, triangle,hitNode)) - { - // collides with wall - vector3df out = triangle.getNormal(); - out.setLength(0.03f); - - imp.when = 1; - imp.outVector = out; - imp.pos = end; - - player->setAnim ( "pow" ); - player->Anim[1].next += player->Anim[1].delta; - } - else - { - // doesnt collide with wall - vector3df start = camera->getPosition(); - if ( player->WeaponNode ) - { - //start.X += 10.f; - //start.Y += -5.f; - //start.Z += 1.f; - } - - vector3df end = (camera->getTarget() - start); - end.normalize(); - start += end*20.0f; - end = start + (end * camera->getFarValue()); - } - - // create fire ball - ISceneNode* node = 0; - node = smgr->addBillboardSceneNode( BulletParent,dimension2d<f32>(10,10), start); - - node->setMaterialFlag(EMF_LIGHTING, false); - node->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture("fireball.bmp")); - node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); - node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR); - - f32 length = (f32)(end - start).getLength(); - const f32 speed = 5.8f; - u32 time = (u32)(length / speed); - - ISceneNodeAnimator* anim = 0; - - // set flight line - - anim = smgr->createFlyStraightAnimator(start, end, time); - node->addAnimator(anim); - anim->drop(); - - snprintf ( buf, 64, "bullet: %s on %.1f,%1.f,%1.f", - imp.when ? "hit" : "nohit", end.X, end.Y, end.Z ); - node->setName ( buf ); - - - anim = smgr->createDeleteAnimator(time); - node->addAnimator(anim); - anim->drop(); - - if (imp.when) - { - // create impact note - imp.when = Game->Device->getTimer()->getTime() + - (time + (s32) ( ( 1.f + Noiser::get() ) * 250.f )); - Impacts.push_back(imp); - } - - // play sound -} - -// rendered when bullets hit something -void CQuake3EventHandler::createParticleImpacts( u32 now ) -{ - ISceneManager* sm = Game->Device->getSceneManager(); - - struct smokeLayer - { - const c8 * texture; - f32 scale; - f32 minparticleSize; - f32 maxparticleSize; - f32 boxSize; - u32 minParticle; - u32 maxParticle; - u32 fadeout; - u32 lifetime; - }; - - smokeLayer smoke[] = - { - { "smoke2.jpg", 0.4f, 1.5f, 18.f, 20.f, 20, 50, 2000, 10000 }, - { "smoke3.jpg", 0.2f, 1.2f, 15.f, 20.f, 10, 30, 1000, 12000 } - }; - - - u32 i; - u32 g; - s32 factor = 1; - for ( g = 0; g != 2; ++g ) - { - smoke[g].minParticle *= factor; - smoke[g].maxParticle *= factor; - smoke[g].lifetime *= factor; - smoke[g].boxSize *= Noiser::get() * 0.5f; - } - - for ( i=0; i < Impacts.size(); ++i) - { - if (now < Impacts[i].when) - continue; - - // create smoke particle system - IParticleSystemSceneNode* pas = 0; - - for ( g = 0; g != 2; ++g ) - { - pas = sm->addParticleSystemSceneNode(false, BulletParent, -1, Impacts[i].pos); - - snprintf ( buf, 64, "bullet impact smoke at %.1f,%.1f,%1.f", - Impacts[i].pos.X,Impacts[i].pos.Y,Impacts[i].pos.Z); - pas->setName ( buf ); - - // create a flat smoke - vector3df direction = Impacts[i].outVector; - direction *= smoke[g].scale; - IParticleEmitter* em = pas->createBoxEmitter( - aabbox3d<f32>(-4.f,0.f,-4.f,20.f,smoke[g].minparticleSize,20.f), - direction,smoke[g].minParticle, smoke[g].maxParticle, - video::SColor(0,0,0,0),video::SColor(0,128,128,128), - 250,4000, 60); - - em->setMinStartSize (dimension2d<f32>( smoke[g].minparticleSize, smoke[g].minparticleSize)); - em->setMaxStartSize (dimension2d<f32>( smoke[g].maxparticleSize, smoke[g].maxparticleSize)); - - pas->setEmitter(em); - em->drop(); - - // particles get invisible - IParticleAffector* paf = pas->createFadeOutParticleAffector( - video::SColor ( 0, 0, 0, 0 ), smoke[g].fadeout); - pas->addAffector(paf); - paf->drop(); - - // particle system life time - ISceneNodeAnimator* anim = sm->createDeleteAnimator( smoke[g].lifetime); - pas->addAnimator(anim); - anim->drop(); - - pas->setMaterialFlag(video::EMF_LIGHTING, false); - pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); - pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); - pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture )); - } - - - // play impact sound - #ifdef USE_IRRKLANG -
if (irrKlang) { audio::ISound* sound = irrKlang->play3D(impactSound, Impacts[i].pos, false, false, true);
-if (sound) { adjust max value a bit to make to sound of an impact louder sound->setMinDistance(400); sound->drop(); } }
-#endif - - - // delete entry - Impacts.erase(i); - i--; - } -} -
render
-void CQuake3EventHandler::Render() -{ - IVideoDriver * driver = Game->Device->getVideoDriver(); - if ( 0 == driver ) - return; - - // TODO: This does not work, yet. - const bool anaglyph=false; - if (anaglyph) - { - scene::ICameraSceneNode* cameraOld = Game->Device->getSceneManager()->getActiveCamera(); - driver->beginScene(true, true, SColor(0,0,0,0)); - driver->getOverrideMaterial().Material.ColorMask = ECP_NONE; - driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = ESNRP_SKY_BOX + - ESNRP_SOLID + - ESNRP_TRANSPARENT + - ESNRP_TRANSPARENT_EFFECT + - ESNRP_SHADOW; - Game->Device->getSceneManager()->drawAll(); - driver->clearZBuffer(); - - const vector3df oldPosition = cameraOld->getPosition(); - const vector3df oldTarget = cameraOld->getTarget(); - const matrix4 startMatrix = cameraOld->getAbsoluteTransformation(); - const vector3df focusPoint = (oldTarget - - cameraOld->getAbsolutePosition()).setLength(10000) + - cameraOld->getAbsolutePosition() ; - - scene::ICameraSceneNode* camera = cameraOld;//Game->Device->getSceneManager()->addCameraSceneNode(); - - //Left eye... - vector3df pos; - matrix4 move; - - move.setTranslation( vector3df(-1.5f,0.0f,0.0f) ); - pos=(startMatrix*move).getTranslation(); - - driver->getOverrideMaterial().Material.ColorMask = ECP_RED; - driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = - ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| - ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; - - camera->setPosition(pos); - camera->setTarget(focusPoint); - - Game->Device->getSceneManager()->drawAll(); - driver->clearZBuffer(); - - //Right eye... - move.setTranslation( vector3df(1.5f,0.0f,0.0f) ); - pos=(startMatrix*move).getTranslation(); - - driver->getOverrideMaterial().Material.ColorMask = ECP_GREEN + ECP_BLUE; - driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; - driver->getOverrideMaterial().EnablePasses = - ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| - ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; - - camera->setPosition(pos); - camera->setTarget(focusPoint); - - Game->Device->getSceneManager()->drawAll(); - - driver->getOverrideMaterial().Material.ColorMask=ECP_ALL; - driver->getOverrideMaterial().EnableFlags=0; - driver->getOverrideMaterial().EnablePasses=0; - - if (camera != cameraOld) - { - Game->Device->getSceneManager()->setActiveCamera(cameraOld); - camera->remove(); - } - else - { - camera->setPosition(oldPosition); - camera->setTarget(oldTarget); - } - } - else - { - driver->beginScene(true, true, SColor(0,0,0,0)); - Game->Device->getSceneManager()->drawAll(); - } - Game->Device->getGUIEnvironment()->drawAll(); - driver->endScene(); -} -
update the generic scene node
-void CQuake3EventHandler::Animate() -{ - u32 now = Game->Device->getTimer()->getTime(); - - Q3Player * player = Player + 0; - - checkTimeFire ( player->Anim, 4, now ); - - // Query Scene Manager attributes - if ( player->Anim[0].flags & FIRED ) - { - ISceneManager *smgr = Game->Device->getSceneManager (); - wchar_t msg[128]; - IVideoDriver * driver = Game->Device->getVideoDriver(); - - IAttributes * attr = smgr->getParameters(); - swprintf ( msg, 128, - L"Q3 %s [%ls], FPS:%03d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)", - Game->CurrentMapName.c_str(), - driver->getName(), - driver->getFPS (), - (f32) driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ), - attr->getAttributeAsInt ( "culled" ), - attr->getAttributeAsInt ( "calls" ), - attr->getAttributeAsInt ( "drawn_solid" ), - attr->getAttributeAsInt ( "drawn_transparent" ), - attr->getAttributeAsInt ( "drawn_transparent_effect" ) - ); - Game->Device->setWindowCaption( msg ); - - swprintf ( msg, 128, - L"%03d fps, F1 GUI on/off, F2 respawn, F3-F6 toggle Nodes, F7 Collision on/off" - L", F8 Gravity on/off, Right Mouse Toggle GUI", - Game->Device->getVideoDriver()->getFPS () - ); - if ( gui.StatusLine ) - gui.StatusLine->setText ( msg ); - player->Anim[0].flags &= ~FIRED; - } - - // idle.. - if ( player->Anim[1].flags & FIRED ) - { - if ( strcmp ( player->animation, "idle" ) ) - player->setAnim ( "idle" ); - - player->Anim[1].flags &= ~FIRED; - } - - createParticleImpacts ( now ); - -} -
The main game states
-void runGame ( GameData *game ) -{ - if ( game->retVal >= 3 ) - return; - - game->Device = (*game->createExDevice) ( game->deviceParam ); - if ( 0 == game->Device) - { - // could not create selected driver. - game->retVal = 0; - return; - } - - // create an event receiver based on current game data - CQuake3EventHandler *eventHandler = new CQuake3EventHandler( game ); - - // load stored config - game->load ( "explorer.cfg" ); - - // add our media directory and archive to the file system - for ( u32 i = 0; i < game->CurrentArchiveList.size(); ++i ) - { - eventHandler->AddArchive ( game->CurrentArchiveList[i] ); - } - - // Load a Map or startup to the GUI - if ( game->CurrentMapName.size () ) - { - eventHandler->LoadMap ( game->CurrentMapName, 1 ); - if ( 0 == game->loadParam.loadSkyShader ) - eventHandler->AddSky ( 1, "skydome2" ); - eventHandler->CreatePlayers (); - eventHandler->CreateGUI (); - eventHandler->SetGUIActive ( 0 ); - - // set player to last position on restart - if ( game->retVal == 2 ) - { - eventHandler->GetPlayer( 0 )->setpos ( game->PlayerPosition, game->PlayerRotation ); - } - } - else - { - // start up empty - eventHandler->AddSky ( 1, "skydome2" ); - eventHandler->CreatePlayers (); - eventHandler->CreateGUI (); - eventHandler->SetGUIActive ( 1 ); - background_music ( "IrrlichtTheme.ogg" ); - } - - - game->retVal = 3; - while( game->Device->run() ) - { - eventHandler->Animate (); - eventHandler->Render (); - //if ( !game->Device->isWindowActive() ) - game->Device->yield(); - } - - game->Device->setGammaRamp ( 1.f, 1.f, 1.f, 0.f, 0.f ); - delete eventHandler; -} - -#if defined (_IRR_WINDOWS_) && 0 - #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") -#endif -
The main routine, doing all setup
-int IRRCALLCONV main(int argc, char* argv[]) -{ - path prgname(argv[0]); - GameData game ( deletePathFromPath ( prgname, 1 ) ); - - // dynamically load irrlicht - const c8 * dllName = argc > 1 ? argv[1] : "irrlicht.dll"; - game.createExDevice = load_createDeviceEx ( dllName ); - if ( 0 == game.createExDevice ) - { - game.retVal = 3; - printf ( "Could not load %s.\n", dllName ); - return game.retVal; // could not load dll - } - - // start without asking for driver - game.retVal = 1; - do - { - // if driver could not created, ask for another driver - if ( game.retVal == 0 ) - { - game.setDefault (); - // ask user for driver - game.deviceParam.DriverType=driverChoiceConsole(); - if (game.deviceParam.DriverType==video::EDT_COUNT) - game.retVal = 3; - } - runGame ( &game ); - } while ( game.retVal < 3 ); - - return game.retVal; -} -