2003-07-22 16:05:51 +00:00
/* ScummVM - Scumm Interpreter
2005-01-01 16:09:25 +00:00
* Copyright ( C ) 2002 - 2005 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
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* $ Header $
*/
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"
# 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-05-17 23:41:35 +00:00
kScrollMillisPerPixel = 80
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).
2004-12-22 01:07:13 +00:00
static const char * credits_intro [ ] = {
2005-01-01 16:09:25 +00:00
" \\ C " " Copyright (C) 2002-2005 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 " ,
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-05-17 23:41:35 +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 ) {
2004-12-19 19:17:43 +00:00
int i ;
2004-02-09 01:27:27 +00:00
2005-05-17 21:40:29 +00:00
const int screenW = g_system - > getOverlayWidth ( ) ;
const int screenH = g_system - > getOverlayHeight ( ) ;
2005-05-11 19:31:23 +00:00
2005-05-17 23:41:35 +00:00
int outerBorder ;
if ( screenW > = 400 & & screenH > = 300 ) {
xOff = 8 ;
yOff = 5 ;
outerBorder = 80 ;
2005-05-17 21:40:29 +00:00
} else {
2005-05-17 23:41:35 +00:00
xOff = 3 ;
yOff = 2 ;
outerBorder = 10 ;
2005-05-17 21:40:29 +00:00
}
2005-05-17 23:41:35 +00:00
_w = screenW - 2 * outerBorder ;
_h = screenH - 2 * outerBorder ;
2005-05-11 19:31:23 +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 ( " " ) ;
2004-02-09 01:27:27 +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 ] ) ;
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 ;
}
}
if ( * str = = 0 ) {
_lines . push_back ( format ) ;
} else {
Common : : StringList wrappedLines ;
2005-06-03 12:07:53 +00:00
g_gui . getFont ( ) . wordWrapText ( str , _w - 2 * xOff , wrappedLines ) ;
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 ;
2005-04-16 11:40:15 +00:00
_canvas . pixels = NULL ;
2004-12-19 19:17:43 +00:00
Dialog : : open ( ) ;
}
2005-04-16 11:40:15 +00:00
void AboutDialog : : close ( ) {
free ( _canvas . pixels ) ;
Dialog : : close ( ) ;
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : drawDialog ( ) {
2005-04-16 11:40:15 +00:00
if ( ! _canvas . pixels ) {
// Blend over the background. Since we can't afford to do that
// every time the text is updated (it's horribly CPU intensive)
// we do it just once and then use a copy of the result as our
// static background for the remainder of the credits.
g_gui . blendRect ( _x , _y , _w , _h , g_gui . _bgcolor ) ;
g_gui . copyToSurface ( & _canvas , _x , _y , _w , _h ) ;
}
g_gui . drawSurface ( _canvas , _x , _y ) ;
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 ( ) ) ;
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 ( ) ;
Graphics : : TextAlignment align = Graphics : : kTextAlignCenter ;
OverlayColor color = g_gui . _textcolor ;
while ( str [ 0 ] = = ' \\ ' ) {
switch ( str [ 1 ] ) {
case ' C ' :
align = Graphics : : kTextAlignCenter ;
break ;
case ' L ' :
align = Graphics : : kTextAlignLeft ;
break ;
case ' R ' :
align = Graphics : : kTextAlignRight ;
break ;
case ' c ' :
switch ( str [ 2 ] ) {
case ' 0 ' :
color = g_gui . _textcolor ;
break ;
case ' 1 ' :
color = g_gui . _textcolorhi ;
break ;
case ' 2 ' :
color = g_gui . _color ;
break ;
case ' 3 ' :
color = g_gui . _shadowcolor ;
break ;
case ' 4 ' :
color = g_gui . _bgcolor ;
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
if ( align = = Graphics : : kTextAlignCenter )
while ( * str & & * str = = ' ' )
str + + ;
2004-02-09 01:27:27 +00:00
2005-06-03 12:07:53 +00:00
g_gui . drawString ( str , _x + xOff , y , _w - 2 * xOff , color , align , 0 , false ) ;
2004-12-19 19:17:43 +00:00
y + = _lineHeight ;
}
// Draw a border
g_gui . box ( _x , _y , _w , _h , g_gui . _color , g_gui . _shadowcolor ) ;
// Finally blit it all to the screen
g_gui . addDirtyRect ( _x , _y , _w , _h ) ;
2003-07-22 16:05:51 +00:00
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : handleTickle ( ) {
2005-04-16 16:29:11 +00:00
// We're in the process of doing a full redraw to re-create the
// background image for the text. That means we need to wait for the
// GUI itself to clear the overlay and call drawDialog() in all of the
// dialogs, otherwise we'll only redraw this one and it'll still have
// the remains of the old image, including the text that was on it.
2005-04-16 13:09:34 +00:00
if ( ! _canvas . pixels )
2005-04-16 12:41:43 +00:00
return ;
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
}
}
2005-04-16 11:40:15 +00:00
void AboutDialog : : handleScreenChanged ( ) {
2005-04-16 16:56:16 +00:00
// The screen has changed. That means the overlay colors in the canvas
// may no longer be correct. Reset it, and issue a full redraw.
// TODO: We could check if the bit format has changed, like we do in
// the MPEG player.
2005-04-16 11:40:15 +00:00
free ( _canvas . pixels ) ;
_canvas . pixels = NULL ;
2005-04-16 12:41:43 +00:00
draw ( ) ;
2005-04-16 11:40:15 +00:00
}
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
}
2003-11-10 23:40:48 +00:00
} // End of namespace GUI