00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "engines/metaengine.h"
00024 #include "base/plugins.h"
00025 #include "base/version.h"
00026 #include "common/events.h"
00027 #include "common/system.h"
00028 #include "common/translation.h"
00029 #include "common/util.h"
00030 #include "gui/about.h"
00031 #include "gui/gui-manager.h"
00032 #include "gui/ThemeEval.h"
00033
00034 namespace GUI {
00035
00036 enum {
00037 kScrollStartDelay = 1500,
00038 kScrollMillisPerPixel = 60
00039 };
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 static const char *copyright_text[] = {
00059 "",
00060 "C0""Copyright (C) 2003-2019 The ResidualVM Team",
00061 "C0""http://www.residualvm.org",
00062 "",
00063 "C0""ResidualVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the AUTHORS file distributed with this binary.",
00064 "",
00065 };
00066
00067 static const char *gpl_text[] = {
00068 "",
00069 "C0""This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.",
00070 "C0""",
00071 "C0""This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.",
00072 "",
00073 "C0""You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.",
00074 "",
00075 };
00076
00077 #include "gui/credits.h"
00078
00079 AboutDialog::AboutDialog()
00080 : Dialog(10, 20, 300, 174),
00081 _scrollPos(0), _scrollTime(0), _willClose(false) {
00082
00083 reflowLayout();
00084
00085 int i;
00086
00087 for (i = 0; i < 1; i++)
00088 _lines.push_back("");
00089
00090 Common::String version("C0""ResidualVM ");
00091 version += gScummVMVersion;
00092 _lines.push_back(version);
00093
00094 Common::String date = Common::String::format(_("(built on %s)"), gScummVMBuildDate);
00095 _lines.push_back("C2" + date);
00096
00097 for (i = 0; i < ARRAYSIZE(copyright_text); i++)
00098 addLine(copyright_text[i]);
00099
00100 Common::String features("C1");
00101 features += _("Features compiled in:");
00102 addLine(features.c_str());
00103 Common::String featureList("C0");
00104 featureList += gScummVMFeatures;
00105 addLine(featureList.c_str());
00106
00107 _lines.push_back("");
00108
00109 Common::String engines("C1");
00110 engines += _("Available engines:");
00111 addLine(engines.c_str());
00112
00113 const PluginList &plugins = EngineMan.getPlugins();
00114 PluginList::const_iterator iter = plugins.begin();
00115 for (; iter != plugins.end(); ++iter) {
00116 Common::String str;
00117 str = "C0";
00118 str += (*iter)->getName();
00119 addLine(str.c_str());
00120
00121 str = "C2";
00122 str += (*iter)->get<MetaEngine>().getOriginalCopyright();
00123 addLine(str.c_str());
00124
00125
00126 }
00127
00128 for (i = 0; i < ARRAYSIZE(gpl_text); i++)
00129 addLine(gpl_text[i]);
00130
00131 _lines.push_back("");
00132
00133 for (i = 0; i < ARRAYSIZE(credits); i++)
00134 addLine(credits[i]);
00135 }
00136
00137 void AboutDialog::addLine(const char *str) {
00138 if (*str == 0) {
00139 _lines.push_back("");
00140 } else {
00141 Common::String format(str, 2);
00142 str += 2;
00143
00144 static Common::String asciiStr;
00145 if (format[0] == 'A') {
00146 bool useAscii = false;
00147 #ifdef USE_TRANSLATION
00148
00149
00150
00151 useAscii = (TransMan.getCharsetMapping() != NULL);
00152 #endif
00153 if (useAscii)
00154 asciiStr = str;
00155 return;
00156 }
00157 StringArray wrappedLines;
00158 if (!asciiStr.empty()) {
00159 g_gui.getFont().wordWrapText(asciiStr, _w - 2 * _xOff, wrappedLines);
00160 asciiStr.clear();
00161 } else
00162 g_gui.getFont().wordWrapText(str, _w - 2 * _xOff, wrappedLines);
00163
00164 for (StringArray::const_iterator i = wrappedLines.begin(); i != wrappedLines.end(); ++i) {
00165 _lines.push_back(format + *i);
00166 }
00167 }
00168 }
00169
00170
00171 void AboutDialog::open() {
00172 _scrollTime = g_system->getMillis() + kScrollStartDelay;
00173 _scrollPos = 0;
00174 _willClose = false;
00175
00176 Dialog::open();
00177 }
00178
00179 void AboutDialog::close() {
00180 Dialog::close();
00181 }
00182
00183 void AboutDialog::drawDialog(DrawLayer layerToDraw) {
00184 Dialog::drawDialog(layerToDraw);
00185
00186 setTextDrawableArea(Common::Rect(_x, _y, _x + _w, _y + _h));
00187
00188
00189
00190
00191
00192
00193 const int firstLine = _scrollPos / _lineHeight;
00194 const int lastLine = MIN((_scrollPos + _h) / _lineHeight + 1, (uint32)_lines.size());
00195 int y = _y + _yOff - (_scrollPos % _lineHeight);
00196
00197 for (int line = firstLine; line < lastLine; line++) {
00198 const char *str = _lines[line].c_str();
00199 Graphics::TextAlign align = Graphics::kTextAlignCenter;
00200 ThemeEngine::WidgetStateInfo state = ThemeEngine::kStateEnabled;
00201 if (*str) {
00202 switch (str[0]) {
00203 case 'C':
00204 align = Graphics::kTextAlignCenter;
00205 break;
00206 case 'L':
00207 align = Graphics::kTextAlignLeft;
00208 break;
00209 case 'R':
00210 align = Graphics::kTextAlignRight;
00211 break;
00212 default:
00213 error("Unknown scroller opcode '%c'", str[0]);
00214 break;
00215 }
00216 switch (str[1]) {
00217 case '0':
00218 state = ThemeEngine::kStateEnabled;
00219 break;
00220 case '1':
00221 state = ThemeEngine::kStateHighlight;
00222 break;
00223 case '2':
00224 state = ThemeEngine::kStateDisabled;
00225 break;
00226 case '3':
00227 warning("Need state for color 3");
00228
00229 break;
00230 case '4':
00231 warning("Need state for color 4");
00232
00233 break;
00234 default:
00235 error("Unknown color type '%c'", str[1]);
00236 }
00237 str += 2;
00238 }
00239
00240 if (align == Graphics::kTextAlignCenter)
00241 while (*str && *str == ' ')
00242 str++;
00243
00244 if (*str)
00245 g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()),
00246 str, state, align, ThemeEngine::kTextInversionNone, 0, false,
00247 ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
00248 y += _lineHeight;
00249 }
00250 }
00251
00252 void AboutDialog::handleTickle() {
00253 const uint32 t = g_system->getMillis();
00254 int scrollOffset = ((int)t - (int)_scrollTime) / kScrollMillisPerPixel;
00255 if (scrollOffset > 0) {
00256 int modifiers = g_system->getEventManager()->getModifierState();
00257
00258
00259 if (modifiers & Common::KBD_SHIFT)
00260 scrollOffset *= 4;
00261
00262 if (modifiers & Common::KBD_ALT)
00263 scrollOffset *= -1;
00264 _scrollPos += scrollOffset;
00265 _scrollTime = t;
00266
00267 if (_scrollPos < 0) {
00268 _scrollPos = 0;
00269 } else if ((uint32)_scrollPos > _lines.size() * _lineHeight) {
00270 _scrollPos = 0;
00271 _scrollTime += kScrollStartDelay;
00272 }
00273 drawDialog(kDrawLayerForeground);
00274 }
00275 }
00276
00277 void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
00278
00279 close();
00280 }
00281
00282 void AboutDialog::handleKeyDown(Common::KeyState state) {
00283 if (state.ascii)
00284 _willClose = true;
00285 }
00286
00287 void AboutDialog::handleKeyUp(Common::KeyState state) {
00288 if (state.ascii && _willClose)
00289 close();
00290 }
00291
00292 void AboutDialog::reflowLayout() {
00293 Dialog::reflowLayout();
00294 int i;
00295 const int screenW = g_system->getOverlayWidth();
00296 const int screenH = g_system->getOverlayHeight();
00297
00298 _xOff = g_gui.xmlEval()->getVar("Globals.About.XOffset", 5);
00299 _yOff = g_gui.xmlEval()->getVar("Globals.About.YOffset", 5);
00300 int outerBorder = g_gui.xmlEval()->getVar("Globals.About.OuterBorder");
00301
00302 _w = screenW - 2 * outerBorder;
00303 _h = screenH - 2 * outerBorder;
00304
00305 _lineHeight = g_gui.getFontHeight() + 3;
00306
00307
00308 int maxW = _w - 2*_xOff;
00309 _w = 0;
00310 for (i = 0; i < ARRAYSIZE(credits); i++) {
00311 int tmp = g_gui.getStringWidth(credits[i]) + 5;
00312 if (_w < tmp && tmp <= maxW) {
00313 _w = tmp;
00314 }
00315 }
00316 _w += 2*_xOff;
00317
00318
00319 _x = (screenW - _w) / 2;
00320 _y = (screenH - _h) / 2;
00321 }
00322
00323 }