File indexing completed on 2024-04-28 04:04:39

0001 /*
0002     This file is part of the game 'KTron'
0003 
0004     SPDX-FileCopyrightText: 1998-2000 Matthias Kiefer <matthias.kiefer@gmx.de>
0005     SPDX-FileCopyrightText: 2005 Benjamin C. Meyer <ben at meyerhome dot net>
0006     SPDX-FileCopyrightText: 2008-2009 Stas Verberkt <legolas at legolasweb dot nl>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 
0010 */
0011 
0012 #include "renderer.h"
0013 
0014 #include "object.h"
0015 #include "ksnakeduel_debug.h"
0016 // KDEGames
0017 #include <KGameThemeProvider>
0018 // KF
0019 #include <KFontUtils>
0020 
0021 static KGameThemeProvider *provider()
0022 {
0023     auto *prov = new KGameThemeProvider(QByteArray()); // empty config key to disable internal config storage
0024     prov->discoverThemes(
0025         QStringLiteral("themes"), // theme file location
0026         QStringLiteral("default") // default theme file name
0027     );
0028     return prov;
0029 }
0030 
0031 
0032 Renderer::Renderer()
0033     : KGameRenderer(provider())
0034 {
0035 }
0036 
0037 
0038 Renderer *Renderer::self()
0039 {
0040     static Renderer r;
0041     return &r;
0042 }
0043 
0044 bool Renderer::loadTheme(const QString &name)
0045 {
0046     const QByteArray identifier = name.toUtf8();
0047     KGameThemeProvider *provider = themeProvider();
0048     const QList<const KGameTheme *> themes = provider->themes();
0049     for (auto* theme : themes) {
0050         if (theme->identifier() == identifier) {
0051         provider->setCurrentTheme(theme);
0052         return true;
0053         }
0054     }
0055     return false;
0056 }
0057 
0058 QPixmap Renderer::getPart(const QString &frameSvgName)
0059 {
0060     return getPartOfSize(frameSvgName, m_partSize);
0061 }
0062 
0063 QPixmap Renderer::getPartOfSize(const QString &frameSvgName, const QSize &partSize)
0064 {
0065     return spritePixmap(frameSvgName, partSize);
0066 }
0067 
0068 QPixmap Renderer::background()
0069 {
0070         if (m_background.isNull())
0071     {
0072         m_background = QPixmap(m_sceneSize);
0073         m_background.fill(Qt::white);
0074         QPainter painter(&m_background);
0075 
0076         QPixmap bgPix = getPart(QStringLiteral( "bgtile" ));
0077         if (!bgPix.isNull())
0078         {
0079             m_background.fill(Qt::white);
0080             int pw = bgPix.width();
0081             int ph = bgPix.height();
0082             for (int x = 0; x <= m_sceneSize.width(); x += pw) {
0083                 for (int y = 0; y <= m_sceneSize.height(); y += ph) {
0084                     painter.drawPixmap(x, y, bgPix);
0085                 }
0086             }
0087         }
0088         else
0089         {
0090             m_background.fill(Qt::green);
0091         }
0092 
0093         painter.end();
0094     }
0095 
0096     // Tiled background
0097     return m_background;
0098 }
0099 
0100 void Renderer::boardResized(int width, int height, int partWidth, int partHeight)
0101 {
0102     //new metrics
0103     m_sceneSize = QSize(width, height);
0104     m_partSize = QSize(partWidth, partHeight);
0105 
0106     clearPixmapCache();
0107 }
0108 
0109 void Renderer::clearPixmapCache()
0110 {
0111     m_background = QPixmap();
0112     m_playField = QPixmap();
0113 }
0114 
0115 void Renderer::updatePlayField(PlayField &playfield)
0116 {
0117     int i, j;
0118 
0119     if (m_playField.isNull())
0120     {
0121         if (m_sceneSize.isEmpty()) {
0122             return;
0123         }
0124         m_playField = QPixmap(m_sceneSize);
0125     }
0126 
0127     QPainter painter;
0128     painter.begin(&m_playField);
0129 
0130     QPixmap bgPix = background();
0131     painter.drawPixmap(0, 0, bgPix);
0132 
0133     // Draw border
0134     const QPixmap part = Renderer::self()->getPart(QStringLiteral( "border" ));
0135     for (i = 0; i < playfield.getWidth() + 2; ++i)
0136     {
0137         for (j = 0; j < playfield.getHeight() + 2; ++j)
0138         {
0139             if (i == 0 || i == playfield.getWidth() + 1 || j == 0 || j == playfield.getHeight() + 1)
0140             {
0141                 painter.drawPixmap(calculateOffsetX(i), calculateOffsetY(j), part);
0142             }
0143         }
0144     }
0145 
0146     // Examine all pixels and draw
0147     for(i = 0; i < playfield.getWidth(); ++i)
0148     {
0149         for(j = 0; j < playfield.getHeight(); ++j)
0150         {
0151             if (playfield.getObjectAt(i, j)->getObjectType() != ObjectType::Object)
0152             {
0153                 drawPart(painter, i, j, playfield.getObjectAt(i, j)->getSVGName());
0154             }
0155         }
0156     }
0157 
0158     painter.end();
0159 }
0160 
0161 int Renderer::calculateOffsetX(int x)
0162 {
0163     return (x * m_partSize.width()) + (m_sceneSize.width() - (TRON_PLAYFIELD_WIDTH + 2) * m_partSize.width()) / 2;
0164 }
0165 
0166 int Renderer::calculateOffsetY(int y)
0167 {
0168     return (y * m_partSize.height()) + (m_sceneSize.height() - (TRON_PLAYFIELD_HEIGHT + 2) * m_partSize.height()) / 2;
0169 }
0170 
0171 void Renderer::drawPart(QPainter & painter, int x, int y, const QString &svgName)
0172 {
0173     //qCDebug(KSNAKEDUEL_LOG) << "Drawing part: " << svgName;
0174 
0175     int xOffset = calculateOffsetX(x + 1);
0176     int yOffset = calculateOffsetY(y + 1);
0177 
0178     //int type = playfield[x][y];
0179 
0180     QPixmap snakePart = Renderer::self()->getPart(svgName);
0181 
0182     painter.drawPixmap(xOffset, yOffset, snakePart);
0183 }
0184 
0185 QPixmap *Renderer::getPlayField()
0186 {
0187     return &m_playField;
0188 }
0189 
0190 QPixmap Renderer::messageBox(const QString &message) {
0191     int w = m_sceneSize.width() / 2;
0192     int h = m_sceneSize.height() / 3;
0193 
0194     QSize size(w, h);
0195     QPixmap pixmap = getPartOfSize(QStringLiteral( "display" ),  size);
0196 
0197     QPainter painter(&pixmap);
0198 
0199     const int fontSize = KFontUtils::adaptFontSize(painter, message, w * 0.9, h, 28, 1, KFontUtils::DoNotAllowWordWrap);
0200 
0201     painter.setPen(QColor(255, 255, 255, 220));
0202     painter.setFont(QFont(QStringLiteral( "Helvetica" ), fontSize, QFont::Bold));
0203     painter.drawText(QRectF(0, 0, w, h), Qt::AlignCenter, message);
0204 
0205     painter.end();
0206 
0207     return pixmap;
0208 }