2003-07-22 16:05:51 +00:00
/* ScummVM - Scumm Interpreter
2006-01-18 17:39:49 +00:00
* Copyright ( C ) 2002 - 2006 The ScummVM project
2003-07-22 16:05:51 +00:00
*
* 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
2005-10-18 01:30:26 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2003-07-22 16:05:51 +00:00
*
2006-02-11 10:08:56 +00:00
* $ URL $
* $ Id $
2003-07-22 16:05:51 +00:00
*/
2005-06-24 15:23:51 +00:00
# include "common/stdafx.h"
2003-09-18 02:07:18 +00:00
# include "base/engine.h"
2004-02-09 01:27:27 +00:00
# include "base/version.h"
2005-01-10 22:06:49 +00:00
# include "common/system.h"
2005-01-10 22:35:43 +00:00
# include "common/util.h"
2003-11-02 14:50:53 +00:00
# include "gui/about.h"
2006-03-24 14:15:45 +00:00
# include "gui/eval.h"
2003-11-02 14:50:53 +00:00
# include "gui/newgui.h"
# include "gui/widget.h"
2003-07-22 16:05:51 +00:00
2003-11-10 23:40:48 +00:00
namespace GUI {
2004-12-19 19:17:43 +00:00
enum {
2004-12-30 14:21:16 +00:00
kScrollStartDelay = 1500 ,
2005-12-19 02:23:01 +00:00
kScrollMillisPerPixel = 60
2004-12-19 19:17:43 +00:00
} ;
// The following commands can be put at the start of a line (all subject to change):
// \C, \L, \R -- set center/left/right alignment
// \c0 - \c4 -- set a custom color:
// 0 normal text (green)
// 1 highlighted text (light green)
// 2 light border (light gray)
// 3 dark border (dark gray)
// 4 background (black)
2005-05-17 23:41:35 +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).
2005-12-19 02:23:01 +00:00
//
// TODO: Add different font sizes (for bigger headlines)
// TODO: Allow color change in the middle of a line...
2004-12-22 01:07:13 +00:00
static const char * credits_intro [ ] = {
2006-01-18 17:39:49 +00:00
" \\ C " " Copyright (C) 2002-2006 The ScummVM project " ,
2004-12-19 19:17:43 +00:00
" \\ C " " http://www.scummvm.org " ,
" \\ C " " " ,
" \\ C " " LucasArts SCUMM Games (C) LucasArts " ,
" \\ C " " Humongous SCUMM Games (C) Humongous " ,
" \\ C " " Simon the Sorcerer (C) Adventure Soft " ,
" \\ C " " Beneath a Steel Sky (C) Revolution " ,
" \\ C " " Broken Sword Games (C) Revolution " ,
" \\ C " " Flight of the Amazon Queen (C) John Passfield " ,
" \\ C " " and Steve Stamatiadis " ,
2005-09-16 22:18:46 +00:00
" \\ C " " Inherit the Earth (C) Wyrmkeep Entertainment " ,
" \\ C " " Goblins Games (C) Coktel Vision " ,
2006-01-26 23:53:13 +00:00
" \\ C " " The Legend of Kyrandia (C) Westwood Studios " ,
2004-12-23 19:32:25 +00:00
" \\ C " " " ,
2005-05-17 23:41:35 +00:00
" \\ C " " 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. " ,
2004-12-23 19:32:25 +00:00
" \\ C " " " ,
2005-05-17 23:41:35 +00:00
" \\ C " " 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. " ,
2004-12-23 19:32:25 +00:00
" \\ C " " " ,
2005-10-18 01:30:26 +00:00
" \\ C " " 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. " ,
2004-12-22 01:07:13 +00:00
" \\ C " " "
2004-12-19 19:17:43 +00:00
} ;
2004-12-22 01:07:13 +00:00
# include "gui/credits.h"
2003-11-02 02:18:16 +00:00
AboutDialog : : AboutDialog ( )
2004-12-19 19:17:43 +00:00
: Dialog ( 10 , 20 , 300 , 174 ) ,
2004-12-30 14:55:20 +00:00
_scrollPos ( 0 ) , _scrollTime ( 0 ) , _modifiers ( 0 ) , _willClose ( false ) {
2005-07-30 21:11:48 +00:00
2004-12-19 19:17:43 +00:00
int i ;
2005-07-30 21:11:48 +00:00
2005-05-17 21:40:29 +00:00
const int screenW = g_system - > getOverlayWidth ( ) ;
const int screenH = g_system - > getOverlayHeight ( ) ;
2005-07-30 21:11:48 +00:00
2006-04-19 01:05:28 +00:00
xOff = g_gui . evaluator ( ) - > getVar ( " aboutXOff " ) ;
yOff = g_gui . evaluator ( ) - > getVar ( " aboutYOff " ) ;
int outerBorder = g_gui . evaluator ( ) - > getVar ( " aboutOuterBorder " ) ;
2005-05-17 23:41:35 +00:00
_w = screenW - 2 * outerBorder ;
_h = screenH - 2 * outerBorder ;
2005-07-30 21:11:48 +00:00
2005-06-03 12:07:53 +00:00
_lineHeight = g_gui . getFontHeight ( ) + 3 ;
2003-11-08 23:22:16 +00:00
2005-05-17 23:41:35 +00:00
// Heuristic to compute 'optimal' dialog width
int maxW = _w - 2 * xOff ;
_w = 0 ;
for ( i = 0 ; i < ARRAYSIZE ( credits ) ; i + + ) {
2005-06-03 12:07:53 +00:00
int tmp = g_gui . getStringWidth ( credits [ i ] + 5 ) ;
2005-05-17 23:41:35 +00:00
if ( _w < tmp & & tmp < = maxW ) {
_w = tmp ;
}
}
_w + = 2 * xOff ;
2004-12-19 19:17:43 +00:00
for ( i = 0 ; i < 1 ; i + + )
_lines . push_back ( " " ) ;
Common : : String version ( " \\ C \\ c0 " " ScummVM " ) ;
2003-07-22 16:05:51 +00:00
version + = gScummVMVersion ;
2004-12-19 19:17:43 +00:00
_lines . push_back ( version ) ;
2003-07-22 16:05:51 +00:00
2004-12-19 19:17:43 +00:00
Common : : String date ( " \\ C \\ c2 " " (built on " ) ;
2003-07-22 16:05:51 +00:00
date + = gScummVMBuildDate ;
date + = ' ) ' ;
2004-12-19 19:17:43 +00:00
_lines . push_back ( date ) ;
2003-07-22 16:05:51 +00:00
2005-05-17 23:41:35 +00:00
Common : : String features ( " \\ C \\ c2 " " Supports: " ) ;
2004-02-09 01:27:27 +00:00
features + = gScummVMFeatures ;
2005-05-17 23:41:35 +00:00
addLine ( features . c_str ( ) ) ;
2004-12-19 19:17:43 +00:00
_lines . push_back ( " " ) ;
2005-07-30 21:11:48 +00:00
2004-12-22 01:07:13 +00:00
for ( i = 0 ; i < ARRAYSIZE ( credits_intro ) ; i + + )
2005-05-17 23:41:35 +00:00
addLine ( credits_intro [ i ] ) ;
2005-07-30 21:11:48 +00:00
2004-12-22 01:07:13 +00:00
for ( i = 0 ; i < ARRAYSIZE ( credits ) ; i + + )
2005-05-17 23:41:35 +00:00
addLine ( credits [ i ] ) ;
2005-05-17 21:40:29 +00:00
// Center the dialog
_x = ( screenW - _w ) / 2 ;
_y = ( screenH - _h ) / 2 ;
2004-12-19 19:17:43 +00:00
}
2005-05-17 23:41:35 +00:00
void AboutDialog : : addLine ( const char * str ) {
// Extract formatting instructions
Common : : String format ;
while ( * str = = ' \\ ' ) {
format + = * str + + ;
switch ( * str ) {
case ' C ' :
case ' L ' :
case ' R ' :
format + = * str + + ;
break ;
case ' c ' :
format + = * str + + ;
format + = * str + + ;
break ;
default :
error ( " Unknown scroller opcode '%c' \n " , * str ) ;
break ;
}
}
2005-07-30 21:11:48 +00:00
2005-05-17 23:41:35 +00:00
if ( * str = = 0 ) {
_lines . push_back ( format ) ;
} else {
Common : : StringList wrappedLines ;
2006-01-27 15:43:23 +00:00
g_gui . getFont ( ) . wordWrapText ( str , _w - 2 * xOff , wrappedLines ) ;
2005-07-30 21:11:48 +00:00
2005-05-17 23:41:35 +00:00
for ( Common : : StringList : : const_iterator i = wrappedLines . begin ( ) ; i ! = wrappedLines . end ( ) ; + + i ) {
_lines . push_back ( format + * i ) ;
}
}
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : open ( ) {
2005-01-10 22:06:49 +00:00
_scrollTime = getMillis ( ) + kScrollStartDelay ;
2004-12-19 19:17:43 +00:00
_scrollPos = 0 ;
2004-12-30 14:55:20 +00:00
_modifiers = 0 ;
_willClose = false ;
2004-12-19 19:17:43 +00:00
Dialog : : open ( ) ;
}
2005-04-16 11:40:15 +00:00
void AboutDialog : : close ( ) {
Dialog : : close ( ) ;
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : drawDialog ( ) {
2006-01-27 15:43:23 +00:00
g_gui . theme ( ) - > setDrawArea ( Common : : Rect ( _x , _y , _x + _w , _y + _h ) ) ;
Dialog : : drawDialog ( ) ;
2004-12-19 19:17:43 +00:00
// Draw text
// TODO: Add a "fade" effect for the top/bottom text lines
2005-04-16 11:40:15 +00:00
// 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...
2004-12-19 19:17:43 +00:00
const int firstLine = _scrollPos / _lineHeight ;
2004-12-20 22:54:20 +00:00
const int lastLine = MIN ( ( _scrollPos + _h ) / _lineHeight + 1 , ( uint32 ) _lines . size ( ) ) ;
2006-05-27 14:41:15 +00:00
// FIXME: There's some confusion here about the meaning of 'yOff'.
// The setDrawArea call above makes it possible to render text
// vertically from _y to _y+_h, while the line below assumes text
// is drawn from _y+yOff down. This causes leftover pixels
// the top while scrolling.
2005-05-17 23:41:35 +00:00
int y = _y + yOff - ( _scrollPos % _lineHeight ) ;
2004-12-19 19:17:43 +00:00
for ( int line = firstLine ; line < lastLine ; line + + ) {
const char * str = _lines [ line ] . c_str ( ) ;
2006-06-05 12:22:51 +00:00
Theme : : TextAlign align = Theme : : kTextAlignCenter ;
Theme : : State state = Theme : : kStateEnabled ;
2004-12-19 19:17:43 +00:00
while ( str [ 0 ] = = ' \\ ' ) {
switch ( str [ 1 ] ) {
case ' C ' :
2006-01-27 15:43:23 +00:00
align = Theme : : kTextAlignCenter ;
2004-12-19 19:17:43 +00:00
break ;
case ' L ' :
2006-01-27 15:43:23 +00:00
align = Theme : : kTextAlignLeft ;
2004-12-19 19:17:43 +00:00
break ;
case ' R ' :
2006-01-27 15:43:23 +00:00
align = Theme : : kTextAlignRight ;
2004-12-19 19:17:43 +00:00
break ;
case ' c ' :
switch ( str [ 2 ] ) {
case ' 0 ' :
2006-01-27 15:43:23 +00:00
state = Theme : : kStateEnabled ;
2004-12-19 19:17:43 +00:00
break ;
case ' 1 ' :
2006-01-27 15:43:23 +00:00
state = Theme : : kStateHighlight ;
2004-12-19 19:17:43 +00:00
break ;
case ' 2 ' :
2006-01-27 15:43:23 +00:00
state = Theme : : kStateDisabled ;
2004-12-19 19:17:43 +00:00
break ;
case ' 3 ' :
2006-01-27 15:43:23 +00:00
warning ( " Need state for color 3 " ) ;
// color = g_gui._shadowcolor;
2004-12-19 19:17:43 +00:00
break ;
case ' 4 ' :
2006-01-27 15:43:23 +00:00
warning ( " Need state for color 4 " ) ;
// color = g_gui._bgcolor;
2004-12-19 19:17:43 +00:00
break ;
default :
2005-05-17 23:41:35 +00:00
error ( " Unknown color type '%c' " , str [ 2 ] ) ;
2004-12-19 19:17:43 +00:00
}
str + + ;
break ;
default :
2005-05-17 23:41:35 +00:00
error ( " Unknown scroller opcode '%c' \n " , str [ 1 ] ) ;
2004-12-19 19:17:43 +00:00
break ;
}
str + = 2 ;
}
// Trim leading whitespaces if center mode is on
2006-01-27 15:43:23 +00:00
if ( align = = Theme : : kTextAlignCenter )
2004-12-19 19:17:43 +00:00
while ( * str & & * str = = ' ' )
str + + ;
2005-07-30 21:11:48 +00:00
2006-01-29 16:12:59 +00:00
g_gui . theme ( ) - > drawText ( Common : : Rect ( _x + xOff , y , _x + _w - xOff , y + g_gui . theme ( ) - > getFontHeight ( ) ) , str , state , align , false , 0 , false ) ;
2004-12-19 19:17:43 +00:00
y + = _lineHeight ;
}
2006-01-27 15:43:23 +00:00
g_gui . theme ( ) - > resetDrawArea ( ) ;
2003-07-22 16:05:51 +00:00
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : handleTickle ( ) {
2005-01-10 22:06:49 +00:00
const uint32 t = getMillis ( ) ;
2004-12-19 19:17:43 +00:00
int scrollOffset = ( ( int ) t - ( int ) _scrollTime ) / kScrollMillisPerPixel ;
if ( scrollOffset > 0 ) {
2004-12-30 14:21:16 +00:00
// Scroll faster when shift is pressed
if ( _modifiers & OSystem : : KBD_SHIFT )
scrollOffset * = 4 ;
// Reverse scrolling when alt is pressed
if ( _modifiers & OSystem : : KBD_ALT )
scrollOffset * = - 1 ;
2004-12-19 19:17:43 +00:00
_scrollPos + = scrollOffset ;
_scrollTime = t ;
if ( _scrollPos < 0 ) {
_scrollPos = 0 ;
} else if ( ( uint32 ) _scrollPos > _lines . size ( ) * _lineHeight ) {
_scrollPos = 0 ;
_scrollTime + = kScrollStartDelay ;
}
2005-04-16 11:40:15 +00:00
drawDialog ( ) ;
2004-12-19 19:17:43 +00:00
}
}
void AboutDialog : : handleMouseUp ( int x , int y , int button , int clickCount ) {
// Close upon any mouse click
close ( ) ;
}
void AboutDialog : : handleKeyDown ( uint16 ascii , int keycode , int modifiers ) {
2004-12-30 14:21:16 +00:00
_modifiers = modifiers ;
2004-12-30 14:55:20 +00:00
if ( ascii )
_willClose = true ;
2004-12-19 19:17:43 +00:00
}
void AboutDialog : : handleKeyUp ( uint16 ascii , int keycode , int modifiers ) {
2004-12-30 14:21:16 +00:00
_modifiers = modifiers ;
2004-12-30 14:55:20 +00:00
if ( ascii & & _willClose )
2004-12-30 14:21:16 +00:00
close ( ) ;
2004-12-19 19:17:43 +00:00
}
2006-04-19 01:05:28 +00:00
void AboutDialog : : handleScreenChanged ( ) {
Dialog : : handleScreenChanged ( ) ;
const int screenW = g_system - > getOverlayWidth ( ) ;
const int screenH = g_system - > getOverlayHeight ( ) ;
xOff = g_gui . evaluator ( ) - > getVar ( " aboutXOff " ) ;
yOff = g_gui . evaluator ( ) - > getVar ( " aboutYOff " ) ;
int outerBorder = g_gui . evaluator ( ) - > getVar ( " aboutOuterBorder " ) ;
_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 ;
for ( int i = 0 ; i < ARRAYSIZE ( credits ) ; i + + ) {
int tmp = g_gui . getStringWidth ( credits [ i ] + 5 ) ;
if ( _w < tmp & & tmp < = maxW ) {
_w = tmp ;
}
}
_w + = 2 * xOff ;
_lineHeight = g_gui . getFontHeight ( ) + 3 ;
_x = ( screenW - _w ) / 2 ;
_y = ( screenH - _h ) / 2 ;
}
2003-11-10 23:40:48 +00:00
} // End of namespace GUI