Merge branch '164-crash-on-patching-and-possibly-right-after-login' into main/gingo...
[ryzomcore.git] / ryzom / client / src / main_loop_debug.cpp
blobb4edaf5e9e5b768af0ce8207a0ed6a764f5efe4c
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2017 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
21 #include "main_loop_debug.h"
23 #include <nel/3d/u_text_context.h>
24 #include <nel/gui/lua_ihm.h>
26 #include "global.h"
27 #include "client_cfg.h"
28 #include "user_entity.h"
29 #include "debug_client.h"
30 #include "entities.h"
31 #include "motion/user_controls.h"
32 #include "pacs_client.h"
33 #include "sound_manager.h"
34 #include "view.h"
35 #include "prim_file.h"
36 #include "weather.h"
37 #include "light_cycle_manager.h"
38 #include "net_manager.h"
39 #include "ping.h"
40 #include "world_database_manager.h"
41 #include "continent_manager.h"
42 #include "client_sheets/weather_function_params_sheet.h"
43 #include "weather_manager_client.h"
44 #include "fog_map.h"
45 #include "misc.h"
46 #include "interface_v3/interface_manager.h"
47 #include "actions_client.h"
48 #include "user_agent.h"
51 using namespace NLMISC;
52 using namespace NL3D;
53 using namespace NLGUI;
55 // ********************************************************************
56 // ********************************************************************
57 // ********************************************************************
58 // ********************************************************************
59 // ********************************************************************
61 extern std::set<std::string> LodCharactersNotFound;
62 extern uint32 NbDatabaseChanges;
63 extern CFogState MainFogState;
64 extern CPing Ping;
65 extern bool Filter3D[RYZOM_MAX_FILTER_3D];
67 //namespace /* anonymous */ {
69 NLMISC::CValueSmoother smoothFPS;
70 NLMISC::CValueSmoother moreSmoothFPS(64);
72 //} /* anonymous namespace */
74 //---------------------------------------------------
75 // displayDebug :
76 // Display some debug infos.
77 //---------------------------------------------------
78 void displayDebug()
80 float lineStep = ClientCfg.DebugLineStep;
81 float line;
83 // Initialize Pen //
84 //----------------//
85 // Create a shadow when displaying a text.
86 TextContext->setShaded(true);
87 TextContext->setShadeOutline(false);
88 // Set the font size.
89 TextContext->setFontSize(ClientCfg.DebugFontSize);
90 // Set the text color
91 TextContext->setColor(ClientCfg.DebugFontColor);
93 // TOP LEFT //
94 //----------//
95 TextContext->setHotSpot(UTextContext::TopLeft);
96 line = 0.9f;
97 // FPS and Ms per frame
99 // smooth across frames.
100 double deltaTime = smoothFPS.getSmoothValue ();
101 // FPS and Ms per frame
102 if(deltaTime != 0.f)
103 TextContext->printfAt(0.f, line,"%.1f fps", 1.f/deltaTime);
104 else
105 TextContext->printfAt(0.f, line,"%.1f fps", 0.f);
106 TextContext->printfAt(0.1f, line, "%d ms", (uint)(deltaTime*1000));
108 line -= lineStep;
109 line -= lineStep;
111 // USER
112 // Front
113 TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) front", atan2(UserEntity->front().y, UserEntity->front().x), UserEntity->front().x, UserEntity->front().y, UserEntity->front().z);
114 line -= lineStep;
115 // Dir
116 TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) dir", atan2(UserEntity->dir().y, UserEntity->dir().x), UserEntity->dir().x, UserEntity->dir().y, UserEntity->dir().z);
117 line -= lineStep;
118 // NB Stage
119 TextContext->printfAt(0.0f, line, " NB Stage: %d", UserEntity->nbStage());
120 line -= lineStep;
121 // NB Animation FXs still remaining in the remove list.
122 TextContext->printfAt(0.0f, line, " NB FXs to remove: %d", UserEntity->nbAnimFXToRemove());
123 line -= lineStep;
124 // Mode.
125 TextContext->printfAt(0.0f, line, " Mode: %d (%s)", (sint)UserEntity->mode(), MBEHAV::modeToString(UserEntity->mode()).c_str());
126 line -= lineStep;
127 // Behaviour.
128 TextContext->printfAt(0.0f, line, " Behaviour: %d (%s)", (sint)UserEntity->behaviour(), MBEHAV::behaviourToString(UserEntity->behaviour()).c_str());
129 line -= lineStep;
130 // Display the target mount.
131 TextContext->printfAt(0.0f, line, " Mount: %d", UserEntity->mount());
132 line -= lineStep;
133 // Display the target rider.
134 TextContext->printfAt(0.0f, line, " Rider: %d", UserEntity->rider());
135 line -= lineStep;
136 // Display the current animation name.
137 TextContext->printfAt(0.0f, line, " Current Animation Name: %s", UserEntity->currentAnimationName().c_str());
138 line -= lineStep;
139 // Display the current move animation set name.
140 TextContext->printfAt(0.0f, line, " Current AnimationSet Name (MOVE): %s", UserEntity->currentAnimationSetName(MOVE).c_str());
141 line -= lineStep;
142 // Display Missing Animations
143 if(::CAnimation::MissingAnim.empty() == false)
145 TextContext->printfAt(0.0f, line, " '%u' Missing Animations, 1st: '%s'", ::CAnimation::MissingAnim.size(), (*(::CAnimation::MissingAnim.begin())).c_str());
146 line -= lineStep;
148 // Display Missing LoD
149 if(LodCharactersNotFound.empty() == false)
151 TextContext->printfAt(0.0f, line, " '%u' Missing LoD, 1st: '%s'", LodCharactersNotFound.size(), (*(LodCharactersNotFound.begin())).c_str());
152 line -= lineStep;
155 // Watched Entity
156 line -= lineStep;
157 // Now Displaying the selection.
158 TextContext->printfAt(0.0f, line, "--*** Watched entity ***--");
159 line -= lineStep;
160 // Display information about the debug entity slot.
161 if(WatchedEntitySlot != CLFECOMMON::INVALID_SLOT)
163 // Get a pointer on the target.
164 CEntityCL *watchedEntity = EntitiesMngr.entity(WatchedEntitySlot);
165 if(watchedEntity)
167 // Display Debug Information about the Selection.
168 watchedEntity->displayDebug(0.0f, line, -lineStep);
170 // Distance of the target
171 CVectorD diffvector = UserEntity->pos() - watchedEntity->pos();
172 TextContext->printfAt(0.0f, line, " Distance: %10.2f (Manhattan: %.2f)", diffvector.norm(), fabs(diffvector.x) + fabs(diffvector.y) );
173 line -= lineStep;
175 // Target not allocated
176 else
178 TextContext->printfAt(0.0f, line, "Not allocated (%d)", WatchedEntitySlot);
179 line -= lineStep;
182 // No Target
183 else
185 TextContext->printfAt(0.0f, line, "None");
186 line -= lineStep;
189 /* Ca rame grave !
191 uint nMem = NLMEMORY::GetAllocatedMemory();
192 line -= lineStep;
193 TextContext->printfAt(0.0f, line, "Mem Used: %d",nMem);*/
195 // 3D Filters information:
196 #ifdef _PROFILE_ON_
197 line-= lineStep;
198 TextContext->printfAt(0.0f, line, "3D Filters:");
199 line-= lineStep;
200 TextContext->printfAt(0.0f, line, "MeshNoVP: %s", Filter3D[FilterMeshNoVP]?"Ok":"NOT RENDERED!");
201 line-= lineStep;
202 TextContext->printfAt(0.0f, line, "MeshVP: %s", Filter3D[FilterMeshVP]?"Ok":"NOT RENDERED!");
203 line-= lineStep;
204 TextContext->printfAt(0.0f, line, "FXs: %s", Filter3D[FilterFXs]?"Ok":"NOT RENDERED!");
205 line-= lineStep;
206 if (Landscape)
208 TextContext->printfAt(0.0f, line, "Landscape: %s", Filter3D[FilterLandscape]?"Ok":"NOT RENDERED!");
209 line-= lineStep;
211 else
213 TextContext->printfAt(0.0f, line, "Landscape not enabled");
215 TextContext->printfAt(0.0f, line, "Vegetable: %s", Filter3D[FilterVegetable]?"Ok":"NOT RENDERED!");
216 line-= lineStep;
217 TextContext->printfAt(0.0f, line, "Skeleton: %s", Filter3D[FilterSkeleton]?"Ok":"NOT RENDERED!");
218 line-= lineStep;
219 TextContext->printfAt(0.0f, line, "Water: %s", Filter3D[FilterWater]?"Ok":"NOT RENDERED!");
220 line-= lineStep;
221 TextContext->printfAt(0.0f, line, "Cloud: %s", Filter3D[FilterCloud]?"Ok":"NOT RENDERED!");
222 line-= lineStep;
223 TextContext->printfAt(0.0f, line, "CoarseMesh: %s", Filter3D[FilterCoarseMesh]?"Ok":"NOT RENDERED!");
224 line-= lineStep;
225 TextContext->printfAt(0.0f, line, "Sky: %s", Filter3D[FilterSky]?"Ok":"NOT RENDERED!");
226 line-= lineStep;
227 // Materials Infos
228 TextContext->printfAt(0.0f, line, "SetupedMatrix: %d", Driver->profileSetupedModelMatrix() );
229 line-= lineStep;
230 TextContext->printfAt(0.0f, line, "SetupedMaterials: %d", Driver->profileSetupedMaterials() );
231 line-= lineStep;
232 // Display camera cluster system
233 TextContext->printfAt(0.0f, line, "ClusterSystem: %p", MainCam.getClusterSystem() );
234 line-= 2 * lineStep;
235 // Lua stuffs
236 CInterfaceManager *pIM = CInterfaceManager::getInstance();
237 TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold());
238 line-= lineStep;
239 TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop());
240 line-= lineStep;
242 #endif
244 // TOP LEFT //
245 //-----------//
246 TextContext->setHotSpot(UTextContext::TopLeft);
247 line = 1.f;
248 string str = getDisplayVersion();
249 TextContext->printfAt(0.f, line, "Version %s", str.c_str());
251 // TOP MIDDLE //
252 //------------//
253 TextContext->setHotSpot(UTextContext::MiddleTop);
254 line = 1.f;
255 // Motion Mode
256 TextContext->printfAt(0.5f, line, "%s", UserControls.modeStr().c_str());
257 line -= lineStep;
259 // TOP RIGHT //
260 //-----------//
261 TextContext->setHotSpot(UTextContext::TopRight);
262 line = 1.f;
263 //// 3D Infos
264 // Video mem allocated.
265 TextContext->printfAt(1.f, line, "Video mem. : %f", Driver->profileAllocatedTextureMemory()/(1024.f*1024.f));
266 line -= lineStep;
267 // Video mem used since last swapBuffers().
268 TextContext->printfAt(1.f, line, "Video mem. since last swap buffer: %f", Driver->getUsedTextureMemory()/(1024.f*1024.f));
269 line -= lineStep;
270 // Get the last face count asked from the main scene before reduction.
271 TextContext->printfAt(1.f, line, "Nb Skin Face Asked: %f", Scene->getGroupNbFaceAsked("Skin"));
272 line -= lineStep;
273 TextContext->printfAt(1.f, line, "Nb Fx Face Asked: %f", Scene->getGroupNbFaceAsked("Fx"));
274 line -= lineStep;
275 // All Triangles In
276 CPrimitiveProfile pIn;
277 CPrimitiveProfile pOut;
278 Driver->profileRenderedPrimitives(pIn, pOut);
279 TextContext->printfAt(1.f, line, "Tri In : %d", pIn.NTriangles+2*pIn.NQuads);
280 line -= lineStep;
281 // All Triangles Out
282 TextContext->printfAt(1.f, line, "Tri Out : %d", pOut.NTriangles+2*pIn.NQuads);
283 line -= lineStep;
284 // Current Cluster
285 string strPos;
286 // Check there is a PACS Primitive before using it.
287 if(UserEntity->getPrimitive() && GR)
289 UGlobalPosition gPos;
290 UserEntity->getPrimitive()->getGlobalPosition(gPos, dynamicWI);
291 string strPos = GR->getIdentifier(gPos);
293 else
294 strPos = "No Primitive";
295 TextContext->printfAt(1.f, line, "Cluster : %s", strPos.c_str());
296 line -= lineStep;
297 //// SOUND Infos
298 line -= lineStep;
299 if(SoundMngr)
301 TextContext->printfAt(1.f, line, "Sound source instance: %u", SoundMngr->getSourcesInstanceCount());
302 line -= lineStep;
303 TextContext->printfAt(1.f, line, "Logical playing SoundSource: %u", SoundMngr->getMixer()->getPlayingSourcesCount ());
304 line -= lineStep;
305 TextContext->printfAt(1.f, line, "Audio tracks: %u/%u", SoundMngr->getMixer()->getUsedTracksCount(), SoundMngr->getMixer()->getPolyphony());
306 line -= lineStep;
307 if (SoundMngr->getMixer()->getMutedPlayingSourcesCount() > 0)
309 TextContext->printfAt(1.f, line, "Source muted: %u !", SoundMngr->getMixer()->getMutedPlayingSourcesCount());
310 line -= lineStep;
312 TextContext->printfAt(1.f, line, "Samples in memory: %g MB", SoundMngr->getLoadingSamplesSize() / (1024.0f*1024.0f));
313 line -= lineStep;
317 // BOTTOM RIGHT //
318 //--------------//
319 TextContext->setHotSpot(UTextContext::BottomRight);
320 line = 0.f;
321 //// POSITION
322 CVector postmp = View.viewPos();
323 // Pos
324 TextContext->printfAt(1.f, line, "Position : %d %d %d",(int)postmp.x,(int)postmp.y,(int)postmp.z);
325 line += lineStep;
326 // Body Heading
327 TextContext->printfAt(1.f, line, "Front : %.2f %.2f %.2f", UserEntity->front().x, UserEntity->front().y, UserEntity->front().z);
328 line += lineStep;
329 // Speed
330 TextContext->printfAt(1.f, line, "Speed : %.2f", (float) UserEntity->speed());
331 line += lineStep;
332 // Zone
333 if (!ClientCfg.Light)
335 if (Landscape)
337 TextContext->printfAt(1.f, line, "Zone: %s", Landscape->getZoneName(postmp).c_str());
338 line += lineStep;
341 // Prim File
342 string primFile = PrimFiles.getCurrentPrimitive ();
343 if (!primFile.empty ())
345 TextContext->printfAt(1.f, line, "Prim File: %s", primFile.c_str ());
346 line += lineStep;
349 //// CONNECTION
350 line += lineStep;
351 // Ryzom Day.
352 TextContext->printfAt(1.f, line, "Ryzom Day : %d", RT.getRyzomDay());
353 line += lineStep;
354 // hour in the game
355 float dayNightCycleHour = (float)RT.getRyzomTime();
356 TextContext->printfAt(1.f, line, "Ryzom Time : %2u:%02u", int(dayNightCycleHour), int((dayNightCycleHour-int(dayNightCycleHour))*60.0f));
357 line += lineStep;
358 // light hour in the game, used to display te day/night
359 TextContext->printfAt(1.f, line, "Ryzom Light Time : %2u:%02u (%s)", int(DayNightCycleHour), int((DayNightCycleHour-int(DayNightCycleHour))*60.0f), LightCycleManager.getStateString().c_str());
360 line += lineStep;
361 // Server GameCycle
362 TextContext->printfAt(1.f, line, "Server GameCycle : %u", (uint)NetMngr.getCurrentServerTick());
363 line += lineStep;
364 // Current GameCycle
365 TextContext->printfAt(1.f, line, "Current GameCycle : %u", (uint)NetMngr.getCurrentClientTick());
366 line += lineStep;
367 // Current GameCycle
368 TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick());
369 line += lineStep;
370 // Smoothed Client Date
371 TextContext->printfAt(1.f, line, "Smoothed Client Date : %u %f", SmoothedClientDate.Day, SmoothedClientDate.Hour);
372 line += lineStep;
373 // Packet Loss
374 TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f);
375 line += lineStep;
376 // Packet Loss
377 TextContext->printfAt(1.f, line, "Packets Lost : %u", NetMngr.getTotalLostPackets());
378 line += lineStep;
379 // Mean Upload
380 TextContext->printfAt(1.f, line, "Mean Upld : %.3f kbps", NetMngr.getMeanUpload());
381 line += lineStep;
382 // Mean Download
383 TextContext->printfAt(1.f, line, "Mean Dnld : %.3f kbps", NetMngr.getMeanDownload());
384 line += lineStep;
386 // Mean Download
387 TextContext->printfAt(1.f, line, "Nb in Vision : %d(%d,%d,%d)",
388 EntitiesMngr.nbEntitiesAllocated(),
389 EntitiesMngr.nbUser(),
390 EntitiesMngr.nbPlayer(),
391 EntitiesMngr.nbChar());
392 line += lineStep;
394 // Number of database changes
395 TextContext->printfAt(1.f, line, "DB Changes : %u", NbDatabaseChanges );
396 line += lineStep;
398 // Ping
399 TextContext->printfAt(1.f, line, "DB Ping : %u ms", Ping.getValue());
400 line += lineStep;
406 // Manual weather setup
408 if(ContinentMngr.cur()) // Only usable if there is a continent loaded.
410 if (!ForceTrueWeatherValue)
412 const CWeatherFunction &wf = ContinentMngr.cur()->WeatherFunction[CurrSeason];
413 float wv;
414 if (ClientCfg.ManualWeatherSetup)
416 wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ManualWeatherValue;
418 else
420 wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ::getBlendedWeather(RT.getRyzomDay(), RT.getRyzomTime(), *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction);
422 const CWeatherSetup *ws = wf.getWeatherSetup((uint) floorf(wv));
423 std::string name0 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???";
424 ws = wf.getWeatherSetup(std::min((uint) (floorf(wv) + 1), wf.getNumWeatherSetups() - 1));
425 std::string name1 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???";
426 TextContext->printfAt(1.f, line, "Weather value : %.02f : %s -> %s", ws ? wv : 0.f, name0.c_str(), name1.c_str());
427 line += lineStep;
429 else
431 TextContext->printfAt(1.f, line, "Weather value : %.02f", WeatherManager.getWeatherValue() * std::max(ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups() - 1, 0u));
432 line += lineStep;
433 TextContext->printfAt(1.f, line, "TEST WEATHER FUNCTION");
434 line += lineStep;
436 // thunder
437 TextContext->printfAt(1.f, line, "Thunder level : %.02f", WeatherManager.getThunderLevel());
438 line += lineStep;
439 // season
440 TextContext->printfAt(1.f, line, "Season : %s", EGSPD::CSeason::toString(CurrSeason).c_str());
441 line += lineStep;
445 // fog dist
446 if (ContinentMngr.cur())
448 TextContext->printfAt(1.f, line, "Continent fog min near = %.1f, max far = %.1f", ContinentMngr.cur()->FogStart, ContinentMngr.cur()->FogEnd);
449 line += lineStep;
450 CFogState tmpFog;
451 ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), tmpFog);
452 TextContext->printfAt(1.f, line, "Continent fog curr near = %.1f, curr far = %.1f", tmpFog.FogStartDist, tmpFog.FogEndDist);
453 line += lineStep;
455 const CWeatherState &ws = WeatherManager.getCurrWeatherState();
456 TextContext->printfAt(1.f, line, "Weather fog near = %.1f, far = %.1f", ws.FogNear[MainFog], ws.FogFar[MainFog]);
457 line += lineStep;
458 TextContext->printfAt(1.f, line, "Final fog near = %.1f, far = %.1f", MainFogState.FogStartDist, MainFogState.FogEndDist);
459 line += lineStep;
460 float left, right, bottom, top, znear, zfar;
461 Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar);
462 TextContext->printfAt(1.f, line, "Clip near = %.1f, far = %.1f", znear, zfar);
463 line += lineStep;
465 // Connection states
466 TextContext->printfAt(1.f, line, "State : %s", NetMngr.getConnectionStateCStr() );
467 line += lineStep;
469 // UGlobalPosition globalPos;
470 // UserEntity->getPrimitive()->getGlobalPosition(globalPos, dynamicWI);
471 // uint32 material = GR->getMaterial( globalPos );
472 // TextContext->printfAt(0.5f,0.5f,"Material : %d Gpos=(inst=%d,surf=%d,x=%.2f,y=%.2f",material, globalPos.InstanceId, globalPos.LocalPosition.Surface, globalPos.LocalPosition.Estimation.x, globalPos.LocalPosition.Estimation.y);
474 // No more shadow when displaying a text.
475 TextContext->setShaded(false);
476 TextContext->setShadeOutline(false);
477 }// displayDebug //
479 // ********************************************************************
480 // ********************************************************************
481 // ********************************************************************
482 // ********************************************************************
483 // ********************************************************************
485 //---------------------------------------------------
486 // displayDebug :
487 // Display some debug infos.
488 //---------------------------------------------------
489 void displayDebugFps()
491 float lineStep = ClientCfg.DebugLineStep;
492 float line;
494 // Initialize Pen //
495 //----------------//
496 // Create a shadow when displaying a text.
497 TextContext->setShaded(true);
498 TextContext->setShadeOutline(false);
499 // Set the font size.
500 TextContext->setFontSize(ClientCfg.DebugFontSize);
501 // Set the text color
502 TextContext->setColor(ClientCfg.DebugFontColor);
504 // TOP LEFT //
505 //----------//
506 TextContext->setHotSpot(UTextContext::TopLeft);
507 line = 0.9f;
508 // Ms per frame
510 float spf = smoothFPS.getSmoothValue ();
511 // Ms per frame
512 TextContext->printfAt(0.1f, line, "FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf);
513 line-= lineStep;
514 // More Smoothed Ms per frame
515 spf = moreSmoothFPS.getSmoothValue ();
516 TextContext->printfAt(0.1f, line, "Smoothed FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf);
517 line-= lineStep;
521 // ********************************************************************
522 // ********************************************************************
523 // ********************************************************************
524 // ********************************************************************
525 // ********************************************************************
527 static NLMISC::CRefPtr<CInterfaceElement> HighlightedDebugUI;
529 // displayDebug :
530 // Display information about ui elements that are under the mouse
531 //---------------------------------------------------
532 void displayDebugUIUnderMouse()
534 float lineStep = ClientCfg.DebugLineStep;
535 float line;
537 // Initialize Pen //
538 //----------------//
539 // Create a shadow when displaying a text.
540 TextContext->setShaded(true);
541 TextContext->setShadeOutline(false);
542 // Set the font size.
543 TextContext->setFontSize(ClientCfg.DebugFontSize);
547 // TOP LEFT //
548 //----------//
549 TextContext->setHotSpot(UTextContext::TopLeft);
550 line = 0.9f;
552 CInterfaceManager *pIM = CInterfaceManager::getInstance();
553 // for now only accessible with R2ED
554 if (ClientCfg.R2EDEnabled)
556 TextContext->setColor(CRGBA::Cyan);
557 TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+A) to cycle prev");
558 line-= lineStep;
559 TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+Q) to cycle next");
560 line-= lineStep;
561 TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+W) to inspect element");
562 line-= 2 * lineStep;
565 const std::vector<CCtrlBase *> &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer ();
566 const std::vector<CInterfaceGroup *> &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer ();
567 // If previous highlighted element is found in the list, then keep it, else reset to first element
568 if (std::find(rICL.begin(), rICL.end(), HighlightedDebugUI) == rICL.end() &&
569 std::find(rIGL.begin(), rIGL.end(), HighlightedDebugUI) == rIGL.end())
571 if (!rICL.empty())
573 HighlightedDebugUI = rICL[0];
575 else
576 if (!rIGL.empty())
578 HighlightedDebugUI = rIGL[0];
580 else
582 HighlightedDebugUI = NULL;
586 TextContext->setColor(CRGBA::Green);
587 TextContext->printfAt(0.1f, line, "Controls under cursor ");
588 line -= lineStep * 1.4f;
589 TextContext->printfAt(0.1f, line, "----------------------");
590 line -= lineStep;
591 for(uint k = 0; k < rICL.size(); ++k)
593 if (rICL[k])
595 TextContext->setColor(rICL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red);
596 TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rICL[k]->getId().c_str(), rICL[k], rICL[k]->getParent());
598 else
600 TextContext->setColor(CRGBA::Blue);
601 TextContext->printfAt(0.1f, line, "<NULL> control found !!!");
603 line-= lineStep;
606 TextContext->setColor(CRGBA::Green);
607 TextContext->printfAt(0.1f, line, "Groups under cursor ");
608 line -= lineStep * 1.4f;
609 TextContext->printfAt(0.1f, line, "----------------------");
610 line-= lineStep;
611 for(uint k = 0; k < rIGL.size(); ++k)
613 if (rIGL[k])
615 TextContext->setColor(rIGL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red);
616 TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rIGL[k]->getId().c_str(), rIGL[k], rIGL[k]->getParent());
618 else
620 TextContext->setColor(CRGBA::Blue);
621 TextContext->printfAt(0.1f, line, "<NULL> group found !!!");
623 line-= lineStep;
627 // get all element under the mouse in a single vector
628 static void getElementsUnderMouse(std::vector<CInterfaceElement *> &ielem)
630 CInterfaceManager *pIM = CInterfaceManager::getInstance();
631 const std::vector<CCtrlBase *> &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer();
632 const std::vector<CInterfaceGroup *> &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer();
633 ielem.clear();
634 ielem.insert(ielem.end(), rICL.begin(), rICL.end());
635 ielem.insert(ielem.end(), rIGL.begin(), rIGL.end());
638 class CHandlerDebugUiPrevElementUnderMouse : public IActionHandler
640 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
642 std::vector<CInterfaceElement *> ielem;
643 getElementsUnderMouse(ielem);
644 for(uint k = 0; k < ielem.size(); ++k)
646 if (HighlightedDebugUI == ielem[k])
648 HighlightedDebugUI = ielem[k == 0 ? ielem.size() - 1 : k - 1];
649 return;
654 REGISTER_ACTION_HANDLER( CHandlerDebugUiPrevElementUnderMouse, "debug_ui_prev_element_under_mouse");
656 class CHandlerDebugUiNextElementUnderMouse : public IActionHandler
658 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
660 std::vector<CInterfaceElement *> ielem;
661 getElementsUnderMouse(ielem);
662 for(uint k = 0; k < ielem.size(); ++k)
664 if (HighlightedDebugUI == ielem[k])
666 HighlightedDebugUI = ielem[(k + 1) % ielem.size()];
667 return;
672 REGISTER_ACTION_HANDLER( CHandlerDebugUiNextElementUnderMouse, "debug_ui_next_element_under_mouse");
674 class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler
676 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
678 if (HighlightedDebugUI == NULL) return;
679 CLuaState *lua = CLuaManager::getInstance().getLuaState();
680 if (!lua) return;
681 CLuaStackRestorer lsr(lua, 0);
682 CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI);
683 lua->pushGlobalTable();
684 CLuaObject env(*lua);
685 env["inspect"].callNoThrow(1, 0);
688 REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse");
690 // ********************************************************************
691 // ********************************************************************
692 // ********************************************************************
693 // ********************************************************************
694 // ********************************************************************
696 //-----------------------------------------------
697 // Macro to Display a Text
698 //-----------------------------------------------
699 #define DISP_TEXT(x, text) \
700 /* Display the text at the right place */ \
701 TextContext->printfAt(x, line, std::string(text).c_str()); \
702 /* Change the line */ \
703 line += lineStep; \
705 //---------------------------------------------------
706 // getActionKey :
707 // Return action key binding as string.
708 static std::string getActionKey(const char* name, const char* param = "")
710 std::string category;
712 CActionsManager *pAM = &Actions;
713 const CActionsManager::TActionComboMap &acmap = pAM->getActionComboMap();
715 CActionsManager::TActionComboMap::const_iterator ite = acmap.find(CAction::CName(name, param));
716 if (ite != acmap.end())
717 return ite->second.toString();
719 return CI18N::get("uiNotAssigned");
722 //---------------------------------------------------
723 // displayHelp :
724 // Display an Help.
725 //---------------------------------------------------
726 void displayHelp()
728 float line = 1.f;
729 float lineStep = -ClientCfg.HelpLineStep;
731 // Create a shadow when displaying a text.
732 TextContext->setShaded(true);
733 TextContext->setShadeOutline(false);
734 // Set the font size.
735 TextContext->setFontSize(ClientCfg.HelpFontSize);
736 // Set the text color
737 TextContext->setColor(ClientCfg.HelpFontColor);
739 line = 1.f;
740 TextContext->setHotSpot(UTextContext::TopLeft);
741 DISP_TEXT(0.0f, getActionKey("toggle_help") + " : This Menu");
742 DISP_TEXT(0.0f, getActionKey("display_infos") + " : Display Debug Infos");
743 DISP_TEXT(0.0f, getActionKey("render_mode") + " : Wire mode");
744 DISP_TEXT(0.0f, getActionKey("toggle_render") + " : Do not Render the Scene");
745 DISP_TEXT(0.0f, getActionKey("toggle_chat") + " : Toggle Display OSD interfaces");
746 // DISP_TEXT(0.0f, "SHIFT + F6 : Not used");
747 DISP_TEXT(0.0f, getActionKey("change_compass_mode") + " : Compass Mode (User/Camera)");
748 DISP_TEXT(0.0f, getActionKey("toggle_fly") + " : Camera Mode (" + getActionKey("debug", "set_pos") + " to change your position)");
749 DISP_TEXT(0.0f, getActionKey("free_mouse") + " : Free Mouse");
750 DISP_TEXT(0.0f, getActionKey("screen_shot") + " : Take a Screen Shot (TGA), " + getActionKey("screen_shot_jpg") + " for jpg, " + getActionKey("screen_shot_png") + " for png");
751 // DISP_TEXT(0.0f, "SHIFT + F11 : Test");
752 DISP_TEXT(0.0f, getActionKey("enter_modal", "group=ui:interface:quit_dialog") + " : Quit");
753 DISP_TEXT(0.0f, getActionKey("toggle_camera") + " : First/Third Person View");
754 DISP_TEXT(0.0f, getActionKey("force_camera_fp") + " : Force Camera to First Person View");
756 line = 1.f;
757 TextContext->setHotSpot(UTextContext::TopRight);
758 DISP_TEXT(1.0f, getActionKey("forward") + " : FORWARD");
759 DISP_TEXT(1.0f, getActionKey("backward") + " : BACKWARD");
760 DISP_TEXT(1.0f, getActionKey("turn_left") + " : ROTATE LEFT");
761 DISP_TEXT(1.0f, getActionKey("turn_right") + " : ROTATE RIGHT");
762 DISP_TEXT(1.0f, getActionKey("strafe_left") + " : STRAFE LEFT");
763 DISP_TEXT(1.0f, getActionKey("strafe_right") + " : STRAFE RIGHT");
764 DISP_TEXT(1.0f, getActionKey("toggle_auto_walk") + " : Auto Walk");
765 DISP_TEXT(1.0f, getActionKey("toggle_run_walk") + " : Walk/Run");
766 DISP_TEXT(1.0f, getActionKey("look_up") + " : Look Up");
767 DISP_TEXT(1.0f, getActionKey("look_down") + " : Look Down");
768 // DISP_TEXT(1.0f, getActionKey("show_hide", "inventory") + " : Inventory");
769 // DISP_TEXT(1.0f, getActionKey("show_hide", "phrase_book") + " : Spells composition interface");
770 // DISP_TEXT(1.0f, getActionKey("show_hide", "gestionsets") + " : Memorized Spells interface");
771 DISP_TEXT(1.0f, getActionKey("pacs_borders") + " : Show/Hide PACS Borders");
772 DISP_TEXT(1.0f, getActionKey("self_target") + " : Player target himself");
773 DISP_TEXT(1.0f, getActionKey("no_target") + " : Unselect target");
774 // DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout");
775 // DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File");
776 // DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting");
777 DISP_TEXT(1.0f, getActionKey("profile") + " : Profile on / off");
778 DISP_TEXT(1.0f, getActionKey("toggle_movie_recorder") + " : Movie Shooter record / stop");
779 DISP_TEXT(1.0f, getActionKey("replay_movie") + " : Movie Shooter replay");
780 DISP_TEXT(1.0f, getActionKey("save_movie") + " : Movie Shooter save");
781 #ifndef NL_USE_DEFAULT_MEMORY_MANAGER
782 DISP_TEXT(1.0f, getActionKey("memory_report") + " : Save memory stat report");
783 #endif // NL_USE_DEFAULT_MEMORY_MANAGER
784 DISP_TEXT(1.0f, getActionKey("toggle_primitive") + " : Show / hide prim file");
785 DISP_TEXT(1.0f, getActionKey("primitive_up") + " : Change prim file UP");
786 DISP_TEXT(1.0f, getActionKey("primitive_down") + " : Change prim file DOWN");
788 // No more shadow when displaying a text.
789 TextContext->setShaded(false);
790 TextContext->setShadeOutline(false);
791 }// displayHelp //
793 // ********************************************************************
794 // ********************************************************************
795 // ********************************************************************
796 // ********************************************************************
797 // ********************************************************************
799 /* end of file */