diff options
author | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
commit | f9158592e1478b2013afc7041d9ed041cf2d2f4a (patch) | |
tree | b16e389d7988700e21b4c9741044cefa536dcbae /libraries/irrlicht-1.8.1/examples/21.Quake3Explorer/main.cpp | |
parent | Libraries readme updated with change markers and more of the Irrlicht changes. (diff) | |
download | SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.zip SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.gz SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.bz2 SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.xz |
Update Irrlicht to 1.8.1. Include actual change markers this time. lol
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8.1/examples/21.Quake3Explorer/main.cpp | 2188 |
1 files changed, 2188 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/examples/21.Quake3Explorer/main.cpp b/libraries/irrlicht-1.8.1/examples/21.Quake3Explorer/main.cpp new file mode 100644 index 0000000..b2277e6 --- /dev/null +++ b/libraries/irrlicht-1.8.1/examples/21.Quake3Explorer/main.cpp | |||
@@ -0,0 +1,2188 @@ | |||
1 | /** Example 021 Quake3 Explorer | ||
2 | |||
3 | This Tutorial shows how to load different Quake 3 maps. | ||
4 | |||
5 | Features: | ||
6 | - Load BSP Archives at Runtime from the menu | ||
7 | - Load a Map from the menu. Showing with Screenshot | ||
8 | - Set the VideoDriver at runtime from menu | ||
9 | - Adjust GammaLevel at runtime | ||
10 | - Create SceneNodes for the Shaders | ||
11 | - Load EntityList and create Entity SceneNodes | ||
12 | - Create Players with Weapons and with Collision Response | ||
13 | - Play music | ||
14 | |||
15 | You can download the Quake III Arena demo ( copyright id software ) | ||
16 | at the following location: | ||
17 | ftp://ftp.idsoftware.com/idstuff/quake3/win32/q3ademo.exe | ||
18 | |||
19 | Copyright 2006-2011 Burningwater, Thomas Alten | ||
20 | */ | ||
21 | |||
22 | #include "driverChoice.h" | ||
23 | #include <irrlicht.h> | ||
24 | #include "q3factory.h" | ||
25 | #include "sound.h" | ||
26 | |||
27 | /* | ||
28 | Game Data is used to hold Data which is needed to drive the game | ||
29 | */ | ||
30 | struct GameData | ||
31 | { | ||
32 | GameData ( const path &startupDir) : | ||
33 | retVal(0), StartupDir(startupDir), createExDevice(0), Device(0) | ||
34 | { | ||
35 | setDefault (); | ||
36 | } | ||
37 | |||
38 | void setDefault (); | ||
39 | s32 save ( const path &filename ); | ||
40 | s32 load ( const path &filename ); | ||
41 | |||
42 | s32 debugState; | ||
43 | s32 gravityState; | ||
44 | s32 flyTroughState; | ||
45 | s32 wireFrame; | ||
46 | s32 guiActive; | ||
47 | s32 guiInputActive; | ||
48 | f32 GammaValue; | ||
49 | s32 retVal; | ||
50 | s32 sound; | ||
51 | |||
52 | path StartupDir; | ||
53 | stringw CurrentMapName; | ||
54 | array<path> CurrentArchiveList; | ||
55 | |||
56 | vector3df PlayerPosition; | ||
57 | vector3df PlayerRotation; | ||
58 | |||
59 | tQ3EntityList Variable; | ||
60 | |||
61 | Q3LevelLoadParameter loadParam; | ||
62 | SIrrlichtCreationParameters deviceParam; | ||
63 | funcptr_createDeviceEx createExDevice; | ||
64 | IrrlichtDevice *Device; | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | set default settings | ||
69 | */ | ||
70 | void GameData::setDefault () | ||
71 | { | ||
72 | debugState = EDS_OFF; | ||
73 | gravityState = 1; | ||
74 | flyTroughState = 0; | ||
75 | wireFrame = 0; | ||
76 | guiActive = 1; | ||
77 | guiInputActive = 0; | ||
78 | GammaValue = 1.f; | ||
79 | |||
80 | // default deviceParam; | ||
81 | #if defined ( _IRR_WINDOWS_ ) | ||
82 | deviceParam.DriverType = EDT_DIRECT3D9; | ||
83 | #else | ||
84 | deviceParam.DriverType = EDT_OPENGL; | ||
85 | #endif | ||
86 | deviceParam.WindowSize.Width = 800; | ||
87 | deviceParam.WindowSize.Height = 600; | ||
88 | deviceParam.Fullscreen = false; | ||
89 | deviceParam.Bits = 24; | ||
90 | deviceParam.ZBufferBits = 16; | ||
91 | deviceParam.Vsync = false; | ||
92 | deviceParam.AntiAlias = false; | ||
93 | |||
94 | // default Quake3 loadParam | ||
95 | loadParam.defaultLightMapMaterial = EMT_LIGHTMAP; | ||
96 | loadParam.defaultModulate = EMFN_MODULATE_1X; | ||
97 | loadParam.defaultFilter = EMF_ANISOTROPIC_FILTER; | ||
98 | loadParam.verbose = 2; | ||
99 | loadParam.mergeShaderBuffer = 1; // merge meshbuffers with same material | ||
100 | loadParam.cleanUnResolvedMeshes = 1; // should unresolved meshes be cleaned. otherwise blue texture | ||
101 | loadParam.loadAllShaders = 1; // load all scripts in the script directory | ||
102 | loadParam.loadSkyShader = 0; // load sky Shader | ||
103 | loadParam.alpharef = 1; | ||
104 | |||
105 | sound = 0; | ||
106 | |||
107 | CurrentMapName = ""; | ||
108 | CurrentArchiveList.clear (); | ||
109 | |||
110 | // Explorer Media directory | ||
111 | CurrentArchiveList.push_back ( StartupDir + "../../media/" ); | ||
112 | |||
113 | // Add the original quake3 files before you load your custom map | ||
114 | // Most mods are using the original shaders, models&items&weapons | ||
115 | CurrentArchiveList.push_back("/q/baseq3/"); | ||
116 | |||
117 | CurrentArchiveList.push_back(StartupDir + "../../media/map-20kdm2.pk3"); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | Load the current game State from a typical quake3 cfg file | ||
122 | */ | ||
123 | s32 GameData::load ( const path &filename ) | ||
124 | { | ||
125 | if (!Device) | ||
126 | return 0; | ||
127 | |||
128 | // the quake3 mesh loader can also handle *.shader and *.cfg file | ||
129 | IQ3LevelMesh* mesh = (IQ3LevelMesh*) Device->getSceneManager()->getMesh ( filename ); | ||
130 | if (!mesh) | ||
131 | return 0; | ||
132 | |||
133 | tQ3EntityList &entityList = mesh->getEntityList (); | ||
134 | |||
135 | stringc s; | ||
136 | u32 pos; | ||
137 | |||
138 | for ( u32 e = 0; e != entityList.size (); ++e ) | ||
139 | { | ||
140 | //dumpShader ( s, &entityList[e], false ); | ||
141 | //printf ( s.c_str () ); | ||
142 | |||
143 | for ( u32 g = 0; g != entityList[e].getGroupSize (); ++g ) | ||
144 | { | ||
145 | const SVarGroup *group = entityList[e].getGroup ( g ); | ||
146 | |||
147 | for ( u32 index = 0; index < group->Variable.size (); ++index ) | ||
148 | { | ||
149 | const SVariable &v = group->Variable[index]; | ||
150 | pos = 0; | ||
151 | if ( v.name == "playerposition" ) | ||
152 | { | ||
153 | PlayerPosition = getAsVector3df ( v.content, pos ); | ||
154 | } | ||
155 | else | ||
156 | if ( v.name == "playerrotation" ) | ||
157 | { | ||
158 | PlayerRotation = getAsVector3df ( v.content, pos ); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | return 1; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | Store the current game State in a quake3 configuration file | ||
169 | */ | ||
170 | s32 GameData::save ( const path &filename ) | ||
171 | { | ||
172 | return 0; | ||
173 | if (!Device) | ||
174 | return 0; | ||
175 | |||
176 | c8 buf[128]; | ||
177 | u32 i; | ||
178 | |||
179 | // Store current Archive for restart | ||
180 | CurrentArchiveList.clear(); | ||
181 | IFileSystem *fs = Device->getFileSystem(); | ||
182 | for ( i = 0; i != fs->getFileArchiveCount(); ++i ) | ||
183 | { | ||
184 | CurrentArchiveList.push_back ( fs->getFileArchive(i)->getFileList()->getPath() ); | ||
185 | } | ||
186 | |||
187 | // Store Player Position and Rotation | ||
188 | ICameraSceneNode * camera = Device->getSceneManager()->getActiveCamera (); | ||
189 | if ( camera ) | ||
190 | { | ||
191 | PlayerPosition = camera->getPosition (); | ||
192 | PlayerRotation = camera->getRotation (); | ||
193 | } | ||
194 | |||
195 | IWriteFile *file = fs->createAndWriteFile ( filename ); | ||
196 | if (!file) | ||
197 | return 0; | ||
198 | |||
199 | snprintf ( buf, 128, "playerposition %.f %.f %.f\nplayerrotation %.f %.f %.f\n", | ||
200 | PlayerPosition.X, PlayerPosition.Z, PlayerPosition.Y, | ||
201 | PlayerRotation.X, PlayerRotation.Z, PlayerRotation.Y); | ||
202 | file->write ( buf, (s32) strlen ( buf ) ); | ||
203 | for ( i = 0; i != fs->getFileArchiveCount(); ++i ) | ||
204 | { | ||
205 | snprintf ( buf, 128, "archive %s\n",stringc ( fs->getFileArchive(i)->getFileList()->getPath() ).c_str () ); | ||
206 | file->write ( buf, (s32) strlen ( buf ) ); | ||
207 | } | ||
208 | |||
209 | file->drop (); | ||
210 | return 1; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | Representing a player | ||
215 | */ | ||
216 | struct Q3Player : public IAnimationEndCallBack | ||
217 | { | ||
218 | Q3Player () | ||
219 | : Device(0), MapParent(0), Mesh(0), WeaponNode(0), StartPositionCurrent(0) | ||
220 | { | ||
221 | animation[0] = 0; | ||
222 | memset(Anim, 0, sizeof(TimeFire)*4); | ||
223 | } | ||
224 | |||
225 | virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node); | ||
226 | |||
227 | void create ( IrrlichtDevice *device, | ||
228 | IQ3LevelMesh* mesh, | ||
229 | ISceneNode *mapNode, | ||
230 | IMetaTriangleSelector *meta | ||
231 | ); | ||
232 | void shutdown (); | ||
233 | void setAnim ( const c8 *name ); | ||
234 | void respawn (); | ||
235 | void setpos ( const vector3df &pos, const vector3df& rotation ); | ||
236 | |||
237 | ISceneNodeAnimatorCollisionResponse * cam() { return camCollisionResponse ( Device ); } | ||
238 | |||
239 | IrrlichtDevice *Device; | ||
240 | ISceneNode* MapParent; | ||
241 | IQ3LevelMesh* Mesh; | ||
242 | IAnimatedMeshSceneNode* WeaponNode; | ||
243 | s32 StartPositionCurrent; | ||
244 | TimeFire Anim[4]; | ||
245 | c8 animation[64]; | ||
246 | c8 buf[64]; | ||
247 | }; | ||
248 | |||
249 | |||
250 | /* End player | ||
251 | */ | ||
252 | void Q3Player::shutdown () | ||
253 | { | ||
254 | setAnim ( 0 ); | ||
255 | |||
256 | dropElement (WeaponNode); | ||
257 | |||
258 | if ( Device ) | ||
259 | { | ||
260 | ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); | ||
261 | dropElement ( camera ); | ||
262 | Device = 0; | ||
263 | } | ||
264 | |||
265 | MapParent = 0; | ||
266 | Mesh = 0; | ||
267 | } | ||
268 | |||
269 | |||
270 | /* create a new player | ||
271 | */ | ||
272 | void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode *mapNode, IMetaTriangleSelector *meta ) | ||
273 | { | ||
274 | setTimeFire ( Anim + 0, 200, FIRED ); | ||
275 | setTimeFire ( Anim + 1, 5000 ); | ||
276 | |||
277 | if (!device) | ||
278 | return; | ||
279 | // load FPS weapon to Camera | ||
280 | Device = device; | ||
281 | Mesh = mesh; | ||
282 | MapParent = mapNode; | ||
283 | |||
284 | ISceneManager *smgr = device->getSceneManager (); | ||
285 | IVideoDriver * driver = device->getVideoDriver(); | ||
286 | |||
287 | ICameraSceneNode* camera = 0; | ||
288 | |||
289 | SKeyMap keyMap[10]; | ||
290 | keyMap[0].Action = EKA_MOVE_FORWARD; | ||
291 | keyMap[0].KeyCode = KEY_UP; | ||
292 | keyMap[1].Action = EKA_MOVE_FORWARD; | ||
293 | keyMap[1].KeyCode = KEY_KEY_W; | ||
294 | |||
295 | keyMap[2].Action = EKA_MOVE_BACKWARD; | ||
296 | keyMap[2].KeyCode = KEY_DOWN; | ||
297 | keyMap[3].Action = EKA_MOVE_BACKWARD; | ||
298 | keyMap[3].KeyCode = KEY_KEY_S; | ||
299 | |||
300 | keyMap[4].Action = EKA_STRAFE_LEFT; | ||
301 | keyMap[4].KeyCode = KEY_LEFT; | ||
302 | keyMap[5].Action = EKA_STRAFE_LEFT; | ||
303 | keyMap[5].KeyCode = KEY_KEY_A; | ||
304 | |||
305 | keyMap[6].Action = EKA_STRAFE_RIGHT; | ||
306 | keyMap[6].KeyCode = KEY_RIGHT; | ||
307 | keyMap[7].Action = EKA_STRAFE_RIGHT; | ||
308 | keyMap[7].KeyCode = KEY_KEY_D; | ||
309 | |||
310 | keyMap[8].Action = EKA_JUMP_UP; | ||
311 | keyMap[8].KeyCode = KEY_KEY_J; | ||
312 | |||
313 | keyMap[9].Action = EKA_CROUCH; | ||
314 | keyMap[9].KeyCode = KEY_KEY_C; | ||
315 | |||
316 | camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 0.6f); | ||
317 | camera->setName ( "First Person Camera" ); | ||
318 | //camera->setFOV ( 100.f * core::DEGTORAD ); | ||
319 | camera->setFarValue( 20000.f ); | ||
320 | |||
321 | IAnimatedMeshMD2* weaponMesh = (IAnimatedMeshMD2*) smgr->getMesh("gun.md2"); | ||
322 | if ( 0 == weaponMesh ) | ||
323 | return; | ||
324 | |||
325 | if ( weaponMesh->getMeshType() == EAMT_MD2 ) | ||
326 | { | ||
327 | s32 count = weaponMesh->getAnimationCount(); | ||
328 | for ( s32 i = 0; i != count; ++i ) | ||
329 | { | ||
330 | snprintf ( buf, 64, "Animation: %s", weaponMesh->getAnimationName(i) ); | ||
331 | device->getLogger()->log(buf, ELL_INFORMATION); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | WeaponNode = smgr->addAnimatedMeshSceneNode( | ||
336 | weaponMesh, | ||
337 | smgr->getActiveCamera(), | ||
338 | 10, | ||
339 | vector3df( 0, 0, 0), | ||
340 | vector3df(-90,-90,90) | ||
341 | ); | ||
342 | WeaponNode->setMaterialFlag(EMF_LIGHTING, false); | ||
343 | WeaponNode->setMaterialTexture(0, driver->getTexture( "gun.jpg")); | ||
344 | WeaponNode->setLoopMode ( false ); | ||
345 | WeaponNode->setName ( "tommi the gun man" ); | ||
346 | |||
347 | //create a collision auto response animator | ||
348 | ISceneNodeAnimator* anim = | ||
349 | smgr->createCollisionResponseAnimator( meta, camera, | ||
350 | vector3df(30,45,30), | ||
351 | getGravity ( "earth" ), | ||
352 | vector3df(0,40,0), | ||
353 | 0.0005f | ||
354 | ); | ||
355 | |||
356 | camera->addAnimator( anim ); | ||
357 | anim->drop(); | ||
358 | |||
359 | if ( meta ) | ||
360 | { | ||
361 | meta->drop (); | ||
362 | } | ||
363 | |||
364 | respawn (); | ||
365 | setAnim ( "idle" ); | ||
366 | } | ||
367 | |||
368 | |||
369 | /* | ||
370 | so we need a good starting Position in the level. | ||
371 | we can ask the Quake3 Loader for all entities with class_name "info_player_deathmatch" | ||
372 | */ | ||
373 | void Q3Player::respawn () | ||
374 | { | ||
375 | if (!Device) | ||
376 | return; | ||
377 | ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); | ||
378 | |||
379 | Device->getLogger()->log( "respawn" ); | ||
380 | |||
381 | if ( StartPositionCurrent >= Q3StartPosition ( | ||
382 | Mesh, camera,StartPositionCurrent++, | ||
383 | cam ()->getEllipsoidTranslation() ) | ||
384 | ) | ||
385 | { | ||
386 | StartPositionCurrent = 0; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | set Player position from saved coordinates | ||
392 | */ | ||
393 | void Q3Player::setpos ( const vector3df &pos, const vector3df &rotation ) | ||
394 | { | ||
395 | if (!Device) | ||
396 | return; | ||
397 | Device->getLogger()->log( "setpos" ); | ||
398 | |||
399 | ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera(); | ||
400 | if ( camera ) | ||
401 | { | ||
402 | camera->setPosition ( pos ); | ||
403 | camera->setRotation ( rotation ); | ||
404 | //! New. FPSCamera and animators catches reset on animate 0 | ||
405 | camera->OnAnimate ( 0 ); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | /* set the Animation of the player and weapon | ||
410 | */ | ||
411 | void Q3Player::setAnim ( const c8 *name ) | ||
412 | { | ||
413 | if ( name ) | ||
414 | { | ||
415 | snprintf ( animation, 64, "%s", name ); | ||
416 | if ( WeaponNode ) | ||
417 | { | ||
418 | WeaponNode->setAnimationEndCallback ( this ); | ||
419 | WeaponNode->setMD2Animation ( animation ); | ||
420 | } | ||
421 | } | ||
422 | else | ||
423 | { | ||
424 | animation[0] = 0; | ||
425 | if ( WeaponNode ) | ||
426 | { | ||
427 | WeaponNode->setAnimationEndCallback ( 0 ); | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | |||
432 | |||
433 | // Callback | ||
434 | void Q3Player::OnAnimationEnd(IAnimatedMeshSceneNode* node) | ||
435 | { | ||
436 | setAnim ( 0 ); | ||
437 | } | ||
438 | |||
439 | |||
440 | |||
441 | /* GUI Elements | ||
442 | */ | ||
443 | struct GUI | ||
444 | { | ||
445 | GUI () | ||
446 | { | ||
447 | memset ( this, 0, sizeof ( *this ) ); | ||
448 | } | ||
449 | |||
450 | void drop() | ||
451 | { | ||
452 | dropElement ( Window ); | ||
453 | dropElement ( Logo ); | ||
454 | } | ||
455 | |||
456 | IGUIComboBox* VideoDriver; | ||
457 | IGUIComboBox* VideoMode; | ||
458 | IGUICheckBox* FullScreen; | ||
459 | IGUICheckBox* Bit32; | ||
460 | IGUIScrollBar* MultiSample; | ||
461 | IGUIButton* SetVideoMode; | ||
462 | |||
463 | IGUIScrollBar* Tesselation; | ||
464 | IGUIScrollBar* Gamma; | ||
465 | IGUICheckBox* Collision; | ||
466 | IGUICheckBox* Visible_Map; | ||
467 | IGUICheckBox* Visible_Shader; | ||
468 | IGUICheckBox* Visible_Fog; | ||
469 | IGUICheckBox* Visible_Unresolved; | ||
470 | IGUICheckBox* Visible_Skydome; | ||
471 | IGUIButton* Respawn; | ||
472 | |||
473 | IGUITable* ArchiveList; | ||
474 | IGUIButton* ArchiveAdd; | ||
475 | IGUIButton* ArchiveRemove; | ||
476 | IGUIFileOpenDialog* ArchiveFileOpen; | ||
477 | IGUIButton* ArchiveUp; | ||
478 | IGUIButton* ArchiveDown; | ||
479 | |||
480 | IGUIListBox* MapList; | ||
481 | IGUITreeView* SceneTree; | ||
482 | IGUIStaticText* StatusLine; | ||
483 | IGUIImage* Logo; | ||
484 | IGUIWindow* Window; | ||
485 | }; | ||
486 | |||
487 | |||
488 | /* | ||
489 | CQuake3EventHandler controls the game | ||
490 | */ | ||
491 | class CQuake3EventHandler : public IEventReceiver | ||
492 | { | ||
493 | public: | ||
494 | |||
495 | CQuake3EventHandler( GameData *gameData ); | ||
496 | virtual ~CQuake3EventHandler (); | ||
497 | |||
498 | void Animate(); | ||
499 | void Render(); | ||
500 | |||
501 | void AddArchive ( const path& archiveName ); | ||
502 | void LoadMap ( const stringw& mapName, s32 collision ); | ||
503 | void CreatePlayers(); | ||
504 | void AddSky( u32 dome, const c8 *texture ); | ||
505 | Q3Player *GetPlayer ( u32 index ) { return &Player[index]; } | ||
506 | |||
507 | void CreateGUI(); | ||
508 | void SetGUIActive( s32 command); | ||
509 | |||
510 | bool OnEvent(const SEvent& eve); | ||
511 | |||
512 | |||
513 | private: | ||
514 | |||
515 | GameData *Game; | ||
516 | |||
517 | IQ3LevelMesh* Mesh; | ||
518 | ISceneNode* MapParent; | ||
519 | ISceneNode* ShaderParent; | ||
520 | ISceneNode* ItemParent; | ||
521 | ISceneNode* UnresolvedParent; | ||
522 | ISceneNode* BulletParent; | ||
523 | ISceneNode* FogParent; | ||
524 | ISceneNode * SkyNode; | ||
525 | IMetaTriangleSelector *Meta; | ||
526 | |||
527 | c8 buf[256]; | ||
528 | |||
529 | Q3Player Player[2]; | ||
530 | |||
531 | struct SParticleImpact | ||
532 | { | ||
533 | u32 when; | ||
534 | vector3df pos; | ||
535 | vector3df outVector; | ||
536 | }; | ||
537 | array<SParticleImpact> Impacts; | ||
538 | void useItem( Q3Player * player); | ||
539 | void createParticleImpacts( u32 now ); | ||
540 | |||
541 | void createTextures (); | ||
542 | void addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent); | ||
543 | |||
544 | GUI gui; | ||
545 | void dropMap (); | ||
546 | }; | ||
547 | |||
548 | /* Constructor | ||
549 | */ | ||
550 | CQuake3EventHandler::CQuake3EventHandler( GameData *game ) | ||
551 | : Game(game), Mesh(0), MapParent(0), ShaderParent(0), ItemParent(0), UnresolvedParent(0), | ||
552 | BulletParent(0), FogParent(0), SkyNode(0), Meta(0) | ||
553 | { | ||
554 | buf[0]=0; | ||
555 | // Also use 16 Bit Textures for 16 Bit RenderDevice | ||
556 | if ( Game->deviceParam.Bits == 16 ) | ||
557 | { | ||
558 | game->Device->getVideoDriver()->setTextureCreationFlag(ETCF_ALWAYS_16_BIT, true); | ||
559 | } | ||
560 | |||
561 | // Quake3 Shader controls Z-Writing | ||
562 | game->Device->getSceneManager()->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); | ||
563 | |||
564 | // create internal textures | ||
565 | createTextures (); | ||
566 | |||
567 | sound_init ( game->Device ); | ||
568 | |||
569 | Game->Device->setEventReceiver ( this ); | ||
570 | } | ||
571 | |||
572 | |||
573 | // destructor | ||
574 | CQuake3EventHandler::~CQuake3EventHandler () | ||
575 | { | ||
576 | Player[0].shutdown (); | ||
577 | sound_shutdown (); | ||
578 | |||
579 | Game->save( "explorer.cfg" ); | ||
580 | |||
581 | Game->Device->drop(); | ||
582 | } | ||
583 | |||
584 | |||
585 | // create runtime textures smog, fog | ||
586 | void CQuake3EventHandler::createTextures() | ||
587 | { | ||
588 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
589 | |||
590 | dimension2du dim(64, 64); | ||
591 | |||
592 | video::IImage* image; | ||
593 | u32 i; | ||
594 | u32 x; | ||
595 | u32 y; | ||
596 | u32 * data; | ||
597 | for ( i = 0; i != 8; ++i ) | ||
598 | { | ||
599 | image = driver->createImage ( video::ECF_A8R8G8B8, dim); | ||
600 | data = (u32*) image->lock (); | ||
601 | for ( y = 0; y != dim.Height; ++y ) | ||
602 | { | ||
603 | for ( x = 0; x != dim.Width; ++x ) | ||
604 | { | ||
605 | data [x] = 0xFFFFFFFF; | ||
606 | } | ||
607 | data = (u32*) ( (u8*) data + image->getPitch() ); | ||
608 | } | ||
609 | image->unlock(); | ||
610 | snprintf ( buf, 64, "smoke_%02d", i ); | ||
611 | driver->addTexture( buf, image ); | ||
612 | image->drop (); | ||
613 | } | ||
614 | |||
615 | // fog | ||
616 | for ( i = 0; i != 1; ++i ) | ||
617 | { | ||
618 | image = driver->createImage ( video::ECF_A8R8G8B8, dim); | ||
619 | data = (u32*) image->lock (); | ||
620 | for ( y = 0; y != dim.Height; ++y ) | ||
621 | { | ||
622 | for ( x = 0; x != dim.Width; ++x ) | ||
623 | { | ||
624 | data [x] = 0xFFFFFFFF; | ||
625 | } | ||
626 | data = (u32*) ( (u8*) data + image->getPitch() ); | ||
627 | } | ||
628 | image->unlock(); | ||
629 | snprintf ( buf, 64, "fog_%02d", i ); | ||
630 | driver->addTexture( buf, image ); | ||
631 | image->drop (); | ||
632 | } | ||
633 | } | ||
634 | |||
635 | |||
636 | /* | ||
637 | create the GUI | ||
638 | */ | ||
639 | void CQuake3EventHandler::CreateGUI() | ||
640 | { | ||
641 | |||
642 | IGUIEnvironment *env = Game->Device->getGUIEnvironment(); | ||
643 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
644 | |||
645 | gui.drop(); | ||
646 | |||
647 | // set skin font | ||
648 | IGUIFont* font = env->getFont("fontlucida.png"); | ||
649 | if (font) | ||
650 | env->getSkin()->setFont(font); | ||
651 | env->getSkin()->setColor ( EGDC_BUTTON_TEXT, video::SColor(240,0xAA,0xAA,0xAA) ); | ||
652 | env->getSkin()->setColor ( EGDC_3D_HIGH_LIGHT, video::SColor(240,0x22,0x22,0x22) ); | ||
653 | env->getSkin()->setColor ( EGDC_3D_FACE, video::SColor(240,0x44,0x44,0x44) ); | ||
654 | env->getSkin()->setColor ( EGDC_EDITABLE, video::SColor(240,0x44,0x44,0x44) ); | ||
655 | env->getSkin()->setColor ( EGDC_FOCUSED_EDITABLE, video::SColor(240,0x54,0x54,0x54) ); | ||
656 | env->getSkin()->setColor ( EGDC_WINDOW, video::SColor(240,0x66,0x66,0x66) ); | ||
657 | |||
658 | // minimal gui size 800x600 | ||
659 | dimension2d<u32> dim ( 800, 600 ); | ||
660 | dimension2d<u32> vdim ( Game->Device->getVideoDriver()->getScreenSize() ); | ||
661 | |||
662 | if ( vdim.Height >= dim.Height && vdim.Width >= dim.Width ) | ||
663 | { | ||
664 | //dim = vdim; | ||
665 | } | ||
666 | else | ||
667 | { | ||
668 | } | ||
669 | |||
670 | gui.Window = env->addWindow ( rect<s32> ( 0, 0, dim.Width, dim.Height ), false, L"Quake3 Explorer" ); | ||
671 | gui.Window->setToolTipText ( L"Quake3Explorer. Loads and show various BSP File Format and Shaders." ); | ||
672 | gui.Window->getCloseButton()->setToolTipText ( L"Quit Quake3 Explorer" ); | ||
673 | |||
674 | // add a status line help text | ||
675 | gui.StatusLine = env->addStaticText( 0, rect<s32>( 5,dim.Height - 30,dim.Width - 5,dim.Height - 10), | ||
676 | false, false, gui.Window, -1, true | ||
677 | ); | ||
678 | |||
679 | |||
680 | env->addStaticText ( L"VideoDriver:", rect<s32>( dim.Width - 400, 24, dim.Width - 310, 40 ),false, false, gui.Window, -1, false ); | ||
681 | gui.VideoDriver = env->addComboBox(rect<s32>( dim.Width - 300, 24, dim.Width - 10, 40 ),gui.Window); | ||
682 | gui.VideoDriver->addItem(L"Direct3D 9.0c", EDT_DIRECT3D9 ); | ||
683 | gui.VideoDriver->addItem(L"Direct3D 8.1", EDT_DIRECT3D8 ); | ||
684 | gui.VideoDriver->addItem(L"OpenGL 1.5", EDT_OPENGL); | ||
685 | gui.VideoDriver->addItem(L"Software Renderer", EDT_SOFTWARE); | ||
686 | gui.VideoDriver->addItem(L"Burning's Video (TM) Thomas Alten", EDT_BURNINGSVIDEO); | ||
687 | gui.VideoDriver->setSelected ( gui.VideoDriver->getIndexForItemData ( Game->deviceParam.DriverType ) ); | ||
688 | gui.VideoDriver->setToolTipText ( L"Use a VideoDriver" ); | ||
689 | |||
690 | env->addStaticText ( L"VideoMode:", rect<s32>( dim.Width - 400, 44, dim.Width - 310, 60 ),false, false, gui.Window, -1, false ); | ||
691 | gui.VideoMode = env->addComboBox(rect<s32>( dim.Width - 300, 44, dim.Width - 10, 60 ),gui.Window); | ||
692 | gui.VideoMode->setToolTipText ( L"Supported Screenmodes" ); | ||
693 | IVideoModeList *modeList = Game->Device->getVideoModeList(); | ||
694 | if ( modeList ) | ||
695 | { | ||
696 | s32 i; | ||
697 | for ( i = 0; i != modeList->getVideoModeCount (); ++i ) | ||
698 | { | ||
699 | u16 d = modeList->getVideoModeDepth ( i ); | ||
700 | if ( d < 16 ) | ||
701 | continue; | ||
702 | |||
703 | u16 w = modeList->getVideoModeResolution ( i ).Width; | ||
704 | u16 h = modeList->getVideoModeResolution ( i ).Height; | ||
705 | u32 val = w << 16 | h; | ||
706 | |||
707 | if ( gui.VideoMode->getIndexForItemData ( val ) >= 0 ) | ||
708 | continue; | ||
709 | |||
710 | f32 aspect = (f32) w / (f32) h; | ||
711 | const c8 *a = ""; | ||
712 | if ( core::equals ( aspect, 1.3333333333f ) ) a = "4:3"; | ||
713 | else if ( core::equals ( aspect, 1.6666666f ) ) a = "15:9 widescreen"; | ||
714 | else if ( core::equals ( aspect, 1.7777777f ) ) a = "16:9 widescreen"; | ||
715 | else if ( core::equals ( aspect, 1.6f ) ) a = "16:10 widescreen"; | ||
716 | else if ( core::equals ( aspect, 2.133333f ) ) a = "20:9 widescreen"; | ||
717 | |||
718 | snprintf ( buf, sizeof ( buf ), "%d x %d, %s",w, h, a ); | ||
719 | gui.VideoMode->addItem ( stringw ( buf ).c_str(), val ); | ||
720 | } | ||
721 | } | ||
722 | gui.VideoMode->setSelected ( gui.VideoMode->getIndexForItemData ( | ||
723 | Game->deviceParam.WindowSize.Width << 16 | | ||
724 | Game->deviceParam.WindowSize.Height ) ); | ||
725 | |||
726 | gui.FullScreen = env->addCheckBox ( Game->deviceParam.Fullscreen, rect<s32>( dim.Width - 400, 64, dim.Width - 300, 80 ), gui.Window,-1, L"Fullscreen" ); | ||
727 | gui.FullScreen->setToolTipText ( L"Set Fullscreen or Window Mode" ); | ||
728 | |||
729 | gui.Bit32 = env->addCheckBox ( Game->deviceParam.Bits == 32, rect<s32>( dim.Width - 300, 64, dim.Width - 240, 80 ), gui.Window,-1, L"32Bit" ); | ||
730 | gui.Bit32->setToolTipText ( L"Use 16 or 32 Bit" ); | ||
731 | |||
732 | env->addStaticText ( L"MultiSample:", rect<s32>( dim.Width - 235, 64, dim.Width - 150, 80 ),false, false, gui.Window, -1, false ); | ||
733 | gui.MultiSample = env->addScrollBar( true, rect<s32>( dim.Width - 150, 64, dim.Width - 70, 80 ), gui.Window,-1 ); | ||
734 | gui.MultiSample->setMin ( 0 ); | ||
735 | gui.MultiSample->setMax ( 8 ); | ||
736 | gui.MultiSample->setSmallStep ( 1 ); | ||
737 | gui.MultiSample->setLargeStep ( 1 ); | ||
738 | gui.MultiSample->setPos ( Game->deviceParam.AntiAlias ); | ||
739 | gui.MultiSample->setToolTipText ( L"Set the MultiSample (disable, 1x, 2x, 4x, 8x )" ); | ||
740 | |||
741 | gui.SetVideoMode = env->addButton (rect<s32>( dim.Width - 60, 64, dim.Width - 10, 80 ), gui.Window, -1,L"set" ); | ||
742 | gui.SetVideoMode->setToolTipText ( L"Set Video Mode with current values" ); | ||
743 | |||
744 | env->addStaticText ( L"Gamma:", rect<s32>( dim.Width - 400, 104, dim.Width - 310, 120 ),false, false, gui.Window, -1, false ); | ||
745 | gui.Gamma = env->addScrollBar( true, rect<s32>( dim.Width - 300, 104, dim.Width - 10, 120 ), gui.Window,-1 ); | ||
746 | gui.Gamma->setMin ( 50 ); | ||
747 | gui.Gamma->setMax ( 350 ); | ||
748 | gui.Gamma->setSmallStep ( 1 ); | ||
749 | gui.Gamma->setLargeStep ( 10 ); | ||
750 | gui.Gamma->setPos ( core::floor32 ( Game->GammaValue * 100.f ) ); | ||
751 | gui.Gamma->setToolTipText ( L"Adjust Gamma Ramp ( 0.5 - 3.5)" ); | ||
752 | Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); | ||
753 | |||
754 | |||
755 | env->addStaticText ( L"Tesselation:", rect<s32>( dim.Width - 400, 124, dim.Width - 310, 140 ),false, false, gui.Window, -1, false ); | ||
756 | gui.Tesselation = env->addScrollBar( true, rect<s32>( dim.Width - 300, 124, dim.Width - 10, 140 ), gui.Window,-1 ); | ||
757 | gui.Tesselation->setMin ( 2 ); | ||
758 | gui.Tesselation->setMax ( 12 ); | ||
759 | gui.Tesselation->setSmallStep ( 1 ); | ||
760 | gui.Tesselation->setLargeStep ( 1 ); | ||
761 | gui.Tesselation->setPos ( Game->loadParam.patchTesselation ); | ||
762 | gui.Tesselation->setToolTipText ( L"How smooth should curved surfaces be rendered" ); | ||
763 | |||
764 | gui.Collision = env->addCheckBox ( true, rect<s32>( dim.Width - 400, 150, dim.Width - 300, 166 ), gui.Window,-1, L"Collision" ); | ||
765 | gui.Collision->setToolTipText ( L"Set collision on or off ( flythrough ). \nPress F7 on your Keyboard" ); | ||
766 | gui.Visible_Map = env->addCheckBox ( true, rect<s32>( dim.Width - 300, 150, dim.Width - 240, 166 ), gui.Window,-1, L"Map" ); | ||
767 | gui.Visible_Map->setToolTipText ( L"Show or not show the static part the Level. \nPress F3 on your Keyboard" ); | ||
768 | gui.Visible_Shader = env->addCheckBox ( true, rect<s32>( dim.Width - 240, 150, dim.Width - 170, 166 ), gui.Window,-1, L"Shader" ); | ||
769 | gui.Visible_Shader->setToolTipText ( L"Show or not show the Shader Nodes. \nPress F4 on your Keyboard" ); | ||
770 | gui.Visible_Fog = env->addCheckBox ( true, rect<s32>( dim.Width - 170, 150, dim.Width - 110, 166 ), gui.Window,-1, L"Fog" ); | ||
771 | gui.Visible_Fog->setToolTipText ( L"Show or not show the Fog Nodes. \nPress F5 on your Keyboard" ); | ||
772 | gui.Visible_Unresolved = env->addCheckBox ( true, rect<s32>( dim.Width - 110, 150, dim.Width - 10, 166 ), gui.Window,-1, L"Unresolved" ); | ||
773 | gui.Visible_Unresolved->setToolTipText ( L"Show the or not show the Nodes the Engine can't handle. \nPress F6 on your Keyboard" ); | ||
774 | gui.Visible_Skydome = env->addCheckBox ( true, rect<s32>( dim.Width - 110, 180, dim.Width - 10, 196 ), gui.Window,-1, L"Skydome" ); | ||
775 | gui.Visible_Skydome->setToolTipText ( L"Show the or not show the Skydome." ); | ||
776 | |||
777 | //Respawn = env->addButton ( rect<s32>( dim.Width - 260, 90, dim.Width - 10, 106 ), 0,-1, L"Respawn" ); | ||
778 | |||
779 | env->addStaticText ( L"Archives:", rect<s32>( 5, dim.Height - 530, dim.Width - 600,dim.Height - 514 ),false, false, gui.Window, -1, false ); | ||
780 | |||
781 | gui.ArchiveAdd = env->addButton ( rect<s32>( dim.Width - 725, dim.Height - 530, dim.Width - 665, dim.Height - 514 ), gui.Window,-1, L"add" ); | ||
782 | gui.ArchiveAdd->setToolTipText ( L"Add an archive, usually packed zip-archives (*.pk3) to the Filesystem" ); | ||
783 | gui.ArchiveRemove = env->addButton ( rect<s32>( dim.Width - 660, dim.Height - 530, dim.Width - 600, dim.Height - 514 ), gui.Window,-1, L"del" ); | ||
784 | gui.ArchiveRemove->setToolTipText ( L"Remove the selected archive from the FileSystem." ); | ||
785 | gui.ArchiveUp = env->addButton ( rect<s32>( dim.Width - 575, dim.Height - 530, dim.Width - 515, dim.Height - 514 ), gui.Window,-1, L"up" ); | ||
786 | gui.ArchiveUp->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive up" ); | ||
787 | gui.ArchiveDown = env->addButton ( rect<s32>( dim.Width - 510, dim.Height - 530, dim.Width - 440, dim.Height - 514 ), gui.Window,-1, L"down" ); | ||
788 | gui.ArchiveDown->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive down" ); | ||
789 | |||
790 | |||
791 | gui.ArchiveList = env->addTable ( rect<s32>( 5,dim.Height - 510, dim.Width - 450,dim.Height - 410 ), gui.Window ); | ||
792 | gui.ArchiveList->addColumn ( L"Type", 0 ); | ||
793 | gui.ArchiveList->addColumn ( L"Real File Path", 1 ); | ||
794 | gui.ArchiveList->setColumnWidth ( 0, 60 ); | ||
795 | gui.ArchiveList->setColumnWidth ( 1, 284 ); | ||
796 | gui.ArchiveList->setToolTipText ( L"Show the attached Archives" ); | ||
797 | |||
798 | |||
799 | env->addStaticText ( L"Maps:", rect<s32>( 5, dim.Height - 400, dim.Width - 450,dim.Height - 380 ),false, false, gui.Window, -1, false ); | ||
800 | gui.MapList = env->addListBox ( rect<s32>( 5,dim.Height - 380, dim.Width - 450,dim.Height - 40 ), gui.Window, -1, true ); | ||
801 | gui.MapList->setToolTipText ( L"Show the current Maps in all Archives.\n Double-Click the Map to start the level" ); | ||
802 | |||
803 | |||
804 | // create a visible Scene Tree | ||
805 | env->addStaticText ( L"Scenegraph:", rect<s32>( dim.Width - 400, dim.Height - 400, dim.Width - 5,dim.Height - 380 ),false, false, gui.Window, -1, false ); | ||
806 | gui.SceneTree = env->addTreeView( rect<s32>( dim.Width - 400, dim.Height - 380, dim.Width - 5, dim.Height - 40 ), | ||
807 | gui.Window, -1, true, true, false ); | ||
808 | gui.SceneTree->setToolTipText ( L"Show the current Scenegraph" ); | ||
809 | gui.SceneTree->getRoot()->clearChildren(); | ||
810 | addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); | ||
811 | |||
812 | |||
813 | IGUIImageList* imageList = env->createImageList( driver->getTexture ( "iconlist.png" ), | ||
814 | dimension2di( 32, 32 ), true ); | ||
815 | |||
816 | if ( imageList ) | ||
817 | { | ||
818 | gui.SceneTree->setImageList( imageList ); | ||
819 | imageList->drop (); | ||
820 | } | ||
821 | |||
822 | |||
823 | // load the engine logo | ||
824 | gui.Logo = env->addImage( driver->getTexture("irrlichtlogo3.png"), position2d<s32>(5, 16 ), true, 0 ); | ||
825 | gui.Logo->setToolTipText ( L"The great Irrlicht Engine" ); | ||
826 | |||
827 | AddArchive ( "" ); | ||
828 | } | ||
829 | |||
830 | |||
831 | /* | ||
832 | Add an Archive to the FileSystems and updates the GUI | ||
833 | */ | ||
834 | void CQuake3EventHandler::AddArchive ( const path& archiveName ) | ||
835 | { | ||
836 | IFileSystem *fs = Game->Device->getFileSystem(); | ||
837 | u32 i; | ||
838 | |||
839 | if ( archiveName.size () ) | ||
840 | { | ||
841 | bool exists = false; | ||
842 | for ( i = 0; i != fs->getFileArchiveCount(); ++i ) | ||
843 | { | ||
844 | if ( fs->getFileArchive(i)->getFileList()->getPath() == archiveName ) | ||
845 | { | ||
846 | exists = true; | ||
847 | break; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | if (!exists) | ||
852 | { | ||
853 | fs->addFileArchive(archiveName, true, false); | ||
854 | } | ||
855 | } | ||
856 | |||
857 | // store the current archives in game data | ||
858 | // show the attached Archive in proper order | ||
859 | if ( gui.ArchiveList ) | ||
860 | { | ||
861 | gui.ArchiveList->clearRows(); | ||
862 | |||
863 | for ( i = 0; i != fs->getFileArchiveCount(); ++i ) | ||
864 | { | ||
865 | IFileArchive * archive = fs->getFileArchive ( i ); | ||
866 | |||
867 | u32 index = gui.ArchiveList->addRow(i); | ||
868 | |||
869 | core::stringw typeName; | ||
870 | switch(archive->getType()) | ||
871 | { | ||
872 | case io::EFAT_ZIP: | ||
873 | typeName = "ZIP"; | ||
874 | break; | ||
875 | case io::EFAT_GZIP: | ||
876 | typeName = "gzip"; | ||
877 | break; | ||
878 | case io::EFAT_FOLDER: | ||
879 | typeName = "Mount"; | ||
880 | break; | ||
881 | case io::EFAT_PAK: | ||
882 | typeName = "PAK"; | ||
883 | break; | ||
884 | case io::EFAT_TAR: | ||
885 | typeName = "TAR"; | ||
886 | break; | ||
887 | default: | ||
888 | typeName = "archive"; | ||
889 | } | ||
890 | |||
891 | gui.ArchiveList->setCellText ( index, 0, typeName ); | ||
892 | gui.ArchiveList->setCellText ( index, 1, archive->getFileList()->getPath() ); | ||
893 | } | ||
894 | } | ||
895 | |||
896 | |||
897 | // browse the archives for maps | ||
898 | if ( gui.MapList ) | ||
899 | { | ||
900 | gui.MapList->clear(); | ||
901 | |||
902 | IGUISpriteBank *bank = Game->Device->getGUIEnvironment()->getSpriteBank("sprite_q3map"); | ||
903 | if ( 0 == bank ) | ||
904 | bank = Game->Device->getGUIEnvironment()->addEmptySpriteBank("sprite_q3map"); | ||
905 | |||
906 | SGUISprite sprite; | ||
907 | SGUISpriteFrame frame; | ||
908 | core::rect<s32> r; | ||
909 | |||
910 | bank->getSprites().clear(); | ||
911 | bank->getPositions().clear (); | ||
912 | gui.MapList->setSpriteBank ( bank ); | ||
913 | |||
914 | u32 g = 0; | ||
915 | core::stringw s; | ||
916 | |||
917 | // browse the attached file system | ||
918 | fs->setFileListSystem ( FILESYSTEM_VIRTUAL ); | ||
919 | fs->changeWorkingDirectoryTo ( "/maps/" ); | ||
920 | IFileList *fileList = fs->createFileList (); | ||
921 | fs->setFileListSystem ( FILESYSTEM_NATIVE ); | ||
922 | |||
923 | for ( i=0; i< fileList->getFileCount(); ++i) | ||
924 | { | ||
925 | s = fileList->getFullFileName(i); | ||
926 | if ( s.find ( ".bsp" ) >= 0 ) | ||
927 | { | ||
928 | // get level screenshot. reformat texture to 128x128 | ||
929 | path c ( s ); | ||
930 | deletePathFromFilename ( c ); | ||
931 | cutFilenameExtension ( c, c ); | ||
932 | c = path ( "levelshots/" ) + c; | ||
933 | |||
934 | dimension2du dim ( 128, 128 ); | ||
935 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
936 | IImage* image = 0; | ||
937 | ITexture *tex = 0; | ||
938 | path filename; | ||
939 | |||
940 | filename = c + ".jpg"; | ||
941 | if ( fs->existFile ( filename ) ) | ||
942 | image = driver->createImageFromFile( filename ); | ||
943 | if ( 0 == image ) | ||
944 | { | ||
945 | filename = c + ".tga"; | ||
946 | if ( fs->existFile ( filename ) ) | ||
947 | image = driver->createImageFromFile( filename ); | ||
948 | } | ||
949 | |||
950 | if ( image ) | ||
951 | { | ||
952 | IImage* filter = driver->createImage ( video::ECF_R8G8B8, dim ); | ||
953 | image->copyToScalingBoxFilter ( filter, 0 ); | ||
954 | image->drop (); | ||
955 | image = filter; | ||
956 | } | ||
957 | |||
958 | if ( image ) | ||
959 | { | ||
960 | tex = driver->addTexture ( filename, image ); | ||
961 | image->drop (); | ||
962 | } | ||
963 | |||
964 | |||
965 | bank->setTexture ( g, tex ); | ||
966 | |||
967 | r.LowerRightCorner.X = dim.Width; | ||
968 | r.LowerRightCorner.Y = dim.Height; | ||
969 | gui.MapList->setItemHeight ( r.LowerRightCorner.Y + 4 ); | ||
970 | frame.rectNumber = bank->getPositions().size(); | ||
971 | frame.textureNumber = g; | ||
972 | |||
973 | bank->getPositions().push_back(r); | ||
974 | |||
975 | sprite.Frames.set_used ( 0 ); | ||
976 | sprite.Frames.push_back(frame); | ||
977 | sprite.frameTime = 0; | ||
978 | bank->getSprites().push_back(sprite); | ||
979 | |||
980 | gui.MapList->addItem ( s.c_str (), g ); | ||
981 | g += 1; | ||
982 | } | ||
983 | } | ||
984 | fileList->drop (); | ||
985 | |||
986 | gui.MapList->setSelected ( -1 ); | ||
987 | IGUIScrollBar * bar = (IGUIScrollBar*)gui.MapList->getElementFromId( 0 ); | ||
988 | if ( bar ) | ||
989 | bar->setPos ( 0 ); | ||
990 | |||
991 | } | ||
992 | |||
993 | } | ||
994 | |||
995 | /* | ||
996 | clears the Map in Memory | ||
997 | */ | ||
998 | void CQuake3EventHandler::dropMap () | ||
999 | { | ||
1000 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
1001 | |||
1002 | driver->removeAllHardwareBuffers (); | ||
1003 | driver->removeAllTextures (); | ||
1004 | |||
1005 | Player[0].shutdown (); | ||
1006 | |||
1007 | |||
1008 | dropElement ( ItemParent ); | ||
1009 | dropElement ( ShaderParent ); | ||
1010 | dropElement ( UnresolvedParent ); | ||
1011 | dropElement ( FogParent ); | ||
1012 | dropElement ( BulletParent ); | ||
1013 | |||
1014 | |||
1015 | Impacts.clear(); | ||
1016 | |||
1017 | if ( Meta ) | ||
1018 | { | ||
1019 | Meta = 0; | ||
1020 | } | ||
1021 | |||
1022 | dropElement ( MapParent ); | ||
1023 | dropElement ( SkyNode ); | ||
1024 | |||
1025 | // clean out meshes, because textures are invalid | ||
1026 | // TODO: better texture handling;-) | ||
1027 | IMeshCache *cache = Game->Device->getSceneManager ()->getMeshCache(); | ||
1028 | cache->clear (); | ||
1029 | Mesh = 0; | ||
1030 | } | ||
1031 | |||
1032 | /* Load new map | ||
1033 | */ | ||
1034 | void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision ) | ||
1035 | { | ||
1036 | if ( 0 == mapName.size() ) | ||
1037 | return; | ||
1038 | |||
1039 | dropMap (); | ||
1040 | |||
1041 | IFileSystem *fs = Game->Device->getFileSystem(); | ||
1042 | ISceneManager *smgr = Game->Device->getSceneManager (); | ||
1043 | |||
1044 | IReadFile* file = fs->createMemoryReadFile(&Game->loadParam, | ||
1045 | sizeof(Game->loadParam), L"levelparameter.cfg", false); | ||
1046 | |||
1047 | // load cfg file | ||
1048 | smgr->getMesh( file ); | ||
1049 | file->drop (); | ||
1050 | |||
1051 | // load the actual map | ||
1052 | Mesh = (IQ3LevelMesh*) smgr->getMesh(mapName); | ||
1053 | if ( 0 == Mesh ) | ||
1054 | return; | ||
1055 | |||
1056 | /* | ||
1057 | add the geometry mesh to the Scene ( polygon & patches ) | ||
1058 | The Geometry mesh is optimised for faster drawing | ||
1059 | */ | ||
1060 | |||
1061 | IMesh *geometry = Mesh->getMesh(E_Q3_MESH_GEOMETRY); | ||
1062 | if ( 0 == geometry || geometry->getMeshBufferCount() == 0) | ||
1063 | return; | ||
1064 | |||
1065 | Game->CurrentMapName = mapName; | ||
1066 | |||
1067 | //create a collision list | ||
1068 | Meta = 0; | ||
1069 | |||
1070 | ITriangleSelector * selector = 0; | ||
1071 | if (collision) | ||
1072 | Meta = smgr->createMetaTriangleSelector(); | ||
1073 | |||
1074 | //IMeshBuffer *b0 = geometry->getMeshBuffer(0); | ||
1075 | //s32 minimalNodes = b0 ? core::s32_max ( 2048, b0->getVertexCount() / 32 ) : 2048; | ||
1076 | s32 minimalNodes = 2048; | ||
1077 | |||
1078 | MapParent = smgr->addOctreeSceneNode(geometry, 0, -1, minimalNodes); | ||
1079 | MapParent->setName ( mapName ); | ||
1080 | if ( Meta ) | ||
1081 | { | ||
1082 | selector = smgr->createOctreeTriangleSelector( geometry,MapParent, minimalNodes); | ||
1083 | //selector = smgr->createTriangleSelector ( geometry, MapParent ); | ||
1084 | Meta->addTriangleSelector( selector); | ||
1085 | selector->drop (); | ||
1086 | } | ||
1087 | |||
1088 | // logical parent for the items | ||
1089 | ItemParent = smgr->addEmptySceneNode(); | ||
1090 | if ( ItemParent ) | ||
1091 | ItemParent->setName ( "Item Container" ); | ||
1092 | |||
1093 | ShaderParent = smgr->addEmptySceneNode(); | ||
1094 | if ( ShaderParent ) | ||
1095 | ShaderParent->setName ( "Shader Container" ); | ||
1096 | |||
1097 | UnresolvedParent = smgr->addEmptySceneNode(); | ||
1098 | if ( UnresolvedParent ) | ||
1099 | UnresolvedParent->setName ( "Unresolved Container" ); | ||
1100 | |||
1101 | FogParent = smgr->addEmptySceneNode(); | ||
1102 | if ( FogParent ) | ||
1103 | FogParent->setName ( "Fog Container" ); | ||
1104 | |||
1105 | // logical parent for the bullets | ||
1106 | BulletParent = smgr->addEmptySceneNode(); | ||
1107 | if ( BulletParent ) | ||
1108 | BulletParent->setName ( "Bullet Container" ); | ||
1109 | |||
1110 | /* | ||
1111 | now construct SceneNodes for each Shader | ||
1112 | The Objects are stored in the quake mesh E_Q3_MESH_ITEMS | ||
1113 | and the Shader ID is stored in the MaterialParameters | ||
1114 | mostly dark looking skulls and moving lava.. or green flashing tubes? | ||
1115 | */ | ||
1116 | Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_ITEMS,ShaderParent, Meta, false ); | ||
1117 | Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_FOG,FogParent, 0, false ); | ||
1118 | Q3ShaderFactory ( Game->loadParam, Game->Device, Mesh, E_Q3_MESH_UNRESOLVED,UnresolvedParent, Meta, true ); | ||
1119 | |||
1120 | /* | ||
1121 | Now construct Models from Entity List | ||
1122 | */ | ||
1123 | Q3ModelFactory ( Game->loadParam, Game->Device, Mesh, ItemParent, false ); | ||
1124 | } | ||
1125 | |||
1126 | /* | ||
1127 | Adds a SceneNode with an icon to the Scene Tree | ||
1128 | */ | ||
1129 | void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNode* nodeParent) | ||
1130 | { | ||
1131 | IGUITreeViewNode* node; | ||
1132 | wchar_t msg[128]; | ||
1133 | |||
1134 | s32 imageIndex; | ||
1135 | list<ISceneNode*>::ConstIterator it = parent->getChildren().begin(); | ||
1136 | for (; it != parent->getChildren().end(); ++it) | ||
1137 | { | ||
1138 | switch ( (*it)->getType () ) | ||
1139 | { | ||
1140 | case ESNT_Q3SHADER_SCENE_NODE: imageIndex = 0; break; | ||
1141 | case ESNT_CAMERA: imageIndex = 1; break; | ||
1142 | case ESNT_EMPTY: imageIndex = 2; break; | ||
1143 | case ESNT_MESH: imageIndex = 3; break; | ||
1144 | case ESNT_OCTREE: imageIndex = 3; break; | ||
1145 | case ESNT_ANIMATED_MESH: imageIndex = 4; break; | ||
1146 | case ESNT_SKY_BOX: imageIndex = 5; break; | ||
1147 | case ESNT_BILLBOARD: imageIndex = 6; break; | ||
1148 | case ESNT_PARTICLE_SYSTEM: imageIndex = 7; break; | ||
1149 | case ESNT_TEXT: imageIndex = 8; break; | ||
1150 | default:imageIndex = -1; break; | ||
1151 | } | ||
1152 | |||
1153 | if ( imageIndex < 0 ) | ||
1154 | { | ||
1155 | swprintf ( msg, 128, L"%hs,%hs", | ||
1156 | Game->Device->getSceneManager ()->getSceneNodeTypeName ( (*it)->getType () ), | ||
1157 | (*it)->getName() | ||
1158 | ); | ||
1159 | } | ||
1160 | else | ||
1161 | { | ||
1162 | swprintf ( msg, 128, L"%hs",(*it)->getName() ); | ||
1163 | } | ||
1164 | |||
1165 | node = nodeParent->addChildBack( msg, 0, imageIndex ); | ||
1166 | |||
1167 | // Add all Animators | ||
1168 | list<ISceneNodeAnimator*>::ConstIterator ait = (*it)->getAnimators().begin(); | ||
1169 | for (; ait != (*it)->getAnimators().end(); ++ait) | ||
1170 | { | ||
1171 | imageIndex = -1; | ||
1172 | swprintf ( msg, 128, L"%hs", | ||
1173 | Game->Device->getSceneManager ()->getAnimatorTypeName ( (*ait)->getType () ) | ||
1174 | ); | ||
1175 | |||
1176 | switch ( (*ait)->getType () ) | ||
1177 | { | ||
1178 | case ESNAT_FLY_CIRCLE: | ||
1179 | case ESNAT_FLY_STRAIGHT: | ||
1180 | case ESNAT_FOLLOW_SPLINE: | ||
1181 | case ESNAT_ROTATION: | ||
1182 | case ESNAT_TEXTURE: | ||
1183 | case ESNAT_DELETION: | ||
1184 | case ESNAT_COLLISION_RESPONSE: | ||
1185 | case ESNAT_CAMERA_FPS: | ||
1186 | case ESNAT_CAMERA_MAYA: | ||
1187 | default: | ||
1188 | break; | ||
1189 | } | ||
1190 | node->addChildBack( msg, 0, imageIndex ); | ||
1191 | } | ||
1192 | |||
1193 | addSceneTreeItem ( *it, node ); | ||
1194 | } | ||
1195 | } | ||
1196 | |||
1197 | |||
1198 | // Adds life! | ||
1199 | void CQuake3EventHandler::CreatePlayers() | ||
1200 | { | ||
1201 | Player[0].create ( Game->Device, Mesh, MapParent, Meta ); | ||
1202 | } | ||
1203 | |||
1204 | |||
1205 | // Adds a skydome to the scene | ||
1206 | void CQuake3EventHandler::AddSky( u32 dome, const c8 *texture) | ||
1207 | { | ||
1208 | ISceneManager *smgr = Game->Device->getSceneManager (); | ||
1209 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
1210 | |||
1211 | bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); | ||
1212 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); | ||
1213 | |||
1214 | if ( 0 == dome ) | ||
1215 | { | ||
1216 | // irrlicht order | ||
1217 | //static const c8*p[] = { "ft", "lf", "bk", "rt", "up", "dn" }; | ||
1218 | // quake3 order | ||
1219 | static const c8*p[] = { "ft", "rt", "bk", "lf", "up", "dn" }; | ||
1220 | |||
1221 | u32 i = 0; | ||
1222 | snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); | ||
1223 | SkyNode = smgr->addSkyBoxSceneNode( driver->getTexture ( buf ), 0, 0, 0, 0, 0 ); | ||
1224 | |||
1225 | if (SkyNode) | ||
1226 | { | ||
1227 | for ( i = 0; i < 6; ++i ) | ||
1228 | { | ||
1229 | snprintf ( buf, 64, "%s_%s.jpg", texture, p[i] ); | ||
1230 | SkyNode->getMaterial(i).setTexture ( 0, driver->getTexture ( buf ) ); | ||
1231 | } | ||
1232 | } | ||
1233 | } | ||
1234 | else | ||
1235 | if ( 1 == dome ) | ||
1236 | { | ||
1237 | snprintf ( buf, 64, "%s.jpg", texture ); | ||
1238 | SkyNode = smgr->addSkyDomeSceneNode( | ||
1239 | driver->getTexture( buf ), 32,32, | ||
1240 | 1.f, 1.f, 1000.f, 0, 11); | ||
1241 | } | ||
1242 | else | ||
1243 | if ( 2 == dome ) | ||
1244 | { | ||
1245 | snprintf ( buf, 64, "%s.jpg", texture ); | ||
1246 | SkyNode = smgr->addSkyDomeSceneNode( | ||
1247 | driver->getTexture( buf ), 16,8, | ||
1248 | 0.95f, 2.f, 1000.f, 0, 11); | ||
1249 | } | ||
1250 | |||
1251 | if (SkyNode) | ||
1252 | SkyNode->setName("Skydome"); | ||
1253 | //SkyNode->getMaterial(0).ZBuffer = video::EMDF_DEPTH_LESS_EQUAL; | ||
1254 | |||
1255 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); | ||
1256 | } | ||
1257 | |||
1258 | |||
1259 | // enable GUI elements | ||
1260 | void CQuake3EventHandler::SetGUIActive( s32 command) | ||
1261 | { | ||
1262 | bool inputState = false; | ||
1263 | |||
1264 | ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); | ||
1265 | |||
1266 | switch ( command ) | ||
1267 | { | ||
1268 | case 0: Game->guiActive = 0; inputState = !Game->guiActive; break; | ||
1269 | case 1: Game->guiActive = 1; inputState = !Game->guiActive;;break; | ||
1270 | case 2: Game->guiActive ^= 1; inputState = !Game->guiActive;break; | ||
1271 | case 3: | ||
1272 | if ( camera ) | ||
1273 | inputState = !camera->isInputReceiverEnabled(); | ||
1274 | break; | ||
1275 | } | ||
1276 | |||
1277 | if ( camera ) | ||
1278 | { | ||
1279 | camera->setInputReceiverEnabled ( inputState ); | ||
1280 | Game->Device->getCursorControl()->setVisible( !inputState ); | ||
1281 | } | ||
1282 | |||
1283 | if ( gui.Window ) | ||
1284 | { | ||
1285 | gui.Window->setVisible ( Game->guiActive != 0 ); | ||
1286 | } | ||
1287 | |||
1288 | if ( Game->guiActive && | ||
1289 | gui.SceneTree && Game->Device->getGUIEnvironment()->getFocus() != gui.SceneTree | ||
1290 | ) | ||
1291 | { | ||
1292 | gui.SceneTree->getRoot()->clearChildren(); | ||
1293 | addSceneTreeItem ( Game->Device->getSceneManager()->getRootSceneNode(), gui.SceneTree->getRoot() ); | ||
1294 | } | ||
1295 | |||
1296 | Game->Device->getGUIEnvironment()->setFocus ( Game->guiActive ? gui.Window: 0 ); | ||
1297 | } | ||
1298 | |||
1299 | |||
1300 | /* | ||
1301 | Handle game input | ||
1302 | */ | ||
1303 | bool CQuake3EventHandler::OnEvent(const SEvent& eve) | ||
1304 | { | ||
1305 | if ( eve.EventType == EET_LOG_TEXT_EVENT ) | ||
1306 | { | ||
1307 | return false; | ||
1308 | } | ||
1309 | |||
1310 | if ( Game->guiActive && eve.EventType == EET_GUI_EVENT ) | ||
1311 | { | ||
1312 | if ( eve.GUIEvent.Caller == gui.MapList && eve.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN ) | ||
1313 | { | ||
1314 | s32 selected = gui.MapList->getSelected(); | ||
1315 | if ( selected >= 0 ) | ||
1316 | { | ||
1317 | stringw loadMap = gui.MapList->getListItem ( selected ); | ||
1318 | if ( 0 == MapParent || loadMap != Game->CurrentMapName ) | ||
1319 | { | ||
1320 | printf ( "Loading map %ls\n", loadMap.c_str() ); | ||
1321 | LoadMap ( loadMap , 1 ); | ||
1322 | if ( 0 == Game->loadParam.loadSkyShader ) | ||
1323 | { | ||
1324 | AddSky ( 1, "skydome2" ); | ||
1325 | } | ||
1326 | CreatePlayers (); | ||
1327 | CreateGUI (); | ||
1328 | SetGUIActive ( 0 ); | ||
1329 | return true; | ||
1330 | } | ||
1331 | } | ||
1332 | } | ||
1333 | else | ||
1334 | if ( eve.GUIEvent.Caller == gui.ArchiveRemove && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) | ||
1335 | { | ||
1336 | Game->Device->getFileSystem()->removeFileArchive( gui.ArchiveList->getSelected() ); | ||
1337 | Game->CurrentMapName = ""; | ||
1338 | AddArchive ( "" ); | ||
1339 | } | ||
1340 | else | ||
1341 | if ( eve.GUIEvent.Caller == gui.ArchiveAdd && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) | ||
1342 | { | ||
1343 | if ( 0 == gui.ArchiveFileOpen ) | ||
1344 | { | ||
1345 | Game->Device->getFileSystem()->setFileListSystem ( FILESYSTEM_NATIVE ); | ||
1346 | gui.ArchiveFileOpen = Game->Device->getGUIEnvironment()->addFileOpenDialog ( L"Add Game Archive" , false,gui.Window ); | ||
1347 | } | ||
1348 | } | ||
1349 | else | ||
1350 | if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_SELECTED ) | ||
1351 | { | ||
1352 | AddArchive ( gui.ArchiveFileOpen->getFileName() ); | ||
1353 | gui.ArchiveFileOpen = 0; | ||
1354 | } | ||
1355 | else | ||
1356 | if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_DIRECTORY_SELECTED ) | ||
1357 | { | ||
1358 | AddArchive ( gui.ArchiveFileOpen->getDirectoryName() ); | ||
1359 | } | ||
1360 | else | ||
1361 | if ( eve.GUIEvent.Caller == gui.ArchiveFileOpen && eve.GUIEvent.EventType == gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED ) | ||
1362 | { | ||
1363 | gui.ArchiveFileOpen = 0; | ||
1364 | } | ||
1365 | else | ||
1366 | if ( ( eve.GUIEvent.Caller == gui.ArchiveUp || eve.GUIEvent.Caller == gui.ArchiveDown ) && | ||
1367 | eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) | ||
1368 | { | ||
1369 | s32 rel = eve.GUIEvent.Caller == gui.ArchiveUp ? -1 : 1; | ||
1370 | if ( Game->Device->getFileSystem()->moveFileArchive ( gui.ArchiveList->getSelected (), rel ) ) | ||
1371 | { | ||
1372 | s32 newIndex = core::s32_clamp ( gui.ArchiveList->getSelected() + rel, 0, gui.ArchiveList->getRowCount() - 1 ); | ||
1373 | AddArchive ( "" ); | ||
1374 | gui.ArchiveList->setSelected ( newIndex ); | ||
1375 | Game->CurrentMapName = ""; | ||
1376 | } | ||
1377 | } | ||
1378 | else | ||
1379 | if ( eve.GUIEvent.Caller == gui.VideoDriver && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) | ||
1380 | { | ||
1381 | Game->deviceParam.DriverType = (E_DRIVER_TYPE) gui.VideoDriver->getItemData ( gui.VideoDriver->getSelected() ); | ||
1382 | } | ||
1383 | else | ||
1384 | if ( eve.GUIEvent.Caller == gui.VideoMode && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) | ||
1385 | { | ||
1386 | u32 val = gui.VideoMode->getItemData ( gui.VideoMode->getSelected() ); | ||
1387 | Game->deviceParam.WindowSize.Width = val >> 16; | ||
1388 | Game->deviceParam.WindowSize.Height = val & 0xFFFF; | ||
1389 | } | ||
1390 | else | ||
1391 | if ( eve.GUIEvent.Caller == gui.FullScreen && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) | ||
1392 | { | ||
1393 | Game->deviceParam.Fullscreen = gui.FullScreen->isChecked(); | ||
1394 | } | ||
1395 | else | ||
1396 | if ( eve.GUIEvent.Caller == gui.Bit32 && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) | ||
1397 | { | ||
1398 | Game->deviceParam.Bits = gui.Bit32->isChecked() ? 32 : 16; | ||
1399 | } | ||
1400 | else | ||
1401 | if ( eve.GUIEvent.Caller == gui.MultiSample && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) | ||
1402 | { | ||
1403 | Game->deviceParam.AntiAlias = gui.MultiSample->getPos(); | ||
1404 | } | ||
1405 | else | ||
1406 | if ( eve.GUIEvent.Caller == gui.Tesselation && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) | ||
1407 | { | ||
1408 | Game->loadParam.patchTesselation = gui.Tesselation->getPos (); | ||
1409 | } | ||
1410 | else | ||
1411 | if ( eve.GUIEvent.Caller == gui.Gamma && eve.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED ) | ||
1412 | { | ||
1413 | Game->GammaValue = gui.Gamma->getPos () * 0.01f; | ||
1414 | Game->Device->setGammaRamp ( Game->GammaValue, Game->GammaValue, Game->GammaValue, 0.f, 0.f ); | ||
1415 | } | ||
1416 | else | ||
1417 | if ( eve.GUIEvent.Caller == gui.SetVideoMode && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) | ||
1418 | { | ||
1419 | Game->retVal = 2; | ||
1420 | Game->Device->closeDevice(); | ||
1421 | } | ||
1422 | else | ||
1423 | if ( eve.GUIEvent.Caller == gui.Window && eve.GUIEvent.EventType == gui::EGET_ELEMENT_CLOSED ) | ||
1424 | { | ||
1425 | Game->Device->closeDevice(); | ||
1426 | } | ||
1427 | else | ||
1428 | if ( eve.GUIEvent.Caller == gui.Collision && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) | ||
1429 | { | ||
1430 | // set fly through active | ||
1431 | Game->flyTroughState ^= 1; | ||
1432 | Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); | ||
1433 | |||
1434 | printf ( "collision %d\n", Game->flyTroughState == 0 ); | ||
1435 | } | ||
1436 | else | ||
1437 | if ( eve.GUIEvent.Caller == gui.Visible_Map && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) | ||
1438 | { | ||
1439 | bool v = gui.Visible_Map->isChecked(); | ||
1440 | |||
1441 | if ( MapParent ) | ||
1442 | { | ||
1443 | printf ( "static node set visible %d\n",v ); | ||
1444 | MapParent->setVisible ( v ); | ||
1445 | } | ||
1446 | } | ||
1447 | else | ||
1448 | if ( eve.GUIEvent.Caller == gui.Visible_Shader && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) | ||
1449 | { | ||
1450 | bool v = gui.Visible_Shader->isChecked(); | ||
1451 | |||
1452 | if ( ShaderParent ) | ||
1453 | { | ||
1454 | printf ( "shader node set visible %d\n",v ); | ||
1455 | ShaderParent->setVisible ( v ); | ||
1456 | } | ||
1457 | } | ||
1458 | else | ||
1459 | if ( eve.GUIEvent.Caller == gui.Visible_Skydome && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) | ||
1460 | { | ||
1461 | if ( SkyNode ) | ||
1462 | { | ||
1463 | bool v = !SkyNode->isVisible(); | ||
1464 | printf ( "skynode set visible %d\n",v ); | ||
1465 | SkyNode->setVisible ( v ); | ||
1466 | } | ||
1467 | } | ||
1468 | else | ||
1469 | if ( eve.GUIEvent.Caller == gui.Respawn && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) | ||
1470 | { | ||
1471 | Player[0].respawn (); | ||
1472 | } | ||
1473 | |||
1474 | return false; | ||
1475 | } | ||
1476 | |||
1477 | // fire | ||
1478 | if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_SPACE && | ||
1479 | eve.KeyInput.PressedDown == false) || | ||
1480 | (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) | ||
1481 | ) | ||
1482 | { | ||
1483 | ICameraSceneNode * camera = Game->Device->getSceneManager()->getActiveCamera (); | ||
1484 | if ( camera && camera->isInputReceiverEnabled () ) | ||
1485 | { | ||
1486 | useItem( Player + 0 ); | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1490 | // gui active | ||
1491 | if ((eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_F1 && | ||
1492 | eve.KeyInput.PressedDown == false) || | ||
1493 | (eve.EventType == EET_MOUSE_INPUT_EVENT && eve.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) | ||
1494 | ) | ||
1495 | { | ||
1496 | SetGUIActive ( 2 ); | ||
1497 | } | ||
1498 | |||
1499 | // check if user presses the key | ||
1500 | if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.PressedDown == false) | ||
1501 | { | ||
1502 | // Escape toggles camera Input | ||
1503 | if ( eve.KeyInput.Key == irr::KEY_ESCAPE ) | ||
1504 | { | ||
1505 | SetGUIActive ( 3 ); | ||
1506 | } | ||
1507 | else | ||
1508 | if (eve.KeyInput.Key == KEY_F11) | ||
1509 | { | ||
1510 | // screenshot are taken without gamma! | ||
1511 | IImage* image = Game->Device->getVideoDriver()->createScreenShot(); | ||
1512 | if (image) | ||
1513 | { | ||
1514 | core::vector3df pos; | ||
1515 | core::vector3df rot; | ||
1516 | ICameraSceneNode * cam = Game->Device->getSceneManager()->getActiveCamera (); | ||
1517 | if ( cam ) | ||
1518 | { | ||
1519 | pos = cam->getPosition (); | ||
1520 | rot = cam->getRotation (); | ||
1521 | } | ||
1522 | |||
1523 | static const c8 *dName[] = { "null", "software", "burning", | ||
1524 | "d3d8", "d3d9", "opengl" }; | ||
1525 | |||
1526 | snprintf(buf, 256, "%s_%ls_%.0f_%.0f_%.0f_%.0f_%.0f_%.0f.jpg", | ||
1527 | dName[Game->Device->getVideoDriver()->getDriverType()], | ||
1528 | Game->CurrentMapName.c_str(), | ||
1529 | pos.X, pos.Y, pos.Z, | ||
1530 | rot.X, rot.Y, rot.Z | ||
1531 | ); | ||
1532 | path filename ( buf ); | ||
1533 | filename.replace ( '/', '_' ); | ||
1534 | printf ( "screenshot : %s\n", filename.c_str() ); | ||
1535 | Game->Device->getVideoDriver()->writeImageToFile(image, filename, 100 ); | ||
1536 | image->drop(); | ||
1537 | } | ||
1538 | } | ||
1539 | else | ||
1540 | if (eve.KeyInput.Key == KEY_F9) | ||
1541 | { | ||
1542 | s32 value = EDS_OFF; | ||
1543 | |||
1544 | Game->debugState = ( Game->debugState + 1 ) & 3; | ||
1545 | |||
1546 | switch ( Game->debugState ) | ||
1547 | { | ||
1548 | case 1: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL; break; | ||
1549 | case 2: value = EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_SKELETON; break; | ||
1550 | } | ||
1551 | /* | ||
1552 | // set debug map data on/off | ||
1553 | debugState = debugState == EDS_OFF ? | ||
1554 | EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL: | ||
1555 | EDS_OFF; | ||
1556 | */ | ||
1557 | if ( ItemParent ) | ||
1558 | { | ||
1559 | list<ISceneNode*>::ConstIterator it = ItemParent->getChildren().begin(); | ||
1560 | for (; it != ItemParent->getChildren().end(); ++it) | ||
1561 | { | ||
1562 | (*it)->setDebugDataVisible ( value ); | ||
1563 | } | ||
1564 | } | ||
1565 | |||
1566 | if ( ShaderParent ) | ||
1567 | { | ||
1568 | list<ISceneNode*>::ConstIterator it = ShaderParent->getChildren().begin(); | ||
1569 | for (; it != ShaderParent->getChildren().end(); ++it) | ||
1570 | { | ||
1571 | (*it)->setDebugDataVisible ( value ); | ||
1572 | } | ||
1573 | } | ||
1574 | |||
1575 | if ( UnresolvedParent ) | ||
1576 | { | ||
1577 | list<ISceneNode*>::ConstIterator it = UnresolvedParent->getChildren().begin(); | ||
1578 | for (; it != UnresolvedParent->getChildren().end(); ++it) | ||
1579 | { | ||
1580 | (*it)->setDebugDataVisible ( value ); | ||
1581 | } | ||
1582 | } | ||
1583 | |||
1584 | if ( FogParent ) | ||
1585 | { | ||
1586 | list<ISceneNode*>::ConstIterator it = FogParent->getChildren().begin(); | ||
1587 | for (; it != FogParent->getChildren().end(); ++it) | ||
1588 | { | ||
1589 | (*it)->setDebugDataVisible ( value ); | ||
1590 | } | ||
1591 | } | ||
1592 | |||
1593 | if ( SkyNode ) | ||
1594 | { | ||
1595 | SkyNode->setDebugDataVisible ( value ); | ||
1596 | } | ||
1597 | |||
1598 | } | ||
1599 | else | ||
1600 | if (eve.KeyInput.Key == KEY_F8) | ||
1601 | { | ||
1602 | // set gravity on/off | ||
1603 | Game->gravityState ^= 1; | ||
1604 | Player[0].cam()->setGravity ( getGravity ( Game->gravityState ? "earth" : "none" ) ); | ||
1605 | printf ( "gravity %s\n", Game->gravityState ? "earth" : "none" ); | ||
1606 | } | ||
1607 | else | ||
1608 | if (eve.KeyInput.Key == KEY_F7) | ||
1609 | { | ||
1610 | // set fly through active | ||
1611 | Game->flyTroughState ^= 1; | ||
1612 | Player[0].cam()->setAnimateTarget ( Game->flyTroughState == 0 ); | ||
1613 | if ( gui.Collision ) | ||
1614 | gui.Collision->setChecked ( Game->flyTroughState == 0 ); | ||
1615 | |||
1616 | printf ( "collision %d\n", Game->flyTroughState == 0 ); | ||
1617 | } | ||
1618 | else | ||
1619 | if (eve.KeyInput.Key == KEY_F2) | ||
1620 | { | ||
1621 | Player[0].respawn (); | ||
1622 | } | ||
1623 | else | ||
1624 | if (eve.KeyInput.Key == KEY_F3) | ||
1625 | { | ||
1626 | if ( MapParent ) | ||
1627 | { | ||
1628 | bool v = !MapParent->isVisible (); | ||
1629 | printf ( "static node set visible %d\n",v ); | ||
1630 | MapParent->setVisible ( v ); | ||
1631 | if ( gui.Visible_Map ) | ||
1632 | gui.Visible_Map->setChecked ( v ); | ||
1633 | } | ||
1634 | } | ||
1635 | else | ||
1636 | if (eve.KeyInput.Key == KEY_F4) | ||
1637 | { | ||
1638 | if ( ShaderParent ) | ||
1639 | { | ||
1640 | bool v = !ShaderParent->isVisible (); | ||
1641 | printf ( "shader node set visible %d\n",v ); | ||
1642 | ShaderParent->setVisible ( v ); | ||
1643 | if ( gui.Visible_Shader ) | ||
1644 | gui.Visible_Shader->setChecked ( v ); | ||
1645 | } | ||
1646 | } | ||
1647 | else | ||
1648 | if (eve.KeyInput.Key == KEY_F5) | ||
1649 | { | ||
1650 | if ( FogParent ) | ||
1651 | { | ||
1652 | bool v = !FogParent->isVisible (); | ||
1653 | printf ( "fog node set visible %d\n",v ); | ||
1654 | FogParent->setVisible ( v ); | ||
1655 | if ( gui.Visible_Fog ) | ||
1656 | gui.Visible_Fog->setChecked ( v ); | ||
1657 | } | ||
1658 | |||
1659 | } | ||
1660 | else | ||
1661 | if (eve.KeyInput.Key == KEY_F6) | ||
1662 | { | ||
1663 | if ( UnresolvedParent ) | ||
1664 | { | ||
1665 | bool v = !UnresolvedParent->isVisible (); | ||
1666 | printf ( "unresolved node set visible %d\n",v ); | ||
1667 | UnresolvedParent->setVisible ( v ); | ||
1668 | if ( gui.Visible_Unresolved ) | ||
1669 | gui.Visible_Unresolved->setChecked ( v ); | ||
1670 | } | ||
1671 | } | ||
1672 | } | ||
1673 | |||
1674 | // check if user presses the key C ( for crouch) | ||
1675 | if ( eve.EventType == EET_KEY_INPUT_EVENT && eve.KeyInput.Key == KEY_KEY_C ) | ||
1676 | { | ||
1677 | // crouch | ||
1678 | ISceneNodeAnimatorCollisionResponse *anim = Player[0].cam (); | ||
1679 | if ( anim && 0 == Game->flyTroughState ) | ||
1680 | { | ||
1681 | if ( false == eve.KeyInput.PressedDown ) | ||
1682 | { | ||
1683 | // stand up | ||
1684 | anim->setEllipsoidRadius ( vector3df(30,45,30) ); | ||
1685 | anim->setEllipsoidTranslation ( vector3df(0,40,0)); | ||
1686 | |||
1687 | } | ||
1688 | else | ||
1689 | { | ||
1690 | // on your knees | ||
1691 | anim->setEllipsoidRadius ( vector3df(30,20,30) ); | ||
1692 | anim->setEllipsoidTranslation ( vector3df(0,20,0)); | ||
1693 | } | ||
1694 | return true; | ||
1695 | } | ||
1696 | } | ||
1697 | return false; | ||
1698 | } | ||
1699 | |||
1700 | |||
1701 | |||
1702 | /* | ||
1703 | useItem | ||
1704 | */ | ||
1705 | void CQuake3EventHandler::useItem( Q3Player * player) | ||
1706 | { | ||
1707 | ISceneManager* smgr = Game->Device->getSceneManager(); | ||
1708 | ICameraSceneNode* camera = smgr->getActiveCamera(); | ||
1709 | |||
1710 | if (!camera) | ||
1711 | return; | ||
1712 | |||
1713 | SParticleImpact imp; | ||
1714 | imp.when = 0; | ||
1715 | |||
1716 | // get line of camera | ||
1717 | |||
1718 | vector3df start = camera->getPosition(); | ||
1719 | |||
1720 | if ( player->WeaponNode ) | ||
1721 | { | ||
1722 | start.X += 0.f; | ||
1723 | start.Y += 0.f; | ||
1724 | start.Z += 0.f; | ||
1725 | } | ||
1726 | |||
1727 | vector3df end = (camera->getTarget() - start); | ||
1728 | end.normalize(); | ||
1729 | start += end*20.0f; | ||
1730 | |||
1731 | end = start + (end * camera->getFarValue()); | ||
1732 | |||
1733 | triangle3df triangle; | ||
1734 | line3d<f32> line(start, end); | ||
1735 | |||
1736 | // get intersection point with map | ||
1737 | scene::ISceneNode* hitNode; | ||
1738 | if (smgr->getSceneCollisionManager()->getCollisionPoint( | ||
1739 | line, Meta, end, triangle,hitNode)) | ||
1740 | { | ||
1741 | // collides with wall | ||
1742 | vector3df out = triangle.getNormal(); | ||
1743 | out.setLength(0.03f); | ||
1744 | |||
1745 | imp.when = 1; | ||
1746 | imp.outVector = out; | ||
1747 | imp.pos = end; | ||
1748 | |||
1749 | player->setAnim ( "pow" ); | ||
1750 | player->Anim[1].next += player->Anim[1].delta; | ||
1751 | } | ||
1752 | else | ||
1753 | { | ||
1754 | // doesnt collide with wall | ||
1755 | vector3df start = camera->getPosition(); | ||
1756 | if ( player->WeaponNode ) | ||
1757 | { | ||
1758 | //start.X += 10.f; | ||
1759 | //start.Y += -5.f; | ||
1760 | //start.Z += 1.f; | ||
1761 | } | ||
1762 | |||
1763 | vector3df end = (camera->getTarget() - start); | ||
1764 | end.normalize(); | ||
1765 | start += end*20.0f; | ||
1766 | end = start + (end * camera->getFarValue()); | ||
1767 | } | ||
1768 | |||
1769 | // create fire ball | ||
1770 | ISceneNode* node = 0; | ||
1771 | node = smgr->addBillboardSceneNode( BulletParent,dimension2d<f32>(10,10), start); | ||
1772 | |||
1773 | node->setMaterialFlag(EMF_LIGHTING, false); | ||
1774 | node->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture("fireball.bmp")); | ||
1775 | node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); | ||
1776 | node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR); | ||
1777 | |||
1778 | f32 length = (f32)(end - start).getLength(); | ||
1779 | const f32 speed = 5.8f; | ||
1780 | u32 time = (u32)(length / speed); | ||
1781 | |||
1782 | ISceneNodeAnimator* anim = 0; | ||
1783 | |||
1784 | // set flight line | ||
1785 | |||
1786 | anim = smgr->createFlyStraightAnimator(start, end, time); | ||
1787 | node->addAnimator(anim); | ||
1788 | anim->drop(); | ||
1789 | |||
1790 | snprintf ( buf, 64, "bullet: %s on %.1f,%1.f,%1.f", | ||
1791 | imp.when ? "hit" : "nohit", end.X, end.Y, end.Z ); | ||
1792 | node->setName ( buf ); | ||
1793 | |||
1794 | |||
1795 | anim = smgr->createDeleteAnimator(time); | ||
1796 | node->addAnimator(anim); | ||
1797 | anim->drop(); | ||
1798 | |||
1799 | if (imp.when) | ||
1800 | { | ||
1801 | // create impact note | ||
1802 | imp.when = Game->Device->getTimer()->getTime() + | ||
1803 | (time + (s32) ( ( 1.f + Noiser::get() ) * 250.f )); | ||
1804 | Impacts.push_back(imp); | ||
1805 | } | ||
1806 | |||
1807 | // play sound | ||
1808 | } | ||
1809 | |||
1810 | // rendered when bullets hit something | ||
1811 | void CQuake3EventHandler::createParticleImpacts( u32 now ) | ||
1812 | { | ||
1813 | ISceneManager* sm = Game->Device->getSceneManager(); | ||
1814 | |||
1815 | struct smokeLayer | ||
1816 | { | ||
1817 | const c8 * texture; | ||
1818 | f32 scale; | ||
1819 | f32 minparticleSize; | ||
1820 | f32 maxparticleSize; | ||
1821 | f32 boxSize; | ||
1822 | u32 minParticle; | ||
1823 | u32 maxParticle; | ||
1824 | u32 fadeout; | ||
1825 | u32 lifetime; | ||
1826 | }; | ||
1827 | |||
1828 | smokeLayer smoke[] = | ||
1829 | { | ||
1830 | { "smoke2.jpg", 0.4f, 1.5f, 18.f, 20.f, 20, 50, 2000, 10000 }, | ||
1831 | { "smoke3.jpg", 0.2f, 1.2f, 15.f, 20.f, 10, 30, 1000, 12000 } | ||
1832 | }; | ||
1833 | |||
1834 | |||
1835 | u32 i; | ||
1836 | u32 g; | ||
1837 | s32 factor = 1; | ||
1838 | for ( g = 0; g != 2; ++g ) | ||
1839 | { | ||
1840 | smoke[g].minParticle *= factor; | ||
1841 | smoke[g].maxParticle *= factor; | ||
1842 | smoke[g].lifetime *= factor; | ||
1843 | smoke[g].boxSize *= Noiser::get() * 0.5f; | ||
1844 | } | ||
1845 | |||
1846 | for ( i=0; i < Impacts.size(); ++i) | ||
1847 | { | ||
1848 | if (now < Impacts[i].when) | ||
1849 | continue; | ||
1850 | |||
1851 | // create smoke particle system | ||
1852 | IParticleSystemSceneNode* pas = 0; | ||
1853 | |||
1854 | for ( g = 0; g != 2; ++g ) | ||
1855 | { | ||
1856 | pas = sm->addParticleSystemSceneNode(false, BulletParent, -1, Impacts[i].pos); | ||
1857 | |||
1858 | snprintf ( buf, 64, "bullet impact smoke at %.1f,%.1f,%1.f", | ||
1859 | Impacts[i].pos.X,Impacts[i].pos.Y,Impacts[i].pos.Z); | ||
1860 | pas->setName ( buf ); | ||
1861 | |||
1862 | // create a flat smoke | ||
1863 | vector3df direction = Impacts[i].outVector; | ||
1864 | direction *= smoke[g].scale; | ||
1865 | IParticleEmitter* em = pas->createBoxEmitter( | ||
1866 | aabbox3d<f32>(-4.f,0.f,-4.f,20.f,smoke[g].minparticleSize,20.f), | ||
1867 | direction,smoke[g].minParticle, smoke[g].maxParticle, | ||
1868 | video::SColor(0,0,0,0),video::SColor(0,128,128,128), | ||
1869 | 250,4000, 60); | ||
1870 | |||
1871 | em->setMinStartSize (dimension2d<f32>( smoke[g].minparticleSize, smoke[g].minparticleSize)); | ||
1872 | em->setMaxStartSize (dimension2d<f32>( smoke[g].maxparticleSize, smoke[g].maxparticleSize)); | ||
1873 | |||
1874 | pas->setEmitter(em); | ||
1875 | em->drop(); | ||
1876 | |||
1877 | // particles get invisible | ||
1878 | IParticleAffector* paf = pas->createFadeOutParticleAffector( | ||
1879 | video::SColor ( 0, 0, 0, 0 ), smoke[g].fadeout); | ||
1880 | pas->addAffector(paf); | ||
1881 | paf->drop(); | ||
1882 | |||
1883 | // particle system life time | ||
1884 | ISceneNodeAnimator* anim = sm->createDeleteAnimator( smoke[g].lifetime); | ||
1885 | pas->addAnimator(anim); | ||
1886 | anim->drop(); | ||
1887 | |||
1888 | pas->setMaterialFlag(video::EMF_LIGHTING, false); | ||
1889 | pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); | ||
1890 | pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); | ||
1891 | pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture )); | ||
1892 | } | ||
1893 | |||
1894 | |||
1895 | // play impact sound | ||
1896 | #ifdef USE_IRRKLANG | ||
1897 | /* | ||
1898 | if (irrKlang) | ||
1899 | { | ||
1900 | audio::ISound* sound = | ||
1901 | irrKlang->play3D(impactSound, Impacts[i].pos, false, false, true); | ||
1902 | |||
1903 | if (sound) | ||
1904 | { | ||
1905 | // adjust max value a bit to make to sound of an impact louder | ||
1906 | sound->setMinDistance(400); | ||
1907 | sound->drop(); | ||
1908 | } | ||
1909 | } | ||
1910 | */ | ||
1911 | #endif | ||
1912 | |||
1913 | |||
1914 | // delete entry | ||
1915 | Impacts.erase(i); | ||
1916 | i--; | ||
1917 | } | ||
1918 | } | ||
1919 | |||
1920 | /* | ||
1921 | render | ||
1922 | */ | ||
1923 | void CQuake3EventHandler::Render() | ||
1924 | { | ||
1925 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
1926 | if ( 0 == driver ) | ||
1927 | return; | ||
1928 | |||
1929 | // TODO: This does not work, yet. | ||
1930 | const bool anaglyph=false; | ||
1931 | if (anaglyph) | ||
1932 | { | ||
1933 | scene::ICameraSceneNode* cameraOld = Game->Device->getSceneManager()->getActiveCamera(); | ||
1934 | driver->beginScene(true, true, SColor(0,0,0,0)); | ||
1935 | driver->getOverrideMaterial().Material.ColorMask = ECP_NONE; | ||
1936 | driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; | ||
1937 | driver->getOverrideMaterial().EnablePasses = ESNRP_SKY_BOX + | ||
1938 | ESNRP_SOLID + | ||
1939 | ESNRP_TRANSPARENT + | ||
1940 | ESNRP_TRANSPARENT_EFFECT + | ||
1941 | ESNRP_SHADOW; | ||
1942 | Game->Device->getSceneManager()->drawAll(); | ||
1943 | driver->clearZBuffer(); | ||
1944 | |||
1945 | const vector3df oldPosition = cameraOld->getPosition(); | ||
1946 | const vector3df oldTarget = cameraOld->getTarget(); | ||
1947 | const matrix4 startMatrix = cameraOld->getAbsoluteTransformation(); | ||
1948 | const vector3df focusPoint = (oldTarget - | ||
1949 | cameraOld->getAbsolutePosition()).setLength(10000) + | ||
1950 | cameraOld->getAbsolutePosition() ; | ||
1951 | |||
1952 | scene::ICameraSceneNode* camera = cameraOld;//Game->Device->getSceneManager()->addCameraSceneNode(); | ||
1953 | |||
1954 | //Left eye... | ||
1955 | vector3df pos; | ||
1956 | matrix4 move; | ||
1957 | |||
1958 | move.setTranslation( vector3df(-1.5f,0.0f,0.0f) ); | ||
1959 | pos=(startMatrix*move).getTranslation(); | ||
1960 | |||
1961 | driver->getOverrideMaterial().Material.ColorMask = ECP_RED; | ||
1962 | driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; | ||
1963 | driver->getOverrideMaterial().EnablePasses = | ||
1964 | ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| | ||
1965 | ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; | ||
1966 | |||
1967 | camera->setPosition(pos); | ||
1968 | camera->setTarget(focusPoint); | ||
1969 | |||
1970 | Game->Device->getSceneManager()->drawAll(); | ||
1971 | driver->clearZBuffer(); | ||
1972 | |||
1973 | //Right eye... | ||
1974 | move.setTranslation( vector3df(1.5f,0.0f,0.0f) ); | ||
1975 | pos=(startMatrix*move).getTranslation(); | ||
1976 | |||
1977 | driver->getOverrideMaterial().Material.ColorMask = ECP_GREEN + ECP_BLUE; | ||
1978 | driver->getOverrideMaterial().EnableFlags = EMF_COLOR_MASK; | ||
1979 | driver->getOverrideMaterial().EnablePasses = | ||
1980 | ESNRP_SKY_BOX|ESNRP_SOLID|ESNRP_TRANSPARENT| | ||
1981 | ESNRP_TRANSPARENT_EFFECT|ESNRP_SHADOW; | ||
1982 | |||
1983 | camera->setPosition(pos); | ||
1984 | camera->setTarget(focusPoint); | ||
1985 | |||
1986 | Game->Device->getSceneManager()->drawAll(); | ||
1987 | |||
1988 | driver->getOverrideMaterial().Material.ColorMask=ECP_ALL; | ||
1989 | driver->getOverrideMaterial().EnableFlags=0; | ||
1990 | driver->getOverrideMaterial().EnablePasses=0; | ||
1991 | |||
1992 | if (camera != cameraOld) | ||
1993 | { | ||
1994 | Game->Device->getSceneManager()->setActiveCamera(cameraOld); | ||
1995 | camera->remove(); | ||
1996 | } | ||
1997 | else | ||
1998 | { | ||
1999 | camera->setPosition(oldPosition); | ||
2000 | camera->setTarget(oldTarget); | ||
2001 | } | ||
2002 | } | ||
2003 | else | ||
2004 | { | ||
2005 | driver->beginScene(true, true, SColor(0,0,0,0)); | ||
2006 | Game->Device->getSceneManager()->drawAll(); | ||
2007 | } | ||
2008 | Game->Device->getGUIEnvironment()->drawAll(); | ||
2009 | driver->endScene(); | ||
2010 | } | ||
2011 | |||
2012 | /* | ||
2013 | update the generic scene node | ||
2014 | */ | ||
2015 | void CQuake3EventHandler::Animate() | ||
2016 | { | ||
2017 | u32 now = Game->Device->getTimer()->getTime(); | ||
2018 | |||
2019 | Q3Player * player = Player + 0; | ||
2020 | |||
2021 | checkTimeFire ( player->Anim, 4, now ); | ||
2022 | |||
2023 | // Query Scene Manager attributes | ||
2024 | if ( player->Anim[0].flags & FIRED ) | ||
2025 | { | ||
2026 | ISceneManager *smgr = Game->Device->getSceneManager (); | ||
2027 | wchar_t msg[128]; | ||
2028 | IVideoDriver * driver = Game->Device->getVideoDriver(); | ||
2029 | |||
2030 | IAttributes * attr = smgr->getParameters(); | ||
2031 | #ifdef _IRR_SCENEMANAGER_DEBUG | ||
2032 | swprintf ( msg, 128, | ||
2033 | L"Q3 %s [%ls], FPS:%03d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)", | ||
2034 | Game->CurrentMapName.c_str(), | ||
2035 | driver->getName(), | ||
2036 | driver->getFPS (), | ||
2037 | (f32) driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ), | ||
2038 | attr->getAttributeAsInt ( "culled" ), | ||
2039 | attr->getAttributeAsInt ( "calls" ), | ||
2040 | attr->getAttributeAsInt ( "drawn_solid" ), | ||
2041 | attr->getAttributeAsInt ( "drawn_transparent" ), | ||
2042 | attr->getAttributeAsInt ( "drawn_transparent_effect" ) | ||
2043 | ); | ||
2044 | #else | ||
2045 | swprintf ( msg, 128, | ||
2046 | L"Q3 %s [%ls], FPS:%03d Tri:%.03fm", | ||
2047 | Game->CurrentMapName.c_str(), | ||
2048 | driver->getName(), | ||
2049 | driver->getFPS (), | ||
2050 | (f32) driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ) | ||
2051 | ); | ||
2052 | #endif | ||
2053 | Game->Device->setWindowCaption( msg ); | ||
2054 | |||
2055 | swprintf ( msg, 128, | ||
2056 | L"%03d fps, F1 GUI on/off, F2 respawn, F3-F6 toggle Nodes, F7 Collision on/off" | ||
2057 | L", F8 Gravity on/off, Right Mouse Toggle GUI", | ||
2058 | Game->Device->getVideoDriver()->getFPS () | ||
2059 | ); | ||
2060 | if ( gui.StatusLine ) | ||
2061 | gui.StatusLine->setText ( msg ); | ||
2062 | player->Anim[0].flags &= ~FIRED; | ||
2063 | } | ||
2064 | |||
2065 | // idle.. | ||
2066 | if ( player->Anim[1].flags & FIRED ) | ||
2067 | { | ||
2068 | if ( strcmp ( player->animation, "idle" ) ) | ||
2069 | player->setAnim ( "idle" ); | ||
2070 | |||
2071 | player->Anim[1].flags &= ~FIRED; | ||
2072 | } | ||
2073 | |||
2074 | createParticleImpacts ( now ); | ||
2075 | |||
2076 | } | ||
2077 | |||
2078 | |||
2079 | /* The main game states | ||
2080 | */ | ||
2081 | void runGame ( GameData *game ) | ||
2082 | { | ||
2083 | if ( game->retVal >= 3 ) | ||
2084 | return; | ||
2085 | |||
2086 | game->Device = (*game->createExDevice) ( game->deviceParam ); | ||
2087 | if ( 0 == game->Device) | ||
2088 | { | ||
2089 | // could not create selected driver. | ||
2090 | game->retVal = 0; | ||
2091 | return; | ||
2092 | } | ||
2093 | |||
2094 | // create an event receiver based on current game data | ||
2095 | CQuake3EventHandler *eventHandler = new CQuake3EventHandler( game ); | ||
2096 | |||
2097 | // load stored config | ||
2098 | game->load ( "explorer.cfg" ); | ||
2099 | |||
2100 | // add our media directory and archive to the file system | ||
2101 | for ( u32 i = 0; i < game->CurrentArchiveList.size(); ++i ) | ||
2102 | { | ||
2103 | eventHandler->AddArchive ( game->CurrentArchiveList[i] ); | ||
2104 | } | ||
2105 | |||
2106 | // Load a Map or startup to the GUI | ||
2107 | if ( game->CurrentMapName.size () ) | ||
2108 | { | ||
2109 | eventHandler->LoadMap ( game->CurrentMapName, 1 ); | ||
2110 | if ( 0 == game->loadParam.loadSkyShader ) | ||
2111 | eventHandler->AddSky ( 1, "skydome2" ); | ||
2112 | eventHandler->CreatePlayers (); | ||
2113 | eventHandler->CreateGUI (); | ||
2114 | eventHandler->SetGUIActive ( 0 ); | ||
2115 | |||
2116 | // set player to last position on restart | ||
2117 | if ( game->retVal == 2 ) | ||
2118 | { | ||
2119 | eventHandler->GetPlayer( 0 )->setpos ( game->PlayerPosition, game->PlayerRotation ); | ||
2120 | } | ||
2121 | } | ||
2122 | else | ||
2123 | { | ||
2124 | // start up empty | ||
2125 | eventHandler->AddSky ( 1, "skydome2" ); | ||
2126 | eventHandler->CreatePlayers (); | ||
2127 | eventHandler->CreateGUI (); | ||
2128 | eventHandler->SetGUIActive ( 1 ); | ||
2129 | background_music ( "IrrlichtTheme.ogg" ); | ||
2130 | } | ||
2131 | |||
2132 | |||
2133 | game->retVal = 3; | ||
2134 | while( game->Device->run() ) | ||
2135 | { | ||
2136 | eventHandler->Animate (); | ||
2137 | eventHandler->Render (); | ||
2138 | //if ( !game->Device->isWindowActive() ) | ||
2139 | game->Device->yield(); | ||
2140 | } | ||
2141 | |||
2142 | game->Device->setGammaRamp ( 1.f, 1.f, 1.f, 0.f, 0.f ); | ||
2143 | delete eventHandler; | ||
2144 | } | ||
2145 | |||
2146 | #if defined (_IRR_WINDOWS_) && 0 | ||
2147 | #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") | ||
2148 | #endif | ||
2149 | |||
2150 | |||
2151 | /* The main routine, doing all setup | ||
2152 | */ | ||
2153 | int IRRCALLCONV main(int argc, char* argv[]) | ||
2154 | { | ||
2155 | path prgname(argv[0]); | ||
2156 | GameData game ( deletePathFromPath ( prgname, 1 ) ); | ||
2157 | |||
2158 | // dynamically load irrlicht | ||
2159 | const c8 * dllName = argc > 1 ? argv[1] : "irrlicht.dll"; | ||
2160 | game.createExDevice = load_createDeviceEx ( dllName ); | ||
2161 | if ( 0 == game.createExDevice ) | ||
2162 | { | ||
2163 | game.retVal = 3; | ||
2164 | printf ( "Could not load %s.\n", dllName ); | ||
2165 | return game.retVal; // could not load dll | ||
2166 | } | ||
2167 | |||
2168 | // start without asking for driver | ||
2169 | game.retVal = 1; | ||
2170 | do | ||
2171 | { | ||
2172 | // if driver could not created, ask for another driver | ||
2173 | if ( game.retVal == 0 ) | ||
2174 | { | ||
2175 | game.setDefault (); | ||
2176 | // ask user for driver | ||
2177 | game.deviceParam.DriverType=driverChoiceConsole(); | ||
2178 | if (game.deviceParam.DriverType==video::EDT_COUNT) | ||
2179 | game.retVal = 3; | ||
2180 | } | ||
2181 | runGame ( &game ); | ||
2182 | } while ( game.retVal < 3 ); | ||
2183 | |||
2184 | return game.retVal; | ||
2185 | } | ||
2186 | |||
2187 | /* | ||
2188 | **/ | ||