2011-04-16 14:08:33 +02:00
/* ScummVM - Graphic Adventure Engine
2009-10-04 10:58:28 +00:00
*
2011-04-16 14:08:33 +02:00
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
2009-10-04 10:58:28 +00:00
* file distributed with this source distribution .
*
* 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 .
*
* 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 .
*
* 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 .
2014-04-05 18:18:42 +02:00
*
2009-10-04 10:58:28 +00:00
*/
# include "engines/metaengine.h"
# include "base/plugins.h"
# include "base/version.h"
# include "common/events.h"
# include "common/system.h"
2011-04-11 02:28:51 +02:00
# include "common/translation.h"
2009-10-04 10:58:28 +00:00
# include "common/util.h"
# include "gui/about.h"
2011-04-14 12:41:26 +02:00
# include "gui/gui-manager.h"
2009-10-04 10:58:28 +00:00
# include "gui/ThemeEval.h"
namespace GUI {
enum {
kScrollStartDelay = 1500 ,
kScrollMillisPerPixel = 60
} ;
2013-07-07 15:29:33 +02:00
// Every Line should start with a letter followed by a digit. Currently those can be
// (all subject to change)
// Letter:
// C, L, R -- set center/left/right alignment
// A -- ASCII text to replace the next (latin1) line
// Digit:
// 0 - 2 -- set a custom color:
// 0 normal text
// 1 highlighted text
2013-07-16 22:11:39 +02:00
// 2 disabled text
2009-10-04 10:58:28 +00:00
// TODO: Maybe add a tab/indent feature; that is, make it possible to specify
// an amount by which that line shall be indented (the indent of course would have
// to be considered while performing any word wrapping, too).
//
// TODO: Add different font sizes (for bigger headlines)
// TODO: Allow color change in the middle of a line...
static const char * copyright_text [ ] = {
" " ,
2014-01-25 22:16:57 +01:00
" C0 " " Copyright (C) 2003-2014 The ResidualVM Team " ,
2012-01-06 00:19:42 +01:00
" C0 " " http://www.residualvm.org " ,
2009-10-04 10:58:28 +00:00
" " ,
2012-01-06 11:37:57 +01:00
" 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. " ,
2009-10-04 10:58:28 +00:00
" " ,
} ;
static const char * gpl_text [ ] = {
" " ,
" 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. " ,
" C0 " " " ,
" 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. " ,
" " ,
" 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. " ,
" " ,
} ;
# include "gui/credits.h"
AboutDialog : : AboutDialog ( )
: Dialog ( 10 , 20 , 300 , 174 ) ,
_scrollPos ( 0 ) , _scrollTime ( 0 ) , _willClose ( false ) {
2011-04-11 02:28:51 +02:00
reflowLayout ( ) ;
2009-10-04 10:58:28 +00:00
2011-04-11 02:28:51 +02:00
int i ;
2009-10-04 10:58:28 +00:00
for ( i = 0 ; i < 1 ; i + + )
_lines . push_back ( " " ) ;
2012-01-06 11:37:57 +01:00
Common : : String version ( " C0 " " ResidualVM " ) ;
2012-02-22 23:26:36 +01:00
version + = gScummVMVersion ;
2009-10-04 10:58:28 +00:00
_lines . push_back ( version ) ;
2012-02-22 23:26:36 +01:00
Common : : String date = Common : : String : : format ( _ ( " (built on %s) " ) , gScummVMBuildDate ) ;
2011-04-11 11:41:07 +02:00
_lines . push_back ( " C2 " + date ) ;
2009-10-04 10:58:28 +00:00
for ( i = 0 ; i < ARRAYSIZE ( copyright_text ) ; i + + )
addLine ( copyright_text [ i ] ) ;
2011-04-11 11:41:07 +02:00
Common : : String features ( " C1 " ) ;
features + = _ ( " Features compiled in: " ) ;
2009-10-04 10:58:28 +00:00
addLine ( features . c_str ( ) ) ;
2011-04-11 11:41:07 +02:00
Common : : String featureList ( " C0 " ) ;
2012-02-22 23:26:36 +01:00
featureList + = gScummVMFeatures ;
2011-04-11 11:41:07 +02:00
addLine ( featureList . c_str ( ) ) ;
2009-10-04 10:58:28 +00:00
_lines . push_back ( " " ) ;
2011-04-11 11:41:07 +02:00
Common : : String engines ( " C1 " ) ;
engines + = _ ( " Available engines: " ) ;
addLine ( engines . c_str ( ) ) ;
2009-10-04 10:58:28 +00:00
const EnginePlugin : : List & plugins = EngineMan . getPlugins ( ) ;
EnginePlugin : : List : : const_iterator iter = plugins . begin ( ) ;
for ( ; iter ! = plugins . end ( ) ; + + iter ) {
2013-07-07 15:29:33 +02:00
Common : : String str ;
str = " C0 " ;
str + = ( * * iter ) . getName ( ) ;
addLine ( str . c_str ( ) ) ;
2009-10-04 10:58:28 +00:00
2013-07-07 15:29:33 +02:00
str = " C2 " ;
str + = ( * * iter ) - > getOriginalCopyright ( ) ;
addLine ( str . c_str ( ) ) ;
2009-10-04 10:58:28 +00:00
2013-07-07 15:29:33 +02:00
//addLine("");
2009-10-04 10:58:28 +00:00
}
for ( i = 0 ; i < ARRAYSIZE ( gpl_text ) ; i + + )
addLine ( gpl_text [ i ] ) ;
_lines . push_back ( " " ) ;
for ( i = 0 ; i < ARRAYSIZE ( credits ) ; i + + )
addLine ( credits [ i ] ) ;
}
void AboutDialog : : addLine ( const char * str ) {
if ( * str = = 0 ) {
_lines . push_back ( " " ) ;
} else {
Common : : String format ( str , 2 ) ;
str + = 2 ;
2013-07-16 22:11:39 +02:00
2013-07-07 15:29:33 +02:00
static Common : : String asciiStr ;
if ( format [ 0 ] = = ' A ' ) {
bool useAscii = false ;
# ifdef USE_TRANSLATION
// We could use TransMan.getCurrentCharset() but rather than compare strings
// it is easier to use TransMan.getCharsetMapping() (non null in case of non
// ISO-8859-1 mapping)
useAscii = ( TransMan . getCharsetMapping ( ) ! = NULL ) ;
# endif
if ( useAscii )
asciiStr = str ;
return ;
}
2011-04-10 21:59:04 +02:00
StringArray wrappedLines ;
2013-07-07 15:29:33 +02:00
if ( ! asciiStr . empty ( ) ) {
g_gui . getFont ( ) . wordWrapText ( asciiStr , _w - 2 * _xOff , wrappedLines ) ;
asciiStr . clear ( ) ;
} else
g_gui . getFont ( ) . wordWrapText ( str , _w - 2 * _xOff , wrappedLines ) ;
2009-10-04 10:58:28 +00:00
2011-04-10 21:59:04 +02:00
for ( StringArray : : const_iterator i = wrappedLines . begin ( ) ; i ! = wrappedLines . end ( ) ; + + i ) {
2009-10-04 10:58:28 +00:00
_lines . push_back ( format + * i ) ;
}
}
}
void AboutDialog : : open ( ) {
2011-04-10 21:59:04 +02:00
_scrollTime = g_system - > getMillis ( ) + kScrollStartDelay ;
2009-10-04 10:58:28 +00:00
_scrollPos = 0 ;
_willClose = false ;
Dialog : : open ( ) ;
}
void AboutDialog : : close ( ) {
Dialog : : close ( ) ;
}
void AboutDialog : : drawDialog ( ) {
Dialog : : drawDialog ( ) ;
2013-10-13 11:30:34 +02:00
setTextDrawableArea ( Common : : Rect ( _x , _y , _x + _w , _y + _h ) ) ;
2009-10-04 10:58:28 +00:00
// Draw text
// TODO: Add a "fade" effect for the top/bottom text lines
// TODO: Maybe prerender all of the text into another surface,
// and then simply compose that over the screen surface
// in the right way. Should be even faster...
const int firstLine = _scrollPos / _lineHeight ;
const int lastLine = MIN ( ( _scrollPos + _h ) / _lineHeight + 1 , ( uint32 ) _lines . size ( ) ) ;
int y = _y + _yOff - ( _scrollPos % _lineHeight ) ;
for ( int line = firstLine ; line < lastLine ; line + + ) {
const char * str = _lines [ line ] . c_str ( ) ;
Graphics : : TextAlign align = Graphics : : kTextAlignCenter ;
ThemeEngine : : WidgetStateInfo state = ThemeEngine : : kStateEnabled ;
if ( * str ) {
switch ( str [ 0 ] ) {
case ' C ' :
align = Graphics : : kTextAlignCenter ;
break ;
case ' L ' :
align = Graphics : : kTextAlignLeft ;
break ;
case ' R ' :
align = Graphics : : kTextAlignRight ;
break ;
default :
error ( " Unknown scroller opcode '%c' " , str [ 0 ] ) ;
break ;
}
switch ( str [ 1 ] ) {
case ' 0 ' :
state = ThemeEngine : : kStateEnabled ;
break ;
case ' 1 ' :
state = ThemeEngine : : kStateHighlight ;
break ;
case ' 2 ' :
state = ThemeEngine : : kStateDisabled ;
break ;
case ' 3 ' :
warning ( " Need state for color 3 " ) ;
// color = g_gui._shadowcolor;
break ;
case ' 4 ' :
warning ( " Need state for color 4 " ) ;
// color = g_gui._bgcolor;
break ;
default :
error ( " Unknown color type '%c' " , str [ 1 ] ) ;
}
str + = 2 ;
}
// Trim leading whitespaces if center mode is on
if ( align = = Graphics : : kTextAlignCenter )
while ( * str & & * str = = ' ' )
str + + ;
2013-10-13 11:30:34 +02:00
if ( * str )
g_gui . theme ( ) - > drawText ( Common : : Rect ( _x + _xOff , y , _x + _w - _xOff , y + g_gui . theme ( ) - > getFontHeight ( ) ) , str , state , align , ThemeEngine : : kTextInversionNone , 0 , false , ThemeEngine : : kFontStyleBold , ThemeEngine : : kFontColorNormal , true , _textDrawableArea ) ;
2009-10-04 10:58:28 +00:00
y + = _lineHeight ;
}
}
void AboutDialog : : handleTickle ( ) {
2011-04-10 21:59:04 +02:00
const uint32 t = g_system - > getMillis ( ) ;
2009-10-04 10:58:28 +00:00
int scrollOffset = ( ( int ) t - ( int ) _scrollTime ) / kScrollMillisPerPixel ;
if ( scrollOffset > 0 ) {
int modifiers = g_system - > getEventManager ( ) - > getModifierState ( ) ;
// Scroll faster when shift is pressed
if ( modifiers & Common : : KBD_SHIFT )
scrollOffset * = 4 ;
// Reverse scrolling when alt is pressed
if ( modifiers & Common : : KBD_ALT )
scrollOffset * = - 1 ;
_scrollPos + = scrollOffset ;
_scrollTime = t ;
if ( _scrollPos < 0 ) {
_scrollPos = 0 ;
} else if ( ( uint32 ) _scrollPos > _lines . size ( ) * _lineHeight ) {
_scrollPos = 0 ;
_scrollTime + = kScrollStartDelay ;
}
drawDialog ( ) ;
}
}
void AboutDialog : : handleMouseUp ( int x , int y , int button , int clickCount ) {
// Close upon any mouse click
close ( ) ;
}
void AboutDialog : : handleKeyDown ( Common : : KeyState state ) {
if ( state . ascii )
_willClose = true ;
}
void AboutDialog : : handleKeyUp ( Common : : KeyState state ) {
if ( state . ascii & & _willClose )
close ( ) ;
}
void AboutDialog : : reflowLayout ( ) {
Dialog : : reflowLayout ( ) ;
2011-04-11 02:28:51 +02:00
int i ;
2009-10-04 10:58:28 +00:00
const int screenW = g_system - > getOverlayWidth ( ) ;
const int screenH = g_system - > getOverlayHeight ( ) ;
_xOff = g_gui . xmlEval ( ) - > getVar ( " Globals.About.XOffset " , 5 ) ;
_yOff = g_gui . xmlEval ( ) - > getVar ( " Globals.About.YOffset " , 5 ) ;
int outerBorder = g_gui . xmlEval ( ) - > getVar ( " Globals.About.OuterBorder " ) ;
_w = screenW - 2 * outerBorder ;
_h = screenH - 2 * outerBorder ;
_lineHeight = g_gui . getFontHeight ( ) + 3 ;
// Heuristic to compute 'optimal' dialog width
int maxW = _w - 2 * _xOff ;
_w = 0 ;
2011-04-11 02:28:51 +02:00
for ( i = 0 ; i < ARRAYSIZE ( credits ) ; i + + ) {
2013-07-07 15:29:33 +02:00
int tmp = g_gui . getStringWidth ( credits [ i ] ) + 5 ;
2009-10-05 08:33:46 +00:00
if ( _w < tmp & & tmp < = maxW ) {
2009-10-04 10:58:28 +00:00
_w = tmp ;
}
}
_w + = 2 * _xOff ;
2011-04-11 02:28:51 +02:00
// Center the dialog
2009-10-04 10:58:28 +00:00
_x = ( screenW - _w ) / 2 ;
_y = ( screenH - _h ) / 2 ;
}
} // End of namespace GUI