• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libtdegames
 

libtdegames

  • libtdegames
  • kgame
  • dialogs
kgamedebugdialog.cpp
1/*
2 This file is part of the TDE games library
3 Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
4 Copyright (C) 2001 Martin Heni (martin@heni-online.de)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "kgamedebugdialog.h"
22
23#include "kgamemessage.h"
24#include "kgame.h"
25#include "kplayer.h"
26#include "kgamepropertyhandler.h"
27
28#include <tdelistview.h>
29#include <tdelistbox.h>
30#include <tdelocale.h>
31#include <kdebug.h>
32#include <kpushbutton.h>
33#include <kstdguiitem.h>
34
35#include <tqlayout.h>
36#include <tqstring.h>
37#include <tqintdict.h>
38#include <tqlabel.h>
39#include <tqdatetime.h>
40
41#include <typeinfo>
42
43
44class KGameDebugDialogPrivate
45{
46public:
47 KGameDebugDialogPrivate()
48 {
49 mGame = 0;
50
51 mGamePage = 0;
52 mGameProperties = 0;
53 mGameAddress = 0;
54 mGameId = 0;
55 mGameCookie = 0;
56 mGameMaster = 0;
57 mGameAdmin = 0;
58 mGameOffering = 0;
59 mGameStatus = 0;
60 mGameRunning = 0;
61 mGameMaxPlayers = 0;
62 mGameMinPlayers = 0;
63 mGamePlayerCount = 0;
64
65 mPlayerPage = 0;
66 mPlayerList = 0;
67 mPlayerProperties = 0;
68 mPlayerAddress = 0;
69 mPlayerId = 0;
70 mPlayerName = 0;
71 mPlayerGroup = 0;
72 mPlayerUserId = 0;
73 mPlayerMyTurn = 0;
74 mPlayerAsyncInput= 0;
75 mPlayerKGameAddress = 0;
76 mPlayerVirtual = 0;
77 mPlayerActive = 0;
78 mPlayerRtti = 0;
79 mPlayerNetworkPriority = 0;
80
81 mMessagePage = 0;
82 mMessageList = 0;
83 mHideIdList = 0;
84 }
85
86 const KGame* mGame;
87
88 TQFrame* mGamePage;
89 TDEListView* mGameProperties;
90 TQListViewItem* mGameAddress;
91 TQListViewItem* mGameId;
92 TQListViewItem* mGameCookie;
93 TQListViewItem* mGameMaster;
94 TQListViewItem* mGameAdmin;
95 TQListViewItem* mGameOffering;
96 TQListViewItem* mGameStatus;
97 TQListViewItem* mGameRunning;
98 TQListViewItem* mGameMaxPlayers;
99 TQListViewItem* mGameMinPlayers;
100 TQListViewItem* mGamePlayerCount;
101
102 TQFrame* mPlayerPage;
103 TDEListBox* mPlayerList;
104 TDEListView* mPlayerProperties;
105 TQListViewItem* mPlayerAddress;
106 TQListViewItem* mPlayerId;
107 TQListViewItem* mPlayerName;
108 TQListViewItem* mPlayerGroup;
109 TQListViewItem* mPlayerUserId;
110 TQListViewItem* mPlayerMyTurn;
111 TQListViewItem* mPlayerAsyncInput;
112 TQListViewItem* mPlayerKGameAddress;
113 TQListViewItem* mPlayerVirtual;
114 TQListViewItem* mPlayerActive;
115 TQListViewItem* mPlayerRtti;
116 TQListViewItem* mPlayerNetworkPriority;
117
118 TQFrame* mMessagePage;
119 TDEListView* mMessageList;
120 TDEListBox* mHideIdList;
121};
122
123KGameDebugDialog::KGameDebugDialog(KGame* g, TQWidget* parent, bool modal) :
124 KDialogBase(Tabbed, i18n("KGame Debug Dialog"), Close, Close,
125 parent, 0, modal, true)
126{
127 d = new KGameDebugDialogPrivate;
128
129 initGamePage();
130 initPlayerPage();
131 initMessagePage();
132
133 setKGame(g);
134}
135
136KGameDebugDialog::~KGameDebugDialog()
137{
138 delete d;
139}
140
141void KGameDebugDialog::initGamePage()
142{
143 d->mGamePage = addPage(i18n("Debug &KGame"));
144 TQVBoxLayout* topLayout = new TQVBoxLayout(d->mGamePage, marginHint(), spacingHint());
145 TQHBoxLayout* layout = new TQHBoxLayout(topLayout);
146
147 TDEListView* v = new TDEListView(d->mGamePage);
148 v->addColumn(i18n("Data"));
149 v->addColumn(i18n("Value"));
150 layout->addWidget(v);
151
152 d->mGameProperties = new TDEListView(d->mGamePage);
153 d->mGameProperties->addColumn(i18n("Property"));
154 d->mGameProperties->addColumn(i18n("Value"));
155 d->mGameProperties->addColumn(i18n("Policy"));
156 layout->addWidget(d->mGameProperties);
157
158 TQPushButton* b = new TQPushButton(i18n("Update"), d->mGamePage);
159 connect(b, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotUpdateGameData()));
160 topLayout->addWidget(b);
161
162// game data
163 d->mGameAddress = new TQListViewItem(v, i18n("KGame Pointer"));
164 d->mGameId = new TQListViewItem(v, i18n("Game ID"));
165 d->mGameCookie = new TQListViewItem(v, i18n("Game Cookie"));
166 d->mGameMaster = new TQListViewItem(v, i18n("Is Master"));
167 d->mGameAdmin = new TQListViewItem(v, i18n("Is Admin"));
168 d->mGameOffering = new TQListViewItem(v, i18n("Is Offering Connections"));
169 d->mGameStatus = new TQListViewItem(v, i18n("Game Status"));
170 d->mGameRunning = new TQListViewItem(v, i18n("Game is Running"));
171 d->mGameMaxPlayers = new TQListViewItem(v, i18n("Maximal Players"));
172 d->mGameMinPlayers = new TQListViewItem(v, i18n("Minimal Players"));
173 d->mGamePlayerCount = new TQListViewItem(v, i18n("Players"));
174}
175
176void KGameDebugDialog::initPlayerPage()
177{
178 d->mPlayerPage = addPage(i18n("Debug &Players"));
179 TQVBoxLayout* topLayout = new TQVBoxLayout(d->mPlayerPage, marginHint(), spacingHint());
180 TQHBoxLayout* layout = new TQHBoxLayout(topLayout);
181
182 //TODO: connect to the KGame signals for joined/removed players!!!
183 TQVBoxLayout* listLayout = new TQVBoxLayout(layout);
184 TQLabel* listLabel = new TQLabel(i18n("Available Players"), d->mPlayerPage);
185 listLayout->addWidget(listLabel);
186 d->mPlayerList = new TDEListBox(d->mPlayerPage);
187 connect(d->mPlayerList, TQ_SIGNAL(executed(TQListBoxItem*)), this, TQ_SLOT(slotUpdatePlayerData(TQListBoxItem*)));
188 listLayout->addWidget(d->mPlayerList);
189 d->mPlayerList->setSizePolicy(TQSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding));
190
191 TDEListView* v = new TDEListView(d->mPlayerPage);
192 layout->addWidget(v);
193 v->addColumn(i18n("Data"));
194 v->addColumn(i18n("Value"));
195
196 d->mPlayerProperties = new TDEListView(d->mPlayerPage);
197 d->mPlayerProperties->addColumn(i18n("Property"));
198 d->mPlayerProperties->addColumn(i18n("Value"));
199 d->mPlayerProperties->addColumn(i18n("Policy"));
200 layout->addWidget(d->mPlayerProperties);
201
202 TQPushButton* b = new TQPushButton(i18n("Update"), d->mPlayerPage);
203 connect(b, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotUpdatePlayerList()));
204 topLayout->addWidget(b);
205
206 d->mPlayerAddress = new TQListViewItem(v, i18n("Player Pointer"));
207 d->mPlayerId = new TQListViewItem(v, i18n("Player ID"));
208 d->mPlayerName = new TQListViewItem(v, i18n("Player Name"));
209 d->mPlayerGroup = new TQListViewItem(v, i18n("Player Group"));
210 d->mPlayerUserId = new TQListViewItem(v, i18n("Player User ID"));
211 d->mPlayerMyTurn = new TQListViewItem(v, i18n("My Turn"));
212 d->mPlayerAsyncInput = new TQListViewItem(v, i18n("Async Input"));
213 d->mPlayerKGameAddress = new TQListViewItem(v, i18n("KGame Address"));
214 d->mPlayerVirtual = new TQListViewItem(v, i18n("Player is Virtual"));
215 d->mPlayerActive = new TQListViewItem(v, i18n("Player is Active"));
216 d->mPlayerRtti = new TQListViewItem(v, i18n("RTTI"));
217 d->mPlayerNetworkPriority = new TQListViewItem(v, i18n("Network Priority"));
218}
219
220void KGameDebugDialog::initMessagePage()
221{
222 d->mMessagePage = addPage(i18n("Debug &Messages"));
223 TQGridLayout* layout = new TQGridLayout(d->mMessagePage, 11, 7, marginHint(), spacingHint());
224 d->mMessageList = new TDEListView(d->mMessagePage);
225 layout->addMultiCellWidget(d->mMessageList, 0, 9, 0, 3);
226 d->mMessageList->addColumn(i18n("Time"));
227 d->mMessageList->addColumn(i18n("ID"));
228 d->mMessageList->addColumn(i18n("Receiver"));
229 d->mMessageList->addColumn(i18n("Sender"));
230 d->mMessageList->addColumn(i18n("ID - Text"));
231
232 TQPushButton* hide = new TQPushButton(i18n("&>>"), d->mMessagePage);
233 connect(hide, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotHideId()));
234 layout->addWidget(hide, 4, 4);
235
236 TQPushButton* show = new TQPushButton(i18n("&<<"), d->mMessagePage);
237 connect(show, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotShowId()));
238 layout->addWidget(show, 6, 4);
239
240 TQLabel* l = new TQLabel(i18n("Do not show IDs:"), d->mMessagePage);
241 layout->addMultiCellWidget(l, 0, 0, 5, 6);
242 d->mHideIdList = new TDEListBox(d->mMessagePage);
243 layout->addMultiCellWidget(d->mHideIdList, 1, 8, 5, 6);
244
245 TQPushButton* clear = new KPushButton(KStdGuiItem::clear(), d->mMessagePage);
246 connect(clear, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotClearMessages()));
247 layout->addMultiCellWidget(clear, 10, 10, 0, 6);
248 //TODO: "show all but..." and "show nothing but..."
249}
250
251void KGameDebugDialog::clearPlayerData()
252{
253 d->mPlayerAddress->setText(1, "");
254 d->mPlayerId->setText(1, "");
255 d->mPlayerName->setText(1, "");
256 d->mPlayerGroup->setText(1, "");
257 d->mPlayerUserId->setText(1, "");
258 d->mPlayerMyTurn->setText(1, "");
259 d->mPlayerAsyncInput->setText(1, "");
260 d->mPlayerKGameAddress->setText(1, "");
261 d->mPlayerVirtual->setText(1, "");
262 d->mPlayerActive->setText(1, "");
263 d->mPlayerRtti->setText(1, "");
264 d->mPlayerNetworkPriority->setText(1, "");
265
266 d->mPlayerProperties->clear();
267}
268
269void KGameDebugDialog::clearGameData()
270{
271 d->mGameAddress->setText(1, "");
272 d->mGameId->setText(1, "");
273 d->mGameCookie->setText(1, "");
274 d->mGameMaster->setText(1, "");
275 d->mGameAdmin->setText(1, "");
276 d->mGameOffering->setText(1, "");
277 d->mGameStatus->setText(1, "");
278 d->mGameRunning->setText(1, "");
279 d->mGameMaxPlayers->setText(1, "");
280 d->mGameMinPlayers->setText(1, "");
281
282 d->mGameProperties->clear();
283}
284
285void KGameDebugDialog::slotUpdatePlayerData()
286{
287 if (!d->mGame || d->mPlayerList->currentItem() == -1) {
288 return;
289 }
290 slotUpdatePlayerData(d->mPlayerList->item(d->mPlayerList->currentItem()));
291}
292
293void KGameDebugDialog::slotUpdatePlayerList()
294{
295 TQListBoxItem* i = d->mPlayerList->firstItem();
296 for (; i; i = d->mPlayerList->firstItem()) {
297 removePlayer(i);
298 }
299
300 TQPtrList<KPlayer> list = *d->mGame->playerList();
301 for (KPlayer* p = list.first(); p; p = list.next()) {
302 addPlayer(p);
303 }
304}
305
306void KGameDebugDialog::slotUpdateGameData()
307{
308 if (!d->mGame) {
309 d->mGameAddress->setText(1, i18n("NULL pointer"));
310 return;
311}
312
313 clearGameData();
314
315 TQString buf;
316 buf.sprintf("%p", d->mGame);
317 d->mGameAddress->setText(1, buf);
318 d->mGameId->setText(1, TQString::number(d->mGame->gameId()));
319 d->mGameCookie->setText(1, TQString::number(d->mGame->cookie()));
320 d->mGameMaster->setText(1, d->mGame->isMaster() ? i18n("True") : i18n("False"));
321 d->mGameAdmin->setText(1, d->mGame->isAdmin() ? i18n("True") : i18n("False"));
322 d->mGameOffering->setText(1, d->mGame->isOfferingConnections() ? i18n("True") : i18n("False"));
323 d->mGameStatus->setText(1, TQString::number(d->mGame->gameStatus()));
324 d->mGameRunning->setText(1, d->mGame->isRunning() ? i18n("True") : i18n("False"));
325 d->mGameMaxPlayers->setText(1, TQString::number(d->mGame->maxPlayers()));
326 d->mGameMinPlayers->setText(1, TQString::number(d->mGame->minPlayers()));
327 d->mGamePlayerCount->setText(1, TQString::number(d->mGame->playerCount()));
328
329//TODO ios
330
331 KGamePropertyHandler* handler = d->mGame->dataHandler();
332 TQIntDictIterator<KGamePropertyBase> it(handler->dict());
333 while (it.current()) {
334 TQString policy;
335 switch (it.current()->policy()) {
336 case KGamePropertyBase::PolicyClean:
337 policy = i18n("Clean");
338 break;
339 case KGamePropertyBase::PolicyDirty:
340 policy = i18n("Dirty");
341 break;
342 case KGamePropertyBase::PolicyLocal:
343 policy = i18n("Local");
344 break;
345 case KGamePropertyBase::PolicyUndefined:
346 default:
347 policy = i18n("Undefined");
348 break;
349 }
350 (void) new TQListViewItem(d->mGameProperties,
351 handler->propertyName(it.current()->id()),
352 handler->propertyValue(it.current()),
353 policy);
354// kdDebug(11001) << k_funcinfo << ": checking for all game properties: found property name " << name << endl;
355 ++it;
356 }
357}
358
359void KGameDebugDialog::slotUpdatePlayerData(TQListBoxItem* item)
360{
361 if (!item || !d->mGame) {
362 return;
363 }
364
365 KPlayer* p = d->mGame->findPlayer(item->text().toInt());
366
367 if (!p) {
368 kdError(11001) << k_funcinfo << ": cannot find player" << endl;
369 return;
370 }
371
372 clearPlayerData();
373
374 TQString buf;
375 buf.sprintf("%p", p);
376 d->mPlayerAddress->setText(1, buf);
377 d->mPlayerId->setText(1, TQString::number(p->id()));
378 d->mPlayerName->setText(1, p->name());
379 d->mPlayerGroup->setText(1, p->group());
380 d->mPlayerUserId->setText(1, TQString::number(p->userId()));
381 d->mPlayerMyTurn->setText(1, p->myTurn() ? i18n("True") : i18n("False"));
382 d->mPlayerAsyncInput->setText(1, p->asyncInput() ? i18n("True") : i18n("False"));
383 buf.sprintf("%p", p->game());
384 d->mPlayerKGameAddress->setText(1, buf);
385 d->mPlayerVirtual->setText(1, p->isVirtual() ? i18n("True") : i18n("False"));
386 d->mPlayerActive->setText(1, p->isActive() ? i18n("True") : i18n("False"));
387 d->mPlayerRtti->setText(1, TQString::number(p->rtti()));
388 d->mPlayerNetworkPriority->setText(1, TQString::number(p->networkPriority()));
389
390//TODO ios
391
392// Properties
393 KGamePropertyHandler * handler = p->dataHandler();
394 TQIntDictIterator<KGamePropertyBase> it((handler->dict()));
395 while (it.current()) {
396 TQString policy;
397 switch (it.current()->policy()) {
398 case KGamePropertyBase::PolicyClean:
399 policy = i18n("Clean");
400 break;
401 case KGamePropertyBase::PolicyDirty:
402 policy = i18n("Dirty");
403 break;
404 case KGamePropertyBase::PolicyLocal:
405 policy = i18n("Local");
406 break;
407 case KGamePropertyBase::PolicyUndefined:
408 default:
409 policy = i18n("Undefined");
410 break;
411 }
412 (void)new TQListViewItem(d->mPlayerProperties,
413 handler->propertyName(it.current()->id()),
414 handler->propertyValue(it.current()),
415 policy);
416 ++it;
417 }
418}
419
420void KGameDebugDialog::clearPages()
421{
422 clearPlayerData();
423 clearGameData();
424 d->mPlayerList->clear();
425 slotClearMessages();
426}
427
428void KGameDebugDialog::setKGame(const KGame* g)
429{
430 slotUnsetKGame();
431 d->mGame = g;
432 if (g) {
433 //TODO: connect to the KGame signals for joined/removed players!!!
434 connect(d->mGame, TQ_SIGNAL(destroyed()), this, TQ_SLOT(slotUnsetKGame()));
435// connect();
436
437 TQPtrList<KPlayer> list = *d->mGame->playerList();
438 for (KPlayer* p = list.first(); p; p = list.next()) {
439 addPlayer(p);
440 }
441
442 slotUpdateGameData();
443
444 connect(d->mGame, TQ_SIGNAL(signalMessageUpdate(int, TQ_UINT32, TQ_UINT32)), this, TQ_SLOT(slotMessageUpdate(int, TQ_UINT32, TQ_UINT32)));
445 }
446}
447
448void KGameDebugDialog::slotUnsetKGame()
449{
450 if (d->mGame) {
451 disconnect(d->mGame, 0, this, 0);
452 }
453 d->mGame = 0;
454 clearPages();
455}
456
457void KGameDebugDialog::addPlayer(KPlayer* p)
458{
459 if (!p) {
460 kdError(11001) << "trying to add NULL player" << endl;
461 return;
462 }
463
464 (void) new TQListBoxText(d->mPlayerList, TQString::number(p->id()));
465 //TODO connect to signals, like deleted/removed, ...
466}
467
468void KGameDebugDialog::removePlayer(TQListBoxItem* i)
469{
470 if (!i || !d->mGame) {
471 return;
472 }
473 KPlayer* p = d->mGame->findPlayer(i->text().toInt());
474 if (!p) {
475 return;
476 }
477 disconnect(p, 0, this, 0);
478 if (i->isSelected()) {
479 clearPlayerData();
480 }
481 delete i;
482}
483
484void KGameDebugDialog::slotMessageUpdate(int msgid, TQ_UINT32 receiver, TQ_UINT32 sender)
485{
486 if (!showId(msgid)) {
487 return;
488 }
489 TQString msgidText = KGameMessage::messageId2Text(msgid);
490 if (msgidText.isNull()) {
491 if (msgid > KGameMessage::IdUser) {
492 emit signalRequestIdName(msgid-KGameMessage::IdUser, true, msgidText);
493 } else {
494 emit signalRequestIdName(msgid, false, msgidText);
495 }
496 if (msgidText.isNull()) {
497 msgidText = i18n("Unknown");
498 }
499 }
500 (void) new TQListViewItem( d->mMessageList, TQTime::currentTime().toString(),
501 TQString::number(msgid), TQString::number(receiver),
502 TQString::number(sender), msgidText);
503}
504
505void KGameDebugDialog::slotClearMessages()
506{
507 d->mMessageList->clear();
508}
509
510void KGameDebugDialog::slotShowId()
511{
512/* TQListBoxItem* i = d->mHideIdList->firstItem();
513 for (; i; i = i->next()) {
514 if (i->selected()) {
515 d->mHideIdList->removeItem(i->);
516 }
517 }*/
518 if (!d->mHideIdList->currentItem()) {
519 return;
520 }
521 d->mHideIdList->removeItem(d->mHideIdList->currentItem());
522}
523
524void KGameDebugDialog::slotHideId()
525{
526 if (!d->mMessageList->currentItem()) {
527 return;
528 }
529 int msgid = d->mMessageList->currentItem()->text(1).toInt();
530 if (!showId(msgid)) {
531 return;
532 }
533 (void)new TQListBoxText(d->mHideIdList, TQString::number(msgid));
534}
535
536bool KGameDebugDialog::showId(int msgid)
537{
538 TQListBoxItem* i = d->mHideIdList->firstItem();
539 for (; i; i = i->next()) {
540 if (i->text().toInt() == msgid) {
541 return false;
542 }
543 }
544 return true;
545}
546
547
548#include "kgamedebugdialog.moc"
KGamePropertyHandler
A collection class for KGameProperty objects.
Definition: kgamepropertyhandler.h:73
KGamePropertyHandler::propertyValue
TQString propertyValue(KGamePropertyBase *property)
In several situations you just want to have a TQString of a KGameProperty object.
Definition: kgamepropertyhandler.cpp:354
KGamePropertyHandler::dict
TQIntDict< KGamePropertyBase > & dict() const
Reference to the internal dictionary.
Definition: kgamepropertyhandler.cpp:349
KGamePropertyHandler::propertyName
TQString propertyName(int id) const
Definition: kgamepropertyhandler.cpp:172
KGame
The main KDE game object.
Definition: kgame.h:63
KGame::findPlayer
KPlayer * findPlayer(TQ_UINT32 id) const
Returns the player object for a given player id.
Definition: kgame.cpp:386
KPlayer
Base class for a game player.
Definition: kplayer.h:70
KPlayer::isVirtual
bool isVirtual() const
Is this player a virtual player, ie is it created by mirroring a real player from another network gam...
Definition: kplayer.cpp:204
KPlayer::rtti
virtual int rtti() const
The idendification of the player.
Definition: kplayer.h:99
KPlayer::name
virtual const TQString & name() const
Definition: kplayer.cpp:192
KPlayer::myTurn
bool myTurn() const
is it my turn to go
Definition: kplayer.h:350
KPlayer::game
KGame * game() const
Query to which game the player belongs to.
Definition: kplayer.h:128
KPlayer::id
TQ_UINT32 id() const
Returns the id of the player.
Definition: kplayer.cpp:195
KPlayer::asyncInput
bool asyncInput() const
Query whether this player does asynchronous input.
Definition: kplayer.h:145
KPlayer::userId
int userId() const
Returns the user defined id of the player This value can be used arbitrary by you to have some user i...
Definition: kplayer.h:208
KPlayer::group
virtual const TQString & group() const
Query the group the player belongs to.
Definition: kplayer.cpp:186
KPlayer::isActive
bool isActive() const
Is this player an active player.
Definition: kplayer.h:174
KPlayer::networkPriority
int networkPriority() const
Returns whether this player can be replaced by a network connection player.
Definition: kplayer.cpp:213
KPlayer::dataHandler
KGamePropertyHandler * dataHandler()
Definition: kplayer.cpp:198

libtdegames

Skip menu "libtdegames"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libtdegames

Skip menu "libtdegames"
  • libtdegames
Generated for libtdegames by doxygen 1.9.4
This website is maintained by Timothy Pearson.