2007-05-30 21:56:52 +00:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
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 .
2014-02-18 02:34:20 +01:00
*
2003-07-22 16:05:51 +00:00
*/
2008-05-13 09:30:23 +00:00
# include "engines/metaengine.h"
2006-07-31 13:41:21 +00:00
# include "base/plugins.h"
2004-02-09 01:27:27 +00:00
# include "base/version.h"
2007-03-17 16:05:16 +00:00
# include "common/events.h"
2005-01-10 22:06:49 +00:00
# include "common/system.h"
2010-06-15 10:44:51 +00:00
# include "common/translation.h"
2005-01-10 22:35:43 +00:00
# include "common/util.h"
2021-04-18 02:31:09 +01:00
# include "graphics/conversion.h"
2021-04-15 23:43:45 +02:00
# include "graphics/surface.h"
2021-04-15 18:31:14 +02:00
# include "graphics/fonts/amigafont.h"
2003-11-02 14:50:53 +00:00
# include "gui/about.h"
2010-11-16 10:19:01 +00:00
# include "gui/gui-manager.h"
2008-08-08 21:52:16 +00:00
# include "gui/ThemeEval.h"
2003-11-10 23:40:48 +00:00
namespace GUI {
2019-10-07 00:11:48 +02:00
class EE ;
class EEHandler {
public :
bool handleKeyDown ( Common : : KeyState & state ) ;
} ;
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
} ;
2013-02-04 13:16:38 +00: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-14 19:01:47 +02:00
// 2 disabled text
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...
2007-06-13 20:37:24 +00:00
static const char * copyright_text [ ] = {
2008-11-20 13:46:34 +00:00
" " ,
2021-01-01 00:00:18 +01:00
" C0 " " Copyright (C) 2001-2021 The ScummVM Team " ,
2019-03-09 19:26:59 +00:00
" C0 " " https://www.scummvm.org " ,
2008-11-20 13:46:34 +00:00
" " ,
" C0 " " ScummVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the COPYRIGHT file distributed with this binary. " ,
" " ,
2007-06-13 20:37:24 +00:00
} ;
2006-07-31 13:41:21 +00:00
static const char * gpl_text [ ] = {
2008-11-20 13:46:34 +00:00
" " ,
" 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. " ,
" " ,
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 ) ,
2007-03-17 16:05:16 +00:00
_scrollPos ( 0 ) , _scrollTime ( 0 ) , _willClose ( false ) {
2005-07-30 21:11:48 +00:00
2010-05-27 20:29:39 +00:00
reflowLayout ( ) ;
2004-12-19 19:17:43 +00:00
int i ;
2005-07-30 21:11:48 +00:00
2004-12-19 19:17:43 +00:00
for ( i = 0 ; i < 1 ; i + + )
2020-11-15 18:15:58 +00:00
_lines . push_back ( U32String ( ) ) ;
2004-12-19 19:17:43 +00:00
2008-11-20 13:46:34 +00:00
Common : : String version ( " 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
2020-06-30 03:40:13 +05:30
Common : : U32String date = Common : : U32String : : format ( _ ( " (built on %s) " ) , gScummVMBuildDate ) ;
_lines . push_back ( U32String ( " C2 " ) + date ) ;
2003-07-22 16:05:51 +00:00
2007-06-13 20:37:24 +00:00
for ( i = 0 ; i < ARRAYSIZE ( copyright_text ) ; i + + )
2020-06-15 01:00:55 +05:30
addLine ( U32String ( copyright_text [ i ] ) ) ;
2006-07-31 13:41:21 +00:00
2020-06-15 01:00:55 +05:30
Common : : U32String features ( " C1 " ) ;
features + = _ ( " Features compiled in: " ) ;
addLine ( features ) ;
2010-06-26 15:48:03 +00:00
Common : : String featureList ( " C0 " ) ;
featureList + = gScummVMFeatures ;
2020-06-15 01:00:55 +05:30
addLine ( featureList ) ;
2004-12-19 19:17:43 +00:00
2020-11-15 18:15:58 +00:00
_lines . push_back ( U32String ( ) ) ;
2005-07-30 21:11:48 +00:00
2020-06-15 01:00:55 +05:30
Common : : U32String engines ( " C1 " ) ;
engines + = _ ( " Available engines: " ) ;
addLine ( engines ) ;
2010-06-26 15:48:03 +00:00
2021-04-14 14:42:10 +02:00
const PluginList & plugins = EngineMan . getPlugins ( PLUGIN_TYPE_ENGINE ) ;
2017-11-10 23:06:42 -06:00
PluginList : : const_iterator iter = plugins . begin ( ) ;
2006-07-31 13:41:21 +00:00
for ( ; iter ! = plugins . end ( ) ; + + iter ) {
2012-12-20 07:55:08 +01:00
Common : : String str ;
str = " C0 " ;
2017-11-10 23:06:42 -06:00
str + = ( * iter ) - > getName ( ) ;
2020-06-15 01:00:55 +05:30
addLine ( str ) ;
2006-07-31 13:41:21 +00:00
2021-04-14 14:42:10 +02:00
const Plugin * p = EngineMan . findPlugin ( ( * iter ) - > getName ( ) ) ;
if ( ! p ) {
warning ( " Cannot find plugin for %s " , ( * iter ) - > getName ( ) ) ;
continue ;
}
2012-12-20 07:55:08 +01:00
str = " C2 " ;
2021-04-14 14:42:10 +02:00
str + = p - > get < MetaEngineDetection > ( ) . getOriginalCopyright ( ) ;
2020-06-15 01:00:55 +05:30
addLine ( str ) ;
2006-07-31 13:41:21 +00:00
2012-12-20 07:55:08 +01:00
//addLine("");
2006-07-31 13:41:21 +00:00
}
2007-06-13 20:37:24 +00:00
for ( i = 0 ; i < ARRAYSIZE ( gpl_text ) ; i + + )
2020-06-15 01:00:55 +05:30
addLine ( U32String ( gpl_text [ i ] ) ) ;
2007-06-13 20:37:24 +00:00
2020-11-15 18:15:58 +00:00
_lines . push_back ( U32String ( ) ) ;
2005-07-30 21:11:48 +00:00
2004-12-22 01:07:13 +00:00
for ( i = 0 ; i < ARRAYSIZE ( credits ) ; i + + )
2021-04-18 01:30:38 +01:00
addLine ( U32String ( credits [ i ] , Common : : kUtf8 ) ) ;
2004-12-19 19:17:43 +00:00
}
2020-06-15 01:00:55 +05:30
void AboutDialog : : addLine ( const U32String & str ) {
U32String : : const_iterator strBeginItr = str . begin ( ) ;
if ( * strBeginItr = = 0 ) {
2020-11-15 18:15:58 +00:00
_lines . push_back ( U32String ( ) ) ;
2005-05-17 23:41:35 +00:00
} else {
GUI: U32: Downscale changes of U32, fix review issues
This commit addresses a range of changes, within scummvm subproject.
- Audio files, like mididrv, remove U32String based name and identifier, because ASCII only.
- mididrv.cpp had some wrong format for warning messages, fix those
- Message dialogs were modified to use default arguments more often, but reverting back to the orignal to minimize changes.
- SetTooltip has a fake constructor that takes in a string, and use it.
- U32Format had some break statements missing, add those.
- RemapWidget: Use fake constructor for setLabel and setTooltip, to make minimal changes
- SDL: setting text in clipboard no longer uses SDL_iconv_string
- TTS: Override base class "say" with strings, so tts->say can be used with normal strings too.
- About dialog: fix incorrect code for u32string variables
- Fix some extra brackets
- Some buttons were incorrectly removed from using translated labels, revert those
- Message Dialog: Pass default and alt buttons as const references
- Saveload Dialog: Use translations in missing places, use const-references. Also, use translations in a correct manner.
- Use const references for tooltip in GraphicsWidget, EditTextWidget, error.cpp
- DomainEditTextWidget: Use U32String for text
2020-07-20 18:06:37 +05:30
Common : : U32String format ( str . begin ( ) , str . begin ( ) + 2 ) ;
2020-06-15 01:00:55 +05:30
strBeginItr + = 2 ;
U32String renderStr ( strBeginItr , str . end ( ) ) ;
2013-07-14 19:01:47 +02:00
2020-06-15 01:00:55 +05:30
U32StringArray wrappedLines ;
2020-06-29 00:21:15 +05:30
g_gui . getFont ( ) . wordWrapText ( renderStr , _w - 2 * _xOff , wrappedLines ) ;
2005-07-30 21:11:48 +00:00
2020-06-15 01:00:55 +05:30
for ( U32StringArray : : const_iterator i = wrappedLines . begin ( ) ; i ! = wrappedLines . end ( ) ; + + i ) {
2005-05-17 23:41:35 +00:00
_lines . push_back ( format + * i ) ;
}
}
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : open ( ) {
2010-03-11 23:41:28 +00:00
_scrollTime = g_system - > getMillis ( ) + kScrollStartDelay ;
2004-12-19 19:17:43 +00:00
_scrollPos = 0 ;
2004-12-30 14:55:20 +00:00
_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 ( ) ;
}
2018-01-07 10:39:22 +01:00
void AboutDialog : : drawDialog ( DrawLayer layerToDraw ) {
Dialog : : drawDialog ( layerToDraw ) ;
2004-12-19 19:17:43 +00:00
2013-06-13 12:32:36 +00:00
setTextDrawableArea ( Common : : Rect ( _x , _y , _x + _w , _y + _h ) ) ;
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 ( ) ) ;
2007-03-17 15:52:35 +00:00
int y = _y + _yOff - ( _scrollPos % _lineHeight ) ;
2004-12-19 19:17:43 +00:00
for ( int line = firstLine ; line < lastLine ; line + + ) {
2020-06-15 01:00:55 +05:30
U32String str = _lines [ line ] ;
U32String : : const_iterator strLineItrBegin = _lines [ line ] . begin ( ) ;
U32String : : const_iterator strLineItrEnd = _lines [ line ] . end ( ) ;
2008-11-12 14:30:16 +00:00
Graphics : : TextAlign align = Graphics : : kTextAlignCenter ;
2008-11-10 11:24:55 +00:00
ThemeEngine : : WidgetStateInfo state = ThemeEngine : : kStateEnabled ;
2020-06-20 23:35:02 +05:30
if ( strLineItrBegin ! = strLineItrEnd ) {
2020-06-15 01:00:55 +05:30
switch ( * strLineItrBegin ) {
2004-12-19 19:17:43 +00:00
case ' C ' :
2008-11-12 14:30:16 +00:00
align = Graphics : : kTextAlignCenter ;
2004-12-19 19:17:43 +00:00
break ;
case ' L ' :
2008-11-12 14:30:16 +00:00
align = Graphics : : kTextAlignLeft ;
2004-12-19 19:17:43 +00:00
break ;
case ' R ' :
2008-11-12 14:30:16 +00:00
align = Graphics : : kTextAlignRight ;
2004-12-19 19:17:43 +00:00
break ;
default :
2008-11-20 13:46:34 +00:00
error ( " Unknown scroller opcode '%c' " , str [ 0 ] ) ;
2004-12-19 19:17:43 +00:00
break ;
}
2020-06-15 01:00:55 +05:30
switch ( * ( strLineItrBegin + 1 ) ) {
2008-11-20 13:46:34 +00:00
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 ] ) ;
}
2020-06-15 01:00:55 +05:30
strLineItrBegin + = 2 ;
2004-12-19 19:17:43 +00:00
}
// Trim leading whitespaces if center mode is on
2008-11-12 14:30:16 +00:00
if ( align = = Graphics : : kTextAlignCenter )
2020-06-30 03:40:13 +05:30
while ( strLineItrBegin ! = strLineItrEnd & & * strLineItrBegin = = ' ' )
2020-06-15 01:00:55 +05:30
strLineItrBegin + + ;
2005-07-30 21:11:48 +00:00
2020-06-15 01:00:55 +05:30
U32String renderStr ( strLineItrBegin , strLineItrEnd ) ;
if ( ! renderStr . empty ( ) )
2018-01-27 08:59:53 +01:00
g_gui . theme ( ) - > drawText ( Common : : Rect ( _x + _xOff , y , _x + _w - _xOff , y + g_gui . theme ( ) - > getFontHeight ( ) ) ,
2020-08-21 18:38:02 +05:30
renderStr , state , align , ThemeEngine : : kTextInversionNone , 0 , false ,
2018-01-27 08:59:53 +01:00
ThemeEngine : : kFontStyleBold , ThemeEngine : : kFontColorNormal , true , _textDrawableArea ) ;
2004-12-19 19:17:43 +00:00
y + = _lineHeight ;
}
2003-07-22 16:05:51 +00:00
}
2004-12-19 19:17:43 +00:00
void AboutDialog : : handleTickle ( ) {
2010-03-11 23:41:28 +00:00
const uint32 t = g_system - > getMillis ( ) ;
2004-12-19 19:17:43 +00:00
int scrollOffset = ( ( int ) t - ( int ) _scrollTime ) / kScrollMillisPerPixel ;
if ( scrollOffset > 0 ) {
2007-03-17 16:05:16 +00:00
int modifiers = g_system - > getEventManager ( ) - > getModifierState ( ) ;
2004-12-30 14:21:16 +00:00
// Scroll faster when shift is pressed
2007-03-17 19:02:05 +00:00
if ( modifiers & Common : : KBD_SHIFT )
2004-12-30 14:21:16 +00:00
scrollOffset * = 4 ;
// Reverse scrolling when alt is pressed
2007-03-17 19:02:05 +00:00
if ( modifiers & Common : : KBD_ALT )
2004-12-30 14:21:16 +00:00
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 ;
}
2018-01-07 10:39:22 +01:00
drawDialog ( kDrawLayerForeground ) ;
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 ( ) ;
}
2007-06-30 12:26:59 +00:00
void AboutDialog : : handleKeyDown ( Common : : KeyState state ) {
2019-11-10 14:50:18 +01:00
EEHandler eeHandler ;
if ( eeHandler . handleKeyDown ( state ) ) {
2019-10-07 00:11:48 +02:00
reflowLayout ( ) ;
return ;
}
2007-06-30 12:26:59 +00:00
if ( state . ascii )
2004-12-30 14:55:20 +00:00
_willClose = true ;
2004-12-19 19:17:43 +00:00
}
2007-06-30 12:26:59 +00:00
void AboutDialog : : handleKeyUp ( Common : : KeyState state ) {
if ( state . ascii & & _willClose )
2004-12-30 14:21:16 +00:00
close ( ) ;
2004-12-19 19:17:43 +00:00
}
2006-08-04 13:55:53 +00:00
void AboutDialog : : reflowLayout ( ) {
Dialog : : reflowLayout ( ) ;
2010-05-27 19:34:12 +00:00
int i ;
2006-04-19 01:05:28 +00:00
const int screenW = g_system - > getOverlayWidth ( ) ;
const int screenH = g_system - > getOverlayHeight ( ) ;
2008-08-08 21:52:16 +00:00
_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 " ) ;
2006-04-19 01:05:28 +00:00
_w = screenW - 2 * outerBorder ;
_h = screenH - 2 * outerBorder ;
_lineHeight = g_gui . getFontHeight ( ) + 3 ;
// Heuristic to compute 'optimal' dialog width
2007-03-17 15:52:35 +00:00
int maxW = _w - 2 * _xOff ;
2006-04-19 01:05:28 +00:00
_w = 0 ;
2010-05-27 19:34:12 +00:00
for ( i = 0 ; i < ARRAYSIZE ( credits ) ; i + + ) {
2013-02-04 13:16:38 +00:00
int tmp = g_gui . getStringWidth ( credits [ i ] ) + 5 ;
2009-09-30 16:16:53 +00:00
if ( _w < tmp & & tmp < = maxW ) {
2006-04-19 01:05:28 +00:00
_w = tmp ;
}
}
2007-03-17 15:52:35 +00:00
_w + = 2 * _xOff ;
2006-04-19 01:05:28 +00:00
2010-05-27 19:34:12 +00:00
// Center the dialog
2006-04-19 01:05:28 +00:00
_x = ( screenW - _w ) / 2 ;
_y = ( screenH - _h ) / 2 ;
}
2019-10-07 00:11:48 +02:00
////////////////////////////////
//// Here we go
////////////////////////////////
enum {
kDirUp , kDirLeft , kDirRight
} ;
enum {
kModeMenu , kModePlay , kModePause
} ;
enum { kPlComp , kPlHuman } ;
enum { kSndPoint , kSndHit , kSndLoss } ;
2021-04-15 23:06:18 +02:00
enum {
kSpL1 , kSpL2 , kSpL3 ,
kSpR1 , kSpR2 , kSpR3 ,
kSpB1 , kSpB2 , kSpB3 , kSpB4 ,
kSp0 , kSp1 , kSp2 , kSp3 , kSp4 ,
kSp5 , kSp6 , kSp7 , kSp8 , kSp9 ,
kSpCode1 ,
kSpCode1h = kSpCode1 + 6 ,
kSpNum0 = kSpCode1h + 6 ,
kSpStar = kSpNum0 + 10 ,
kSpSpace ,
kSpLast
} ;
2019-10-07 00:11:48 +02:00
class EE {
public :
EE ( ) ;
~ EE ( ) ;
void run ( ) ;
private :
2021-04-15 23:43:45 +02:00
Graphics : : Surface _back ;
2019-10-07 00:11:48 +02:00
int _hits ;
bool _rmode ; // animation after loosing
int _score [ 2 ] ;
bool _soundEnabled ;
bool _shouldQuit ;
int _rcnt ; //last 20 cycles of round
int _winner ; //who wins the point or serving
int _tvelx , _tvely ;
int _x [ 2 ] , _y [ 2 ] , _px [ 2 ] ;
int _frame [ 2 ] , _frameindex [ 2 ] ;
int _rebound [ 2 ] ;
int _bx , _by , _pbx , _pby , _tbx , _tby , _bvelx , _bvely ;
int _serve , _server , _servevel , _compserve ;
int _hitter , _starter , _sstage ;
int _bytop ;
int _rnd ;
int _olx , _oly , _orx , _ory , _obx , _oby ;
bool _air ;
bool _oCoords ;
int _mode ;
int _keymove [ 2 ] [ 3 ] ;
int _opts ;
int _opt ;
2021-04-15 18:31:14 +02:00
Graphics : : AmigaFont _font ;
2021-04-15 23:06:18 +02:00
Graphics : : Surface _sp [ kSpLast ] ;
2019-10-07 00:11:48 +02:00
Graphics : : PixelFormat _format ;
2021-04-15 23:06:18 +02:00
int _windowX , _windowY , _windowW , _windowH ;
float _scale ;
bool _inited ;
2019-10-07 00:11:48 +02:00
2021-04-18 02:31:09 +01:00
uint32 _colorBlack , _colorBlue , _colorOrange , _colorKey ;
2019-10-07 00:11:48 +02:00
void cls ( bool update = true ) ;
void loadSounds ( ) ;
void processKeyUp ( Common : : Event & e ) ;
void processKeyDown ( Common : : Event & e ) ;
void getPos ( ) ;
void setwinner ( ) ;
void resetpt ( ) ;
void calcscore ( ) ;
int destination ( int pl , int destx , int tol ) ;
bool moveball ( ) ;
void docollisions ( ) ;
void computer0 ( ) ;
void computer1 ( ) ;
void init ( ) ;
void draw ( int sn , int x , int y ) ;
void doMenu ( Common : : Event & e ) ;
void putshapes ( ) ;
void game ( ) ;
void playSound ( int d ) ;
2021-04-18 10:28:18 +01:00
void setupGraphics ( ) ;
2021-04-15 23:43:45 +02:00
void genField ( ) ;
2019-10-07 00:11:48 +02:00
} ;
bool EEHandler : : handleKeyDown ( Common : : KeyState & state ) {
if ( state . ascii = = ' v ' ) {
2019-11-10 14:50:18 +01:00
EE * ee = new EE ( ) ;
ee - > run ( ) ;
delete ee ;
2019-10-07 00:11:48 +02:00
g_gui . redrawFull ( ) ;
return true ;
}
return false ;
}
EE : : EE ( ) {
init ( ) ;
2021-04-30 15:41:37 +02:00
_scale = 1.0 ;
_windowW = 320 ;
_windowH = 200 ;
_windowX = _windowY = 0 ;
_format = g_system - > getOverlayFormat ( ) ;
_colorBlack = _colorBlue = _colorOrange = _colorKey = 0 ;
2019-10-07 00:11:48 +02:00
}
EE : : ~ EE ( ) {
2021-04-15 23:06:18 +02:00
for ( int i = 0 ; i < kSpLast ; i + + )
_sp [ i ] . free ( ) ;
2019-10-07 00:11:48 +02:00
}
void EE : : cls ( bool update ) {
2021-04-18 02:31:09 +01:00
_back . fillRect ( Common : : Rect ( 0 , 0 , _windowW , _windowH ) , _colorBlack ) ;
2019-10-07 00:11:48 +02:00
if ( update )
2021-04-15 23:06:18 +02:00
g_system - > copyRectToOverlay ( _back . getPixels ( ) , _back . pitch , _windowX , _windowY , _windowW , _windowH ) ;
2019-10-07 00:11:48 +02:00
}
void EE : : run ( ) {
2021-04-15 23:06:18 +02:00
if ( ! _inited )
return ;
2019-10-07 00:11:48 +02:00
_shouldQuit = false ;
2021-04-18 10:28:18 +01:00
setupGraphics ( ) ;
2019-10-07 00:11:48 +02:00
init ( ) ;
while ( ! _shouldQuit ) {
Common : : Event event ;
while ( g_system - > getEventManager ( ) - > pollEvent ( event ) ) {
switch ( event . type ) {
case Common : : EVENT_QUIT :
2020-05-10 18:49:46 -04:00
case Common : : EVENT_RETURN_TO_LAUNCHER :
2019-10-07 00:11:48 +02:00
_shouldQuit = true ;
break ;
2021-04-18 10:28:18 +01:00
case Common : : EVENT_SCREEN_CHANGED :
if ( g_gui . checkScreenChange ( ) )
setupGraphics ( ) ;
break ;
2019-10-07 00:11:48 +02:00
case Common : : EVENT_LBUTTONDOWN :
break ;
case Common : : EVENT_KEYDOWN :
processKeyDown ( event ) ;
break ;
case Common : : EVENT_KEYUP :
processKeyUp ( event ) ;
break ;
default :
break ;
}
}
game ( ) ;
putshapes ( ) ;
g_system - > updateScreen ( ) ;
g_system - > delayMillis ( 10 ) ;
}
}
const int polecol [ ] = { 0 , 1 , 2 , 3 , 3 , 4 , 6 , 7 , 9 , 14 } ;
const int jump [ ] = { - 4 , - 4 , - 3 , - 3 , - 3 , - 3 , - 2 , - 2 , - 2 , - 2 , - 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 0 , 0 ,
0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 } ;
void EE : : loadSounds ( ) {
#if 0
if ( $ . isEmptyObject ( sounds ) ) {
for ( i = 0 ; i < snNames . length ; i + + ) {
s = snNames [ i ] ;
sounds [ s ] = new Audio ( ) ;
sounds [ s ] . src = ' sounds / ' + s + ' . wav ' ;
}
}
# endif
}
void EE : : processKeyUp ( Common : : Event & e ) {
switch ( e . kbd . keycode ) {
case Common : : KEYCODE_LEFT : // left
_keymove [ 1 ] [ kDirLeft ] = 0 ;
break ;
case Common : : KEYCODE_RIGHT : // right
_keymove [ 1 ] [ kDirRight ] = 0 ;
break ;
case Common : : KEYCODE_UP : // top
_keymove [ 1 ] [ kDirUp ] = 0 ;
break ;
case Common : : KEYCODE_a : //a
_keymove [ 0 ] [ kDirLeft ] = 0 ;
break ;
case Common : : KEYCODE_d : // d
_keymove [ 0 ] [ kDirRight ] = 0 ;
break ;
case Common : : KEYCODE_w : // w
_keymove [ 0 ] [ kDirUp ] = 0 ;
break ;
default :
break ;
}
}
void EE : : processKeyDown ( Common : : Event & e ) {
if ( _mode = = kModeMenu ) {
doMenu ( e ) ;
return ;
}
switch ( e . kbd . keycode ) {
case Common : : KEYCODE_LEFT : // left
_keymove [ 1 ] [ kDirLeft ] = - 2 ;
break ;
case Common : : KEYCODE_RIGHT : // right
_keymove [ 1 ] [ kDirRight ] = 2 ;
break ;
case Common : : KEYCODE_UP : // top
_keymove [ 1 ] [ kDirUp ] = 1 ;
break ;
case Common : : KEYCODE_a : //a
_keymove [ 0 ] [ kDirLeft ] = - 2 ;
break ;
case Common : : KEYCODE_d : // d
_keymove [ 0 ] [ kDirRight ] = 2 ;
break ;
case Common : : KEYCODE_w : // w
_keymove [ 0 ] [ kDirUp ] = 1 ;
break ;
case Common : : KEYCODE_ESCAPE :
_mode = kModeMenu ;
break ;
case Common : : KEYCODE_p : // p
_keymove [ 0 ] [ kDirRight ] = _keymove [ 0 ] [ kDirLeft ] = _keymove [ 0 ] [ kDirUp ] = 0 ;
_mode = ( _mode = = kModePlay ) ? kModePause : kModePlay ;
break ;
case Common : : KEYCODE_r : // r
if ( _mode = = kModePlay )
init ( ) ;
break ;
case Common : : KEYCODE_s : // s
if ( ! _soundEnabled )
loadSounds ( ) ;
_soundEnabled = ! _soundEnabled ;
break ;
default :
break ;
}
}
void EE : : getPos ( ) {
for ( int i = 0 ; i < 2 ; i + + ) {
if ( _keymove [ i ] [ kDirUp ] & & _frameindex [ i ] = = - 1 )
_frameindex [ i ] = 0 ;
2020-07-15 23:29:52 +02:00
int velx = _keymove [ i ] [ kDirLeft ] + _keymove [ i ] [ kDirRight ] ;
int tx = _x [ i ] + velx ;
int bnd = 3 + i * 155 ;
2019-10-07 00:11:48 +02:00
if ( velx > 0 ) {
if ( tx < bnd + 119 )
_x [ i ] = tx ;
else
_x [ i ] = bnd + 119 ;
} else if ( tx > bnd ) {
_x [ i ] = tx ;
} else {
_x [ i ] = bnd ;
}
if ( _frameindex [ i ] = = - 2 ) {
_y [ i ] = 173 ;
_frame [ i ] = 0 ;
_frameindex [ i ] = - 1 ;
}
if ( _frameindex [ i ] = = - 1 ) {
if ( velx ! = 0 ) {
if ( abs ( _px [ i ] - _x [ i ] ) > 4 ) {
_frame [ i ] ^ = 1 ;
_px [ i ] = _x [ i ] ;
}
} else {
_frame [ i ] = 0 ;
}
} else {
_frame [ i ] = 2 + ( _frameindex [ i ] > 18 ) ;
if ( _frameindex [ i ] = = 19 )
_y [ i ] - = 4 ;
_y [ i ] + = jump [ _frameindex [ i ] + + ] ;
if ( _frameindex [ i ] > 37 )
_frameindex [ i ] = - 2 ;
}
}
}
void EE : : setwinner ( ) {
if ( _hits > 2 ) {
_winner = 1 - _hitter ;
} else {
_winner = _tbx < 150 ? 1 : 0 ;
}
_tvely = abs ( _bvely ) > > 3 ;
_tvelx = abs ( _bvelx ) > > 3 ;
}
void EE : : resetpt ( ) {
_keymove [ 0 ] [ kDirUp ] = 0 ;
_keymove [ 1 ] [ kDirUp ] = 0 ;
getPos ( ) ;
if ( abs ( _bvelx ) > _tvelx ) {
if ( _bvelx < 0 )
_bvelx = - _tvelx ;
else
_bvelx = _tvelx ;
}
if ( abs ( _bvely ) > _tvely ) {
if ( _bvely < 0 )
_bvely = - _tvely ;
else
_bvely = _tvely ;
}
docollisions ( ) ;
moveball ( ) ;
putshapes ( ) ;
}
void EE : : calcscore ( ) {
if ( _winner = = _server ) {
2019-10-12 10:43:51 +01:00
if ( _soundEnabled & & _mode ! = kModeMenu ) {
2019-10-07 00:11:48 +02:00
playSound ( kSndPoint ) ;
2019-10-12 10:43:51 +01:00
}
_score [ _winner ] + + ;
2019-10-07 00:11:48 +02:00
if ( _score [ _winner ] > 14 & & _score [ _winner ] - _score [ 1 - _winner ] > 1 ) {
init ( ) ;
return ;
}
} else {
2019-10-12 10:43:51 +01:00
if ( _soundEnabled & & _mode ! = kModeMenu ) {
2019-10-07 00:11:48 +02:00
playSound ( kSndLoss ) ;
2019-10-12 10:43:51 +01:00
}
2019-10-07 00:11:48 +02:00
_server = _winner ;
}
_bx = ( _tbx = _pbx = ( 64 + _winner * 165 ) ) < < 6 ;
_by = ( _tby = _pby = 135 ) < < 6 ;
_bvelx = _bvely = _hits = _rebound [ 0 ] = _rebound [ 1 ] = 0 ;
_serve = _servevel = 1 ;
_hitter = 2 ;
_compserve = abs ( _rnd ) % 5 ;
if ( _score [ _server ] = = 14 )
_compserve = 5 ;
_sstage = 0 ;
}
int EE : : destination ( int pl , int destx , int tol ) {
2020-07-15 23:29:52 +02:00
int xp = _x [ pl ] ;
2019-10-07 00:11:48 +02:00
if ( abs ( xp - destx ) < tol ) {
_keymove [ pl ] [ kDirLeft ] = 0 ;
_keymove [ pl ] [ kDirRight ] = 0 ;
return 1 ;
}
if ( xp < destx ) {
_keymove [ pl ] [ kDirLeft ] = 0 ;
_keymove [ pl ] [ kDirRight ] = 2 ;
} else {
_keymove [ pl ] [ kDirLeft ] = - 2 ;
_keymove [ pl ] [ kDirRight ] = 0 ;
}
return 0 ;
}
int reset = false ;
bool EE : : moveball ( ) {
if ( ! reset ) {
_bx = 4096 ; _by = 8640 ; _bvelx = 125 ; _bvely = - 259 ;
reset = true ;
}
2020-07-15 23:29:52 +02:00
int rbvelx = _bvelx ;
int rbvely = _bvely ;
2019-10-07 00:11:48 +02:00
if ( rbvelx > 319 ) rbvelx = 319 ;
if ( rbvelx < - 319 ) rbvelx = - 319 ;
if ( rbvely > 319 ) rbvely = 319 ;
if ( rbvely < - 319 ) rbvely = - 319 ;
_pbx = _tbx ;
_pby = _tby ;
_bx + = rbvelx ;
_by + = rbvely ;
if ( _bx < 320 ) {
_bx = 320 ;
rbvelx = - rbvelx ;
rbvelx - = rbvelx > > 4 ;
rbvely - = rbvely > > 4 ;
if ( _hitter = = 1 ) {
_hitter = 2 ;
_hits = 0 ;
}
}
if ( _bx > 18112 ) {
_bx = 18112 ;
rbvelx = - rbvelx ;
rbvelx - = rbvelx > > 4 ;
rbvely - = rbvely > > 4 ;
if ( _hitter = = 0 ) {
_hitter = 2 ;
_hits = 0 ;
}
}
if ( _by < 832 ) {
_by = 832 ;
rbvely = - rbvely ;
rbvelx - = rbvelx > > 4 ;
rbvely - = rbvely > > 4 ;
}
2020-07-15 23:29:52 +02:00
bool hitfloor ;
2019-10-07 00:11:48 +02:00
if ( _by > 11392 ) {
_by = 11392 ;
rbvely = - rbvely ;
hitfloor = false ;
} else {
hitfloor = true ;
}
2020-04-27 14:38:24 +02:00
//if (rbvely > 0) // Checked with original, this is how it is
// rbvely += 1;
//else
2019-10-07 00:11:48 +02:00
rbvely + = 1 ;
_tbx = _bx > > 6 ;
_tby = _by > > 6 ;
_bvelx = rbvelx ;
_bvely = rbvely ;
return hitfloor ;
}
void EE : : docollisions ( ) {
for ( int i = 0 ; i < 2 ; i + + ) {
2020-07-15 23:29:52 +02:00
int dx = _tbx - _x [ i ] - i * 7 ;
int dy = ( _tby - _y [ i ] ) > > 1 ;
int dist = ( dx > > 2 ) * dx + dy * dy ;
2019-10-07 00:11:48 +02:00
if ( dist < 110 ) {
2020-07-15 23:29:52 +02:00
int rndoff = 8 - ( _rnd & 15 ) ;
2019-10-07 00:11:48 +02:00
if ( _frameindex [ i ] > - 1 )
_bvely = - abs ( _bvely ) + ( jump [ _frameindex [ i ] ] < < ( 3 < < _servevel ) ) ;
else
_bvely = - abs ( _bvely ) ;
_bvely + = rndoff ;
_bvelx + = dx * abs ( dx ) + ( ( _keymove [ i ] [ kDirRight ] + _keymove [ i ] [ kDirLeft ] ) < < ( 4 + _servevel ) ) + rndoff ;
if ( ! _rebound [ i ] ) {
if ( _mode ! = kModeMenu ) {
2019-10-12 10:43:51 +01:00
if ( _soundEnabled & & _mode ! = kModeMenu ) {
2019-10-07 00:11:48 +02:00
playSound ( kSndHit ) ;
}
2019-10-12 10:43:51 +01:00
}
2019-10-07 00:11:48 +02:00
_bytop = 200 ;
_serve = 0 ;
_rebound [ i ] = 1 ;
if ( _hitter ! = i ) {
_hitter = i ;
_hits = 0 ;
2019-10-12 10:43:51 +01:00
} else {
2019-10-07 00:11:48 +02:00
_hits + + ;
2019-10-12 10:43:51 +01:00
}
2019-10-07 00:11:48 +02:00
}
} else if ( _rebound [ i ] ) {
_rebound [ i ] = _servevel = 0 ;
}
}
int i = 1 ;
if ( _tby > 91 ) {
if ( _pbx < 128 & & _tbx > 127 ) {
_bvelx = - abs ( _bvelx ) > > 1 ;
_bx = 127 * 64 ;
i = 0 ;
} else if ( _pbx > 159 & & _tbx < 160 ) {
_bvelx = abs ( _bvelx ) > > 1 ;
_bx = 160 * 64 ;
i = 0 ;
}
}
if ( i & & _tby > 81 & & _tbx > 127 & & _tbx < 160 ) {
if ( _tby > 91 ) {
if ( _tbx < 148 )
_bvelx = - abs ( _bvelx ) ;
else
_bvelx = abs ( _bvelx ) ;
} else if ( ( _tbx > 147 & & 161 - _tbx > = polecol [ 91 - _tby ] ) | |
( _tbx < 148 & & _tbx - 133 > = polecol [ 91 - _tby ] ) ) {
if ( _bvely > 0 ) {
2020-07-15 23:29:52 +02:00
int dx = _tbx - 145 ;
2019-10-07 00:11:48 +02:00
if ( dx < - 5 ) _bvelx = - abs ( _bvelx ) ;
if ( dx > 5 ) _bvelx = abs ( _bvelx ) ;
_bvely = - abs ( _bvely ) ;
}
if ( abs ( _bvelx ) > 32 ) _bvelx = _bvelx > > 1 ;
if ( abs ( _bvely ) > 32 ) _bvely = _bvely > > 1 ;
}
}
}
void EE : : computer0 ( ) {
_keymove [ 0 ] [ kDirUp ] = 0 ;
if ( _tby < _bytop ) _bytop = _tby ;
2020-07-15 23:29:52 +02:00
int rndoff = 5 - _rnd % 10 ;
int dest = 0 ;
2019-10-07 00:11:48 +02:00
if ( _serve & & ( ( _server & 1 ) = = 0 ) ) {
switch ( _compserve ) {
case 0 :
dest = destination ( 0 , 55 , 2 ) ;
break ;
case 1 :
dest = destination ( 0 , 84 , 2 ) ;
break ;
case 2 :
dest = destination ( 0 , 80 , 2 ) ;
break ;
case 3 :
if ( _sstage = = 0 ) {
if ( ( dest = destination ( 0 , 44 , 2 ) ) )
_sstage = 1 ;
} else {
destination ( 0 , 58 , 2 ) ;
dest = 1 ;
}
break ;
case 4 :
if ( _sstage = = 0 ) {
if ( ( dest = destination ( 0 , 90 , 2 ) ) )
_sstage = 1 ;
} else {
destination ( 0 , 58 , 2 ) ;
dest = 1 ;
}
break ;
case 5 :
if ( _sstage = = 0 ) {
if ( destination ( 0 , 3 , 2 ) )
_sstage = 1 ;
dest = 0 ;
} else {
destination ( 0 , 8 + _sstage + + , 1 ) ;
dest = 1 ;
}
break ;
2019-10-14 04:00:45 +01:00
default :
break ;
2019-10-07 00:11:48 +02:00
}
_keymove [ 0 ] [ kDirUp ] = dest ;
} else if ( _bvely > 0 & & _tbx < 140 ) {
2020-07-15 23:29:52 +02:00
int ystep , destx ;
2019-10-07 00:11:48 +02:00
if ( _bvely > > 6 = = 0 )
ystep = 0 ;
else
ystep = ( 140 - _tby ) / ( _bvely > > 6 ) ;
if ( ystep < 1 | | ( _bvelx > > 6 ) = = 0 )
destx = _tbx ;
else
destx = _tbx + ( _bvelx > > 6 ) * ystep - 4 ;
2020-07-15 23:29:52 +02:00
int dx = _x [ 0 ] - _tbx ;
2019-10-07 00:11:48 +02:00
if ( abs ( _bvelx ) < 128 & & _bytop < 75 ) {
if ( ( _tby < 158 ) ^ ( _bvelx < 0 ) )
destination ( 0 , _tbx - 15 , 3 ) ;
else
destination ( 0 , _tbx + 15 , 3 ) ;
} else {
if ( _tby > 130 ) {
if ( abs ( dx ) > 6 & & abs ( _bvelx ) < 1024 ) {
destination ( 0 , _tbx - ( ( _x [ 0 ] - 60 ) > > 3 ) , 3 ) ;
} else {
destination ( 0 , _tbx + rndoff + ( ( _x [ 0 ] - 60 ) > > 3 ) , 10 ) ;
_keymove [ 0 ] [ kDirUp ] = _x [ 0 ] < 105 & & ( _hitter ! = 0 | | _hits < 2 ) ;
}
} else {
if ( destx < 3 )
destx = 6 - destx ;
if ( destx > 123 )
destx = 246 - destx ;
destination ( 0 , destx + rndoff , 3 ) ;
}
}
} else
destination ( 0 , 56 , 8 ) ;
}
void EE : : computer1 ( ) {
_keymove [ 1 ] [ kDirUp ] = 0 ;
if ( _tby < _bytop ) _bytop = _tby ;
2020-07-15 23:29:52 +02:00
int rndoff = 5 - _rnd % 10 ;
2019-10-07 00:11:48 +02:00
if ( _serve & & ( ( _server & 1 ) = = 1 ) ) {
2020-07-15 23:29:52 +02:00
int dest = 0 ;
2019-10-07 00:11:48 +02:00
switch ( _compserve ) {
case 0 :
dest = destination ( 1 , 232 , 2 ) ;
break ;
case 1 :
dest = destination ( 1 , 202 , 2 ) ;
break ;
case 2 :
dest = destination ( 1 , 208 , 2 ) ;
break ;
case 3 :
if ( _sstage = = 0 ) {
if ( ( dest = destination ( 1 , 250 , 2 ) ) )
_sstage = 1 ;
} else {
destination ( 1 , 220 , 2 ) ;
dest = 1 ;
}
break ;
case 4 :
if ( _sstage = = 0 ) {
if ( ( dest = destination ( 1 , 190 , 2 ) ) )
_sstage = 1 ;
} else {
destination ( 1 , 230 , 2 ) ;
dest = 1 ;
}
break ;
case 5 :
if ( _sstage = = 0 ) {
if ( destination ( 1 , 277 , 2 ) )
_sstage = 1 ;
dest = 0 ;
} else {
destination ( 1 , 272 - _sstage + + , 1 ) ;
dest = 1 ;
}
break ;
2019-10-14 04:00:45 +01:00
default :
break ;
2019-10-07 00:11:48 +02:00
}
_keymove [ 1 ] [ kDirUp ] = dest ;
} else if ( _bvely > 0 & & _tbx > 125 ) {
2020-07-15 23:29:52 +02:00
int ystep , destx ;
2019-10-07 00:11:48 +02:00
if ( _bvely > > 6 = = 0 )
ystep = 0 ;
else
ystep = ( 140 - _tby ) / ( _bvely > > 6 ) ;
if ( ystep < 1 | | ( _bvelx > > 6 ) = = 0 )
destx = _tbx ;
else
destx = _tbx + ( _bvelx > > 6 ) * ystep - 4 ;
2020-07-15 23:29:52 +02:00
int dx = _x [ 1 ] - _tbx ;
2019-10-07 00:11:48 +02:00
if ( abs ( _bvelx ) < 128 & & _bytop < 75 ) {
if ( ( _tby < 158 ) ^ ( _bvelx < 0 ) )
destination ( 1 , _tbx + 15 , 3 ) ;
else
destination ( 1 , _tbx - 15 , 3 ) ;
} else {
if ( _tby > 130 ) {
if ( abs ( dx ) > 6 & & abs ( _bvelx ) < 1024 )
destination ( 1 , _tbx + ( ( _x [ 1 ] - 218 ) > > 3 ) , 3 ) ;
else {
destination ( 1 , _tbx - rndoff - ( ( _x [ 1 ] - 218 ) > > 3 ) , 10 ) ;
_keymove [ 1 ] [ kDirUp ] = _x [ 1 ] > 175 & & ( _hitter ! = 1 | | _hits < 2 ) ;
}
} else {
if ( destx < 158 )
destx = 316 - destx ;
if ( destx > 277 )
destx = 554 - destx ;
destination ( 1 , destx - rndoff , 3 ) ;
}
}
} else
destination ( 1 , 211 , 8 ) ;
}
void EE : : init ( ) {
_rnd = 0 ;
_starter = _winner = _hits = 0 ;
_bvelx = _bvely = 0 ;
2020-07-15 23:29:52 +02:00
_tbx = 200 ; _tby = 20 ;
2019-10-07 00:11:48 +02:00
_bytop = 200 ;
2020-07-15 23:29:52 +02:00
_x [ 0 ] = 64 ; _x [ 1 ] = 226 ;
2019-10-07 00:11:48 +02:00
_air = false ;
_rcnt = 0 ;
_tvelx = _tvely = 0 ;
for ( int i = 0 ; i < 2 ; i + + ) {
_px [ i ] = _x [ i ] ;
_y [ i ] = 173 ;
_frameindex [ i ] = - 1 ;
_rebound [ i ] = 0 ;
_score [ i ] = 0 ;
_keymove [ i ] [ kDirRight ] = _keymove [ i ] [ kDirLeft ] = _keymove [ i ] [ kDirUp ] = 0 ;
_frame [ i ] = 0 ;
}
_oCoords = false ;
_opts = 3 ;
_opt = 0 ;
_mode = kModeMenu ;
_soundEnabled = false ;
_olx = _oly = _orx = _ory = _obx = _oby = 0 ;
_compserve = 0 ;
_sstage = 0 ;
_tbx = 64 + _starter * 165 ;
_pbx = _tbx ;
_bx = _tbx < < 6 ;
_tby = 135 ;
_pby = 135 ;
_by = _tby < < 6 ;
_server = 2 + _starter ;
_hitter = 2 ;
_serve = _servevel = 1 ;
_rmode = false ;
2020-04-27 14:38:24 +02:00
_shouldQuit = false ;
2019-10-07 00:11:48 +02:00
2021-04-15 23:06:18 +02:00
_inited = true ;
2019-10-07 00:11:48 +02:00
}
2021-04-15 23:06:18 +02:00
void EE : : draw ( int sn , int x1 , int y1 ) {
int x = x1 * _scale ;
int y = y1 * _scale ;
2021-04-15 23:43:45 +02:00
2021-04-18 02:31:09 +01:00
Graphics : : keyBlit ( ( byte * ) _back . getBasePtr ( x , y ) , ( const byte * ) _sp [ sn ] . getPixels ( ) , _back . pitch , _sp [ sn ] . pitch , _sp [ sn ] . w , _sp [ sn ] . h , _back . format . bytesPerPixel , _colorKey ) ;
2021-04-15 23:06:18 +02:00
g_system - > copyRectToOverlay ( _back . getBasePtr ( x , y ) , _back . pitch , _windowX + x , _windowY + y , _sp [ sn ] . w , _sp [ sn ] . h ) ;
2019-10-07 00:11:48 +02:00
}
void EE : : putshapes ( ) {
int sprite ;
cls ( false ) ;
if ( _oCoords ) {
2021-04-15 23:06:18 +02:00
int obx = _obx * _scale , oby = _oby * _scale ;
int olx = _olx * _scale , oly = _oly * _scale ;
int orx = _orx * _scale , ory = _ory * _scale ;
g_system - > copyRectToOverlay ( _back . getBasePtr ( obx , oby ) , _back . pitch , _windowX + obx , _windowY + oby , _sp [ kSpB1 ] . w , _sp [ kSpB1 ] . h ) ;
g_system - > copyRectToOverlay ( _back . getBasePtr ( olx , oly ) , _back . pitch , _windowX + olx , _windowY + oly , _sp [ kSpL1 ] . w , _sp [ kSpL1 ] . h ) ;
g_system - > copyRectToOverlay ( _back . getBasePtr ( orx , ory ) , _back . pitch , _windowX + orx , _windowY + ory , _sp [ kSpR1 ] . w , _sp [ kSpR1 ] . h ) ;
2019-10-07 00:11:48 +02:00
}
sprite = kSpB1 + ( _tbx / 16 ) % 4 ;
draw ( sprite , _tbx , _tby ) ;
_obx = _tbx ;
_oby = _tby ;
if ( _y [ 0 ] < 173 ) {
sprite = kSpL3 ;
} else {
if ( ( _x [ 0 ] / 8 ) % 2 )
sprite = kSpL1 ;
else
sprite = kSpL2 ;
}
draw ( sprite , _x [ 0 ] , _y [ 0 ] ) ;
_olx = _x [ 0 ] ;
_oly = _y [ 0 ] ;
if ( _y [ 1 ] < 173 ) {
sprite = kSpR3 ;
} else {
if ( ( _x [ 1 ] / 8 ) % 2 )
sprite = kSpR1 ;
else
sprite = kSpR2 ;
}
draw ( sprite , _x [ 1 ] , _y [ 1 ] ) ;
_orx = _x [ 1 ] ;
_ory = _y [ 1 ] ;
_oCoords = true ;
const int frames [ ] = {
153 , 106 , 160 , 200 ,
4 , 13 , 6 , 200 ,
310 , 13 , 312 , 200 ,
4 , 13 , 312 , 14 ,
4 , 199 , 312 , 200 ,
154 , 107 , 159 , 199
} ;
uint32 color1 = _back . format . RGBToColor ( 5 * 16 , 7 * 16 , 8 * 16 ) ;
uint32 color2 = _back . format . RGBToColor ( 6 * 16 , 8 * 16 , 12 * 16 ) ;
const int * ptr = frames ;
for ( int i = 0 ; i < 6 ; i + + , ptr + = 4 ) {
2021-04-15 23:06:18 +02:00
Common : : Rect r ( ptr [ 0 ] * _scale , ptr [ 1 ] * _scale , ptr [ 2 ] * _scale , ptr [ 3 ] * _scale ) ;
2019-10-07 00:11:48 +02:00
_back . fillRect ( r , ( i < 5 ? color1 : color2 ) ) ;
2021-04-15 23:06:18 +02:00
g_system - > copyRectToOverlay ( _back . getBasePtr ( r . left , r . top ) , _back . pitch , _windowX + r . left , _windowY + r . top , r . width ( ) , r . height ( ) ) ;
2019-10-07 00:11:48 +02:00
}
2021-04-15 23:06:18 +02:00
for ( int i = 0 ; i < 2 ; i + + ) {
int startx = i ? 264 : 32 ;
2019-10-07 00:11:48 +02:00
2021-04-15 23:06:18 +02:00
draw ( kSpNum0 + _score [ i ] / 10 , startx , 1 ) ;
startx + = 8 ;
draw ( kSpNum0 + _score [ i ] % 10 , startx , 1 ) ;
startx + = 8 ;
draw ( _server = = i ? kSpStar : kSpSpace , startx , 1 ) ;
}
2019-10-07 00:11:48 +02:00
for ( int i = 0 ; i < 6 ; i + + ) {
2021-04-15 18:31:14 +02:00
int sx = i = = 0 ? 92 : 80 ;
int sy = i = = 0 ? 2 : 20 ;
2021-04-15 23:06:18 +02:00
int code = i = = 0 ? kSpCode1 : i - 1 = = _opt ? kSpCode1h + i : kSpCode1 + i ;
draw ( code , sx , sy + i * 10 ) ;
2019-10-07 00:11:48 +02:00
if ( _mode ! = kModeMenu )
break ;
}
}
void EE : : doMenu ( Common : : Event & e ) {
switch ( e . kbd . keycode ) {
case Common : : KEYCODE_UP :
_opt - - ;
if ( _opt < 0 )
_opt = 4 ;
break ;
case Common : : KEYCODE_DOWN :
_opt = ( _opt + 1 ) % 5 ;
break ;
case Common : : KEYCODE_RETURN :
if ( _opt < 4 ) {
_opts = _opt ;
_mode = kModePlay ;
cls ( ) ;
} else {
_shouldQuit = true ;
}
break ;
case Common : : KEYCODE_ESCAPE :
_shouldQuit = true ;
break ;
default :
break ;
}
}
void EE : : game ( ) {
if ( _mode = = kModePlay | | _mode = = kModeMenu ) {
_rnd = ( _rnd * 5 + 1 ) % 32767 ;
if ( _opts & 1 )
computer0 ( ) ;
if ( _opts & 2 )
computer1 ( ) ;
if ( _rmode ) {
if ( _rcnt - - > 0 | | _frameindex [ 0 ] ! = - 1 | | _frameindex [ 1 ] ! = - 1 ) {
resetpt ( ) ;
} else {
_rmode = false ;
calcscore ( ) ;
}
return ;
}
getPos ( ) ;
if ( _serve ) {
docollisions ( ) ;
_air = true ;
} else {
if ( _air ) {
docollisions ( ) ;
_air = moveball ( ) ;
}
}
if ( ! _air | | _hits > 2 ) {
setwinner ( ) ;
_rmode = true ;
_rcnt = 20 ;
}
}
}
void EE : : playSound ( int sound ) {
// FIXME
}
static const uint32 ball [ 21 ] = {
0x0000fd00 , 0x00074ac0 , 0x000afde0 , 0x001703e8 , 0x0038f7d8 , 0x0056f73c ,
0x00aef6fc , 0x00cf79fb , 0x01afbbf7 , 0x01b7bdcd , 0x0077dd3a , 0x013beef3 ,
0x01bbef6a , 0x015df78b , 0x00defbea , 0x00ef7dd8 , 0x00779eb4 , 0x0029ef68 ,
0x001ef4a0 , 0x000673c0 , 0x0000ae00
} ;
static const uint32 head [ 38 ] = {
0xbb400000 , 0x0000000f , 0xea650000 , 0x000003af , 0xfaaa6000 , 0x00000e7f ,
0xfea5a400 , 0x03ff2af0 , 0x3eaa6900 , 0x3ea969c0 , 0x3ea99940 , 0xeaaa69c8 ,
0x3a669540 , 0xea995540 , 0x5a555550 , 0xa9aa999a , 0x65a65550 , 0x2aa69a5a ,
0x59555650 , 0x02aaaa55 , 0x6aa66550 , 0x000aa950 , 0x6a569950 , 0x000a9500 ,
0xa9595580 , 0x00015001 , 0xa9a55540 , 0x00000015 , 0xa9a9a500 , 0x0000015a ,
0x59695800 , 0x00001659 , 0x65659000 , 0x00000a96 , 0xa65a8000 , 0x000002aa ,
0xa6500000 , 0x0000002a
} ;
static const uint32 legs [ 42 ] = {
2020-07-15 23:29:52 +02:00
0xa0000000 , 0x00000000 , 0x80000000 , 0x00000002 , 0x80000000 , 0x00000002 , 0xa0000000 ,
2019-10-07 00:11:48 +02:00
0x00000000 , 0x50000000 , 0x00000000 , 0xf0000000 , 0x00000003 , 0xfc000000 , 0x000003ff ,
0xa0000000 , 0x00000002 , 0x0a000000 , 0x0000000a , 0x02400000 , 0x00000028 , 0x00700000 ,
0x00000028 , 0x00fc0000 , 0x00000014 , 0x03c00000 , 0x000000fc , 0x0f000000 , 0x0000ffff ,
0xa0000000 , 0x00000000 , 0x80000000 , 0x00000002 , 0xa8000000 , 0x00000002 , 0x29c00000 ,
0x00000000 , 0x01f00000 , 0x00000000 , 0x0fc00000 , 0x00000000 , 0xfc000000 , 0x00000000
} ;
static const int spcolors [ 10 * 3 ] = {
0 , 0 , 0 , 8 , 15 , 8 , 6 , 12 , 6 , 12 , 13 , 12 ,
0 , 0 , 0 , 15 , 8 , 8 , 12 , 6 , 6 , 13 , 12 , 12 ,
0 , 0 , 0 , 12 , 12 , 12
} ;
2021-04-15 23:06:18 +02:00
const char * codes =
" Dvhgkm#Ztrsm|ffrs(#$%&'#$%&O}pes&}{1$M{tiq$%&'#$M{tiq${y5(Fsrv||hv%&'#$ "
" Hutxxxjx'~v2%N|udr%&'#Gtsw}wiw&}{1$Hutxxxjx'#$%&'(#$%W|qw$%&'(#$%&' " ;
2021-04-18 10:28:18 +01:00
void EE : : setupGraphics ( ) {
// Determine scale factor
float scaleX = g_system - > getOverlayWidth ( ) * 0.9 / 320 ;
float scaleY = g_system - > getOverlayHeight ( ) * 0.9 / 200 ;
_scale = MIN ( scaleX , scaleY ) ;
_windowW = 320 * _scale ;
_windowH = 200 * _scale ;
_windowX = ( g_system - > getOverlayWidth ( ) > 320 ) ? ( g_system - > getOverlayWidth ( ) - _windowW ) / 2 : 0 ;
_windowY = ( g_system - > getOverlayHeight ( ) > 200 ) ? ( g_system - > getOverlayHeight ( ) - _windowH ) / 2 : 0 ;
_format = g_system - > getOverlayFormat ( ) ;
_back . create ( _windowW , _windowH , _format ) ;
_colorBlack = _format . RGBToColor ( 0 * 16 , 0 * 16 , 0 * 16 ) ;
_colorBlue = _format . RGBToColor ( 5 * 16 , 7 * 16 , 8 * 16 ) ;
_colorOrange = _format . RGBToColor ( 15 * 16 , 7 * 16 , 8 * 16 ) ;
_colorKey = _colorBlack ;
cls ( ) ;
2019-10-07 00:11:48 +02:00
uint32 palette [ 12 ] ;
for ( int i = 0 ; i < 10 * 3 ; i + = 3 )
palette [ i / 3 ] = _back . format . RGBToColor ( spcolors [ i ] * 16 , spcolors [ i + 1 ] * 16 , spcolors [ i + 2 ] * 16 ) ;
2021-04-15 23:06:18 +02:00
Graphics : : Surface tmp ;
int w = 25 , h = 21 ;
tmp . create ( w , h , g_system - > getOverlayFormat ( ) ) ;
2019-10-07 00:11:48 +02:00
for ( int s = 0 ; s < 4 ; s + + ) {
int posy = 0 , dy = 1 ;
if ( s & 2 ) { posy = 20 ; dy = - 1 ; }
2021-04-15 23:06:18 +02:00
for ( int y = 0 ; y < h ; y + + , posy + = dy ) {
2019-10-07 00:11:48 +02:00
uint32 pixels = ball [ y ] ;
int posx = 0 , dx = 1 ;
if ( s & 1 ) { posx = 24 ; dx = - 1 ; }
2021-04-15 23:06:18 +02:00
for ( int x = 0 ; x < w ; x + + , posx + = dx ) {
2019-10-07 00:11:48 +02:00
int color = pixels & 1 ;
pixels > > = 1 ;
2021-04-18 02:31:09 +01:00
tmp . setPixel ( posx , posy , palette [ color + 8 ] ) ;
2019-10-07 00:11:48 +02:00
}
}
2021-04-15 23:06:18 +02:00
Graphics : : Surface * tmp2 = tmp . scale ( w * _scale , h * _scale ) ;
_sp [ kSpB1 + s ] . copyFrom ( * tmp2 ) ;
tmp2 - > free ( ) ;
delete tmp2 ;
2019-10-07 00:11:48 +02:00
}
2021-04-15 23:06:18 +02:00
tmp . free ( ) ;
2019-10-07 00:11:48 +02:00
2021-04-15 23:06:18 +02:00
w = 32 ;
h = 26 ;
tmp . create ( w , h , g_system - > getOverlayFormat ( ) ) ;
2019-10-07 00:11:48 +02:00
2021-04-15 23:06:18 +02:00
for ( int s = 0 ; s < 6 ; s + + ) {
for ( int y = 0 ; y < h ; y + + ) {
2019-10-07 00:11:48 +02:00
const uint32 * ptr = ( y < 19 ) ? & head [ y * 2 ] : & legs [ ( y - 19 + ( s % 3 ) * 7 ) * 2 ] ;
uint32 pixels = * ptr + + ;
int posx = 0 , dx = 1 ;
if ( s > 2 ) { posx = 31 ; dx = - 1 ; }
2021-04-15 23:06:18 +02:00
for ( int x = 0 ; x < w ; x + + , posx + = dx ) {
2019-10-07 00:11:48 +02:00
int color = pixels & 3 ;
pixels > > = 2 ;
if ( x = = 15 )
pixels = * ptr ;
2021-04-18 02:31:09 +01:00
tmp . setPixel ( posx , y , palette [ color + 4 * ( s / 3 ) ] ) ;
2019-10-07 00:11:48 +02:00
}
}
2021-04-15 23:06:18 +02:00
Graphics : : Surface * tmp2 = tmp . scale ( w * _scale , h * _scale ) ;
_sp [ kSpL1 + s ] . copyFrom ( * tmp2 ) ;
tmp2 - > free ( ) ;
delete tmp2 ;
}
tmp . free ( ) ;
w = 23 * 8 ;
h = 10 ;
tmp . create ( w , h , g_system - > getOverlayFormat ( ) ) ;
for ( int hl = 0 ; hl < 2 ; hl + + ) {
for ( int i = 0 ; i < 6 ; i + + ) {
2021-04-18 02:31:09 +01:00
tmp . fillRect ( Common : : Rect ( 0 , 0 , w , h ) , hl = = 1 ? _colorBlue : _colorKey ) ;
2021-04-15 23:06:18 +02:00
char buf [ 100 ] ;
int c ;
for ( c = 0 ; c < 23 ; c + + )
buf [ c ] = codes [ c + 23 * i ] - 3 - c % 6 ;
buf [ c ] = 0 ;
2021-04-18 02:31:09 +01:00
int c1 = i = = 0 ? _colorOrange : hl = = 1 ? _colorKey : _colorBlue ;
2021-04-15 23:06:18 +02:00
_font . drawString ( & tmp , buf , 0 , 1 , w , c1 , Graphics : : kTextAlignLeft , 0 , false ) ;
Graphics : : Surface * tmp2 = tmp . scale ( w * _scale , h * _scale , true ) ;
_sp [ kSpCode1 + hl * 6 + i ] . copyFrom ( * tmp2 ) ;
tmp2 - > free ( ) ;
delete tmp2 ;
}
}
tmp . free ( ) ;
w = 8 ;
h = 10 ;
tmp . create ( w , h , g_system - > getOverlayFormat ( ) ) ;
for ( int i = 0 ; i < 12 ; i + + ) {
2021-04-18 02:31:09 +01:00
tmp . fillRect ( Common : : Rect ( 0 , 0 , w , h ) , _colorKey ) ;
2021-04-15 23:06:18 +02:00
char buf [ 2 ] ;
buf [ 0 ] = i = = 10 ? ' * ' : i = = 11 ? ' ' : ' 0 ' + i ;
buf [ 1 ] = 0 ;
int c = i > 9 ? _colorBlue : _colorOrange ;
_font . drawString ( & tmp , buf , 0 , 1 , w , c , Graphics : : kTextAlignLeft , 0 , false ) ;
Graphics : : Surface * tmp2 = tmp . scale ( w * _scale , h * _scale , true ) ;
_sp [ kSpNum0 + i ] . copyFrom ( * tmp2 ) ;
tmp2 - > free ( ) ;
delete tmp2 ;
2019-10-07 00:11:48 +02:00
}
2021-04-15 23:06:18 +02:00
tmp . free ( ) ;
2019-10-07 00:11:48 +02:00
}
2003-11-10 23:40:48 +00:00
} // End of namespace GUI