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 }