File indexing completed on 2024-04-28 04:02:14

0001 /*
0002     SPDX-FileCopyrightText: 2012 Ian Wadham <iandw.au@gmail.com>
0003     SPDX-FileCopyrightText: 2012 Roney Gomes <roney477@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef KGRRENDERER_H
0009 #define KGRRENDERER_H
0010 
0011 #include <QObject>
0012 #include <QString>
0013 #include <KGameRenderer>
0014 
0015 #include "kgrsprite.h"
0016 
0017 class KGrScene;
0018 class KGameThemeProvider;
0019 class KGameThemeSelector;
0020 class KGameRenderedItem;
0021 
0022 /* @short A class to assist theme-handling and rendering in KGoldrunner.
0023  *
0024  * KGoldrunner has two SVG files for each theme: one to hold the Actors (hero
0025  * and enemies) and one to hold the Set (bricks, ladders, background, etc.).
0026  *
0027  * The files are marked with the keywords "Actors" and "Set" in each theme's
0028  * .desktop file, rather than the usual "Filename" keyword. There are two
0029  * KGameThemeProvider objects and two KGameRenderer objects, each with its own
0030  * set of SVG files and KGameTheme objects.
0031  *
0032  * There is one KGameThemeSelector object, which selects the "Set" theme and uses
0033  * the "Set" KGameThemeProvider. Its currentThemeChanged signal is connected to a
0034  * currentThemeChanged slot in KGrRenderer, which finds the KGameTheme for the
0035  * corresponding "Actors" theme and SVG file.
0036  *
0037  * KGoldrunner also has several different usages of the KGameRenderer concepts
0038  * of "frameSuffix" and "frameBaseIndex". For animation frames (hero, enemies
0039  * and dug bricks), it always has frameSuffix = "_%1" and frameBaseIndex = 1, so
0040  * animation will be handled normally by KGameRenderer. 
0041  *
0042  * Depending on the theme and the artist's choices, backgrounds and tiles can
0043  * have one or more variants, to add variety to the look of brick walls, etc.
0044  * The suffixes used can be "-%1" or just "%1" and the frameBaseIndex = 0, or
0045  * there can be just one variant, with no suffix. The keyTable structure and the
0046  * getPixmapKey() and getBackgroundKey() methods of KGrRenderer provide ways to
0047  * go from KGoldrunner's internal tile-types to SVG element names that can be
0048  * used as pixmap keys in KGameRenderer.
0049  */
0050 class KGrRenderer : public QObject
0051 {
0052     Q_OBJECT
0053 public:
0054     explicit KGrRenderer (KGrScene * scene);
0055     ~KGrRenderer() override;
0056 
0057     /*
0058      * Get a pointer to the KGameRenderer for "Set" graphics (bricks, etc.).
0059      */
0060     KGameRenderer * getSetRenderer()    { return m_setRenderer; }
0061 
0062     /*
0063      * Get a pointer to the KGameRenderer for "Actors" graphics (hero, etc.).
0064      */
0065     KGameRenderer * getActorsRenderer() { return m_actorsRenderer; }
0066 
0067     /*
0068      * Create the QGraphicsScene item for a tile of a particular type (e.g. bar,
0069      * gold, concrete, etc.) at a place in the on-screen KGoldrunner grid.
0070      *
0071      * @param picType     The internal KGoldrunner type of the required tile. If
0072      *                    FREE, just delete the previous tile (if any).
0073      * @param currentTile The pre-existing tile that is to be replaced or
0074      *                    deleted, or zero if the place is empty.
0075      */
0076     KGameRenderedItem * getTileItem (const char picType,
0077                                      KGameRenderedItem * currentTile);
0078 
0079     /*
0080      * Create the QGraphicsScene item for the background corresponding to the
0081      * current level.
0082      *
0083      * @param level             The current level in a KGoldrunner game.
0084      * @param currentBackground The pre-existing background that is to be
0085      *                          replaced, or zero if there's no background yet.
0086      */
0087     KGameRenderedItem * getBackground (const int level,
0088                                        KGameRenderedItem * currentBackground);
0089 
0090     /*
0091      * Create the QGraphicsScene item for a border tile.
0092      *
0093      * @param spriteKey     The name of the sprite which will be rendered. 
0094      * @param currentItem   The pre-existing item that is to be replaced, or
0095      *                      zero if the previous theme had no border.
0096      */
0097     KGameRenderedItem * getBorderItem (const QString &spriteKey,
0098                                        KGameRenderedItem * currentItem);
0099 
0100     /*
0101      * TODO - Document this.
0102      */
0103     KGrSprite * getSpriteItem (const char picType, const int tickTime);
0104 
0105     /*
0106      * Returns true case the current theme has a border around its background
0107      * and false otherwise.
0108      */
0109     bool hasBorder      () const;
0110 
0111     /*
0112      * Get the color of the scene's background brush requested for the current
0113      * theme.
0114      */
0115     QColor borderColor  () const;
0116 
0117     /*
0118      * Get the color of the on-screen text which appears in certain game stages
0119      * (the demo stage for instance) and in the score box.
0120      */
0121     QColor textColor    () const;
0122 
0123     /*
0124      * Get a pixmap of a particular tile type (e.g. brick, ladder, gold etc.) 
0125      *
0126      * @param picType The internal KGoldRunner type of the required tile.
0127      */
0128     QPixmap getPixmap   (const char picType);
0129 
0130     /*
0131      * Show the theme-selector dialog. When the theme changes, KGrRenderer uses
0132      * a signal and slot to keep the "Set" and "Actors" parts of the theme and
0133      * SVG files in synch.
0134      */
0135     void selectTheme();
0136 
0137 private Q_SLOTS:
0138      // Keep the "Set" and "Actors" parts of a KGoldrunner theme in synch as
0139      // the theme-selection changes.
0140     void currentThemeChanged(const KGameTheme * currentSetTheme);
0141 
0142 private:
0143     enum   PicSrc     {Actors, Set};
0144 
0145     // Structure of table-row to specify a tile or pixmap type in a theme.
0146     struct PixmapSpec {
0147         const char    picType;      // KGoldrunner's internal type.
0148     const PicSrc  picSource;    // Actors or Set?
0149     const char *  picKey;       // Prefix of SVG element name.
0150     const char *  frameSuffix;  // Format of suffix or "" if none.
0151     const int     frameBaseIndex;   // Lowest value of suffix or -1 if none.
0152           int     frameCount;   // Number of variants available.
0153                     // -2 = not yet counted, -1 = element
0154                     // not found, 0 = only one variant with
0155                     // no suffix, >0 = number of variants.
0156     };
0157 
0158     KGrScene        * m_scene;      // The scene to be rendered.
0159 
0160     KGameThemeProvider * m_setProvider; // Provider for Set themes.
0161     KGameThemeProvider * m_actorsProvider;  // Provider for Actors themes.
0162 
0163     KGameThemeSelector * m_themeSelector;   // Selector (dialog) for themes.
0164 
0165     KGameRenderer   * m_setRenderer;    // Renderer for Set SVG files.
0166     KGameRenderer   * m_actorsRenderer; // Renderer for Actors SVG files.
0167 
0168     static PixmapSpec keyTable [];  // Table of tile/background specs.
0169 
0170     // Set the frame counts to -2 at startup and when the theme changes.
0171     void initPixmapKeys();
0172 
0173     // Make the Actors theme (hero, etc.) match the Set theme (bricks, etc.).
0174     void matchThemes (const KGameTheme * currentSetTheme);
0175 
0176     // Find a tile type or background in the table of tiles and backgrounds.
0177     int findKeyTableIndex (const char picType);
0178 
0179     // Count the number of variants of a tile or background.
0180     int countFrames (const int index);
0181 
0182     /*
0183      * Get the SVG element name for a KGoldrunner tile type. If the theme has
0184      * more than one tile of that type (e.g. BRICK), make a random selection.
0185      *
0186      * @param picType The internal KGoldrunner type of a tile or background.
0187      */
0188     QString getPixmapKey (const int index);
0189 
0190     /*
0191      * Get the SVG element name for a KGoldrunner background. If the theme has
0192      * more than one background, cycle though the choices as the KGoldrunner
0193      * game's level changes.
0194      *
0195      * @param level The current level in a KGoldrunner game.
0196      */
0197     QString getBackgroundKey (const int level);
0198 };
0199 
0200 #endif // KGRRENDERER_H