Difference between revisions of "KDE Games/Porting"

(Ported Bomber to KgSound)
 
(16 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
== Targets of porting ==
 
== Targets of porting ==
  
 +
* '''Graphics stack:''' QGraphicsView is currently the recommended solution. Some games still use KGameCanvas; these should be ported to QGraphicsView. In the future, we likely want to move to Qt Quick instead, but this needs proper investigation and changes in libkdegames.
 
* '''Rendering method:''' Current solutions commonly include usage of a QSvgRenderer, combined either with QGraphicsSvgItems or with (Q/K)PixmapCache. It is suggested to migrate to KGameRenderer instead. Integration with QGraphicsView is available through the KGameRenderedItem and KGameRenderedObjectItem classes. Integration with KGameCanvas is available through the KGameCanvasRenderedPixmap.
 
* '''Rendering method:''' Current solutions commonly include usage of a QSvgRenderer, combined either with QGraphicsSvgItems or with (Q/K)PixmapCache. It is suggested to migrate to KGameRenderer instead. Integration with QGraphicsView is available through the KGameRenderedItem and KGameRenderedObjectItem classes. Integration with KGameCanvas is available through the KGameCanvasRenderedPixmap.
 +
* '''Theme selection:''' When one game supports multiple themes, the KGameTheme class has commonly been used. Starting with the 4.9 release, the new KgTheme class supersedes KGameTheme.
 +
* '''Sounds:''' Some games used Phonon, some KNotify. Both libraries are bad because of their commonly high playback latencies. The new KgSound classes in libkdegames are specialized on low-latency playback of small sound samples.
 
* ''(more to come)''
 
* ''(more to come)''
  
 
== Porting status ==
 
== Porting status ==
  
The second column shows which graphics stack (e. g. QGraphicsView, KGameCanvas) is used by the application. The third column shows the rendering method.
+
This table explains the usage of relevant libraries and highlights those parts of the code which need porting. "N/A" means "not applicable", that is: This application does not use this specific type of library functionality at all (e.g. it does not play any sounds). When the "Sounds" column says "none", there is no code that plays sounds (like "N/A"), but there are sound files in the source tree, so the application should (probably?) be playing sounds.
  
If you want to take part in porting, pick an app, contact the author or the kde-games-devel mailing list to coordinate your effort, read into the [http://api.kde.org/classmapper.php?class=KGameRender KGameRenderer APIDOX] and start hacking! Please note that this porting effort is mainly about porting rendering code to KGameRenderer. Usage of outdated graphics stacks should not be changed because this might cause severe and non-trivial bugs.
+
If you want to take part in porting, pick an app, contact the author or the kde-games-devel mailing list to coordinate your effort, read into the [http://api.kde.org/4.x-api/kdegames-apidocs/libkdegames/html/annotated.html API documentation] and start hacking! Please note that the complexity of ports (roughly) increases from right to left. Porting to KgSound is largely unproblematic, while porting from KGameCanvas to QGraphicsView is a very deep cut that likely introduces subtle errors if not executed properly.
  
'''Warning:''' It is advised not to use the primaryView property of KGameRenderedObjectItem class in new ports. The existing ports using it (KDiamond and Klickety/KSame) made it clear that the primaryView property has design flaws (concerning performance), so it will probably be removed again.
+
'''Warning:''' When porting to KGameRenderer, it is advised not to use the primaryView property of KGameRenderedObjectItem class in new ports. The existing ports using it (KDiamond and Klickety/KSame) made it clear that the primaryView property has design flaws (concerning performance), so it will probably be removed again.
  
{| border="1" cellpadding="1"
+
{| class="sortable" border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"
|-
+
|- style="white-space:nowrap"
 
! Application
 
! Application
! Graphics stack
+
! Graphics stack
 
! Rendering method
 
! Rendering method
! Who does/did the port? (if applicable)
+
! Theme selection
 +
! Sounds
 
|-
 
|-
 
| bomber
 
| bomber
| style="background-color:#FFFFA0" | KGameCanvas
+
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Stefan Majewsky
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| bovo
 
| bovo
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
|
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| granatier
 
| granatier
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Mathias Kraus
+
| style="background-color:#FFFFA0" | KgTheme+custom
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| kajongg
 
| kajongg
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | libkmahjongg
 
| style="background-color:#ABFFAB" | libkmahjongg
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#FFFFA0" | custom
 
|-
 
|-
 
| kapman
 
| kapman
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
|
+
| style="background-color:#FFABAB" | KGameTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| katomic
 
| katomic
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Brian Croom
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kblackbox
 
| kblackbox
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
|
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kblocks
 
| kblocks
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
| Brian Croom
+
| style="background-color:#FFABAB" | KGameTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| kbounce
 
| kbounce
| style="background-color:#FFFFA0" | KGameCanvas
+
| style="background-color:#ABFFAB" | QGraphicsView
| style="background-color:#FFFFA0" | KPixmapCache
+
| style="background-color:#ABFFAB" | KGameRenderer
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| kbreakout
 
| kbreakout
| style="background-color:#FFFFA0" | KGameCanvas
+
| style="background-color:#ABFFAB" | QtQuick
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Brian Croom
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#FFABAB" | none
 
|-
 
|-
 
| kdiamond
 
| kdiamond
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Stefan Majewsky
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#FFABAB" | KNotify
 
|-
 
|-
 
| kfourinline
 
| kfourinline
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
| style="background-color:#FFFFA0" | PixmapCache (and classes similar to KGameRendererClient)
+
| style="background-color:#FFFFA0" | PixmapCache (client pattern)
|
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kgoldrunner
 
| kgoldrunner
 
| style="background-color:#FFFFA0" | KGameCanvas
 
| style="background-color:#FFFFA0" | KGameCanvas
 
| style="background-color:#FFFFA0" | KPixmapCache
 
| style="background-color:#FFFFA0" | KPixmapCache
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| kigo
 
| kigo
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | KPixmapCache
 
| style="background-color:#FFFFA0" | KPixmapCache
|
+
| style="background-color:#FFABAB" | KGameTheme
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| killbots
 
| killbots
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Parker Coates
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kiriki
 
| kiriki
 
| colspan="2" style="background-color:#FFFFA0" | QWidget with pre-rendered PNG
 
| colspan="2" style="background-color:#FFFFA0" | QWidget with pre-rendered PNG
| N/A
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kjumpingcube
 
| kjumpingcube
 
| style="background-color:#FFABAB" | QWidget
 
| style="background-color:#FFABAB" | QWidget
| style="background-color:#FFABAB" | simple QSvgRenderer::render()
+
| style="background-color:#FFABAB" | QSvgRenderer
|
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| klickety
 
| klickety
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| ''(native QGV/KGR app)''
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| klines
 
| klines
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | KPixmapCache
 
| style="background-color:#FFFFA0" | KPixmapCache
| Lindsay Mathieson (Blackpaw)
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kmahjongg
 
| kmahjongg
| style="background-color:#FFFFA0" | KGameCanvas
+
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | libkmahjongg
 
| style="background-color:#ABFFAB" | libkmahjongg
| Christian Krippendorf
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kmines
 
| kmines
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Brian Croom
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| knavalbattle
 
| knavalbattle
| style="background-color:#ABFFAB" | QGraphicsView
+
| style="background-color:#FFFFA0" | KGameCanvas
| style="background-color:#FFFFA0" | PixmapCache
+
| style="background-color:#FFFFA0" | QSvgRenderer, QHash
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#FFABAB" | Phonon
 
|-
 
|-
 
| knetwalk
 
| knetwalk
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Brian Croom
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| kolf
 
| kolf
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Stefan Majewsky
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#FFABAB" | Phonon
 
|-
 
|-
 
| kollision
 
| kollision
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Brian Croom
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| konquest
 
| konquest
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | KPixmapCache
 
| style="background-color:#FFFFA0" | KPixmapCache
|
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| kpat
 
| kpat
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Parker Coates
+
| style="background-color:#FFFFA0" | KgTheme+KCardTheme
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| kreversi
 
| kreversi
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | KGameRenderer
 
| style="background-color:#ABFFAB" | KGameRenderer
| Brian Croom
+
| style="background-color:#ABFFAB" | KgTheme
 +
| style="background-color:#FFABAB" | none
 
|-
 
|-
 
| kshisen
 
| kshisen
 
| style="background-color:#FFABAB" | QWidget
 
| style="background-color:#FFABAB" | QWidget
 
| style="background-color:#ABFFAB" | libkmahjongg
 
| style="background-color:#ABFFAB" | libkmahjongg
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#ABFFAB" | KgSound
 
|-
 
|-
 
| ksirk
 
| ksirk
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
| style="background-color:#FFFFA0" | QGraphicsSvgItem and KPixmapCache
+
| style="background-color:#FFFFA0" | QGraphicsSvgItem+KPixmapCache
|
+
| style="text-align:center" | N/A
|-
+
| style="background-color:#FFABAB" | Phonon
| ksnakeduel
 
| style="background-color:#FFABAB" | QWidget
 
| style="background-color:#FFFFA0" | KPixmapCache
 
|
 
 
|-
 
|-
 
| kspaceduel
 
| kspaceduel
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
|
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| ksquares
 
| ksquares
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
| N/A
+
| style="text-align:center" | N/A
| N/A
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| ksudoku
 
| ksudoku
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | KPixmapCache
 
| style="background-color:#FFFFA0" | KPixmapCache
|
+
| style="background-color:#FFABAB" | KGameTheme
 +
| style="text-align:center" | N/A
 +
|-
 +
| ktron
 +
| style="background-color:#FFABAB" | QWidget
 +
| style="background-color:#FFFFA0" | KPixmapCache
 +
| style="background-color:#FFABAB" | KGameTheme
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| ktuberling
 
| ktuberling
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
 
| style="background-color:#FFFFA0" | QGraphicsSvgItem
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#FFABAB" | Phonon
 
|-
 
|-
 
| kubrick
 
| kubrick
 
| style="background-color:#ABFFAB" | QGLWidget
 
| style="background-color:#ABFFAB" | QGLWidget
| N/A
+
| style="text-align:center" | N/A
| N/A
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| libkmahjongg
 
| libkmahjongg
| N/A
+
| style="text-align:center" | N/A
 
| style="background-color:#FFFFA0" | QPixmapCache
 
| style="background-color:#FFFFA0" | QPixmapCache
| (can now also be ported, with the new capabilities of KgTheme)
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|-
 
|-
 
| lskat
 
| lskat
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
| style="background-color:#FFFFA0" | PixmapCache (and classes similar to KGameRendererClient)
+
| style="background-color:#FFFFA0" | PixmapCache (client pattern)
|
+
| style="text-align:center" | N/A
 +
| style="background-color:#FFABAB" | none
 
|-
 
|-
 
| palapeli
 
| palapeli
 
| style="background-color:#ABFFAB" | QGraphicsView
 
| style="background-color:#ABFFAB" | QGraphicsView
| N/A
+
| style="text-align:center" | N/A
| N/A
+
| style="text-align:center" | N/A
 +
| style="text-align:center" | N/A
 
|}
 
|}

Latest revision as of 21:45, 25 April 2016

Targets of porting

  • Graphics stack: QGraphicsView is currently the recommended solution. Some games still use KGameCanvas; these should be ported to QGraphicsView. In the future, we likely want to move to Qt Quick instead, but this needs proper investigation and changes in libkdegames.
  • Rendering method: Current solutions commonly include usage of a QSvgRenderer, combined either with QGraphicsSvgItems or with (Q/K)PixmapCache. It is suggested to migrate to KGameRenderer instead. Integration with QGraphicsView is available through the KGameRenderedItem and KGameRenderedObjectItem classes. Integration with KGameCanvas is available through the KGameCanvasRenderedPixmap.
  • Theme selection: When one game supports multiple themes, the KGameTheme class has commonly been used. Starting with the 4.9 release, the new KgTheme class supersedes KGameTheme.
  • Sounds: Some games used Phonon, some KNotify. Both libraries are bad because of their commonly high playback latencies. The new KgSound classes in libkdegames are specialized on low-latency playback of small sound samples.
  • (more to come)

Porting status

This table explains the usage of relevant libraries and highlights those parts of the code which need porting. "N/A" means "not applicable", that is: This application does not use this specific type of library functionality at all (e.g. it does not play any sounds). When the "Sounds" column says "none", there is no code that plays sounds (like "N/A"), but there are sound files in the source tree, so the application should (probably?) be playing sounds.

If you want to take part in porting, pick an app, contact the author or the kde-games-devel mailing list to coordinate your effort, read into the API documentation and start hacking! Please note that the complexity of ports (roughly) increases from right to left. Porting to KgSound is largely unproblematic, while porting from KGameCanvas to QGraphicsView is a very deep cut that likely introduces subtle errors if not executed properly.

Warning: When porting to KGameRenderer, it is advised not to use the primaryView property of KGameRenderedObjectItem class in new ports. The existing ports using it (KDiamond and Klickety/KSame) made it clear that the primaryView property has design flaws (concerning performance), so it will probably be removed again.

Application Graphics stack Rendering method Theme selection Sounds
bomber QGraphicsView KGameRenderer KgTheme KgSound
bovo QGraphicsView QGraphicsSvgItem N/A N/A
granatier QGraphicsView KGameRenderer KgTheme+custom KgSound
kajongg QGraphicsView libkmahjongg N/A custom
kapman QGraphicsView QGraphicsSvgItem KGameTheme KgSound
katomic QGraphicsView KGameRenderer KgTheme N/A
kblackbox QGraphicsView QGraphicsSvgItem N/A N/A
kblocks QGraphicsView QGraphicsSvgItem KGameTheme KgSound
kbounce QGraphicsView KGameRenderer N/A KgSound
kbreakout QtQuick KGameRenderer KgTheme none
kdiamond QGraphicsView KGameRenderer KgTheme KNotify
kfourinline QGraphicsView PixmapCache (client pattern) N/A N/A
kgoldrunner KGameCanvas KPixmapCache N/A KgSound
kigo QGraphicsView KPixmapCache KGameTheme N/A
killbots QGraphicsView KGameRenderer KgTheme N/A
kiriki QWidget with pre-rendered PNG N/A N/A
kjumpingcube QWidget QSvgRenderer N/A N/A
klickety QGraphicsView KGameRenderer KgTheme KgSound
klines QGraphicsView KPixmapCache N/A N/A
kmahjongg QGraphicsView libkmahjongg N/A N/A
kmines QGraphicsView KGameRenderer KgTheme N/A
knavalbattle KGameCanvas QSvgRenderer, QHash N/A Phonon
knetwalk QGraphicsView KGameRenderer KgTheme KgSound
kolf QGraphicsView KGameRenderer KgTheme Phonon
kollision QGraphicsView KGameRenderer KgTheme KgSound
konquest QGraphicsView KPixmapCache N/A N/A
kpat QGraphicsView KGameRenderer KgTheme+KCardTheme KgSound
kreversi QGraphicsView KGameRenderer KgTheme none
kshisen QWidget libkmahjongg N/A KgSound
ksirk QGraphicsView QGraphicsSvgItem+KPixmapCache N/A Phonon
kspaceduel QGraphicsView QGraphicsSvgItem N/A N/A
ksquares QGraphicsView N/A N/A N/A
ksudoku QGraphicsView KPixmapCache KGameTheme N/A
ktron QWidget KPixmapCache KGameTheme N/A
ktuberling QGraphicsView QGraphicsSvgItem N/A Phonon
kubrick QGLWidget N/A N/A N/A
libkmahjongg N/A QPixmapCache N/A N/A
lskat QGraphicsView PixmapCache (client pattern) N/A none
palapeli QGraphicsView N/A N/A N/A

This page was last edited on 25 April 2016, at 21:45. Content is available under Creative Commons License SA 4.0 unless otherwise noted.