2013-06-02 11:43:15 +00:00
// Copyright (c) 2013- PPSSPP Project.
// 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, version 2.0 or later versions.
// 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
2014-06-21 21:03:50 +00:00
# include <algorithm>
2013-06-09 10:41:12 +00:00
# include "base/colorutil.h"
# include "base/timeutil.h"
2013-08-18 18:25:33 +00:00
# include "gfx_es2/draw_buffer.h"
2013-07-15 22:29:00 +00:00
# include "i18n/i18n.h"
2013-06-09 10:41:12 +00:00
# include "math/curves.h"
2013-12-11 19:19:30 +00:00
# include "util/text/utf8.h"
2013-06-09 10:41:12 +00:00
# include "ui/ui_context.h"
2013-06-08 20:42:31 +00:00
# include "ui/view.h"
# include "ui/viewgroup.h"
# include "UI/EmuScreen.h"
# include "UI/GameScreen.h"
# include "UI/GameSettingsScreen.h"
# include "UI/GameInfoCache.h"
2013-07-15 15:41:24 +00:00
# include "UI/MiscScreens.h"
2013-06-10 20:06:51 +00:00
# include "UI/MainScreen.h"
2014-06-22 15:02:04 +00:00
# include "UI/BackgroundAudio.h"
2013-08-26 17:00:16 +00:00
# include "Core/Host.h"
2013-09-19 08:10:31 +00:00
# include "Core/Config.h"
2013-06-08 20:42:31 +00:00
2014-06-22 15:02:04 +00:00
GameScreen : : GameScreen ( const std : : string & gamePath ) : UIDialogScreenWithGameBackground ( gamePath ) {
SetBackgroundAudioGame ( gamePath ) ;
}
GameScreen : : ~ GameScreen ( ) {
SetBackgroundAudioGame ( " " ) ;
}
2013-06-08 20:42:31 +00:00
void GameScreen : : CreateViews ( ) {
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , GAMEINFO_WANTBG | GAMEINFO_WANTSIZE ) ;
2013-06-08 20:42:31 +00:00
2013-09-03 08:42:26 +00:00
I18NCategory * d = GetI18NCategory ( " Dialog " ) ;
2013-07-15 22:29:00 +00:00
I18NCategory * ga = GetI18NCategory ( " Game " ) ;
2013-06-08 20:42:31 +00:00
// Information in the top left.
// Back button to the bottom left.
// Scrolling action menu to the right.
using namespace UI ;
Margins actionMenuMargins ( 0 , 100 , 15 , 0 ) ;
root_ = new LinearLayout ( ORIENT_HORIZONTAL ) ;
ViewGroup * leftColumn = new AnchorLayout ( new LinearLayoutParams ( 1.0f ) ) ;
root_ - > Add ( leftColumn ) ;
2013-09-03 08:42:26 +00:00
leftColumn - > Add ( new Choice ( d - > T ( " Back " ) , " " , false , new AnchorLayoutParams ( 150 , WRAP_CONTENT , 10 , NONE , NONE , 10 ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnSwitchBack ) ;
2013-06-08 20:42:31 +00:00
if ( info ) {
2014-08-17 19:29:36 +00:00
texvGameIcon_ = leftColumn - > Add ( new Thin3DTextureView ( 0 , IS_DEFAULT , new AnchorLayoutParams ( 144 * 2 , 80 * 2 , 10 , 10 , NONE , NONE ) ) ) ;
2013-12-08 06:48:12 +00:00
tvTitle_ = leftColumn - > Add ( new TextView ( info - > title , ALIGN_LEFT , false , new AnchorLayoutParams ( 10 , 200 , NONE , NONE ) ) ) ;
2015-02-15 10:21:17 +00:00
tvTitle_ - > SetShadow ( true ) ;
2013-12-08 06:48:12 +00:00
// This one doesn't need to be updated.
2015-02-15 10:21:17 +00:00
leftColumn - > Add ( new TextView ( gamePath_ , ALIGN_LEFT , true , new AnchorLayoutParams ( 10 , 250 , NONE , NONE ) ) ) - > SetShadow ( true ) ;
2013-12-08 06:48:12 +00:00
tvGameSize_ = leftColumn - > Add ( new TextView ( " ... " , ALIGN_LEFT , true , new AnchorLayoutParams ( 10 , 290 , NONE , NONE ) ) ) ;
2015-02-15 10:21:17 +00:00
tvGameSize_ - > SetShadow ( true ) ;
2013-12-08 06:48:12 +00:00
tvSaveDataSize_ = leftColumn - > Add ( new TextView ( " ... " , ALIGN_LEFT , true , new AnchorLayoutParams ( 10 , 320 , NONE , NONE ) ) ) ;
2015-02-15 10:21:17 +00:00
tvSaveDataSize_ - > SetShadow ( true ) ;
2013-12-08 06:48:12 +00:00
tvInstallDataSize_ = leftColumn - > Add ( new TextView ( " " , ALIGN_LEFT , true , new AnchorLayoutParams ( 10 , 350 , NONE , NONE ) ) ) ;
2015-02-15 10:21:17 +00:00
tvInstallDataSize_ - > SetShadow ( true ) ;
2013-12-08 06:48:12 +00:00
tvRegion_ = leftColumn - > Add ( new TextView ( " " , ALIGN_LEFT , true , new AnchorLayoutParams ( 10 , 380 , NONE , NONE ) ) ) ;
2015-02-15 10:21:17 +00:00
tvRegion_ - > SetShadow ( true ) ;
2013-06-08 20:42:31 +00:00
}
ViewGroup * rightColumn = new ScrollView ( ORIENT_VERTICAL , new LinearLayoutParams ( 300 , FILL_PARENT , actionMenuMargins ) ) ;
root_ - > Add ( rightColumn ) ;
2013-10-16 17:02:51 +00:00
LinearLayout * rightColumnItems = new LinearLayout ( ORIENT_VERTICAL ) ;
rightColumnItems - > SetSpacing ( 0.0f ) ;
2013-06-08 20:42:31 +00:00
rightColumn - > Add ( rightColumnItems ) ;
2013-08-14 15:24:58 +00:00
Choice * play = new Choice ( ga - > T ( " Play " ) ) ;
rightColumnItems - > Add ( play ) - > OnClick . Handle ( this , & GameScreen : : OnPlay ) ;
2014-12-14 19:33:20 +00:00
if ( info & & ! info - > id . empty ( ) )
{
if ( g_Config . hasGameConfig ( info - > id ) )
{
rightColumnItems - > Add ( new Choice ( ga - > T ( " Game Settings " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnGameSettings ) ;
rightColumnItems - > Add ( new Choice ( ga - > T ( " Delete Game Config " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnDeleteConfig ) ;
}
else
{
rightColumnItems - > Add ( new Choice ( ga - > T ( " Create Game Config " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnCreateConfig ) ;
}
}
2014-07-21 18:59:03 +00:00
std : : vector < std : : string > saveDirs = info - > GetSaveDataDirectories ( ) ;
if ( saveDirs . size ( ) ) {
rightColumnItems - > Add ( new Choice ( ga - > T ( " Delete Save Data " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnDeleteSaveData ) ;
}
2013-09-22 10:25:27 +00:00
rightColumnItems - > Add ( new Choice ( ga - > T ( " Delete Game " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnDeleteGame ) ;
2013-08-26 17:00:16 +00:00
if ( host - > CanCreateShortcut ( ) ) {
rightColumnItems - > Add ( new Choice ( ga - > T ( " Create Shortcut " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnCreateShortcut ) ;
}
2013-09-19 08:10:31 +00:00
if ( isRecentGame ( gamePath_ ) ) {
rightColumnItems - > Add ( new Choice ( ga - > T ( " Remove From Recent " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnRemoveFromRecent ) ;
}
2013-12-11 19:19:30 +00:00
# ifdef _WIN32
rightColumnItems - > Add ( new Choice ( ga - > T ( " Show In Folder " ) ) ) - > OnClick . Handle ( this , & GameScreen : : OnShowInFolder ) ;
# endif
2013-06-08 20:42:31 +00:00
}
2014-12-14 19:33:20 +00:00
UI : : EventReturn GameScreen : : OnCreateConfig ( UI : : EventParams & e )
{
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , 0 ) ;
g_Config . createGameConfig ( info - > id ) ;
2014-12-19 13:52:44 +00:00
g_Config . saveGameConfig ( info - > id ) ;
2014-12-14 19:33:20 +00:00
screenManager ( ) - > topScreen ( ) - > RecreateViews ( ) ;
return UI : : EVENT_DONE ;
}
void GameScreen : : CallbackDeleteConfig ( bool yes )
{
if ( yes )
{
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , 0 ) ;
g_Config . deleteGameConfig ( info - > id ) ;
screenManager ( ) - > RecreateAllViews ( ) ;
}
}
UI : : EventReturn GameScreen : : OnDeleteConfig ( UI : : EventParams & e )
{
I18NCategory * d = GetI18NCategory ( " Dialog " ) ;
I18NCategory * ga = GetI18NCategory ( " Game " ) ;
screenManager ( ) - > push (
new PromptScreen ( d - > T ( " DeleteConfirmGameConfig " , " Do you really want to delete the settings for this game? " ) , ga - > T ( " ConfirmDelete " ) , d - > T ( " Cancel " ) ,
std : : bind ( & GameScreen : : CallbackDeleteConfig , this , placeholder : : _1 ) ) ) ;
return UI : : EVENT_DONE ;
}
2013-06-08 20:42:31 +00:00
void GameScreen : : update ( InputState & input ) {
UIScreen : : update ( input ) ;
2013-08-30 17:00:25 +00:00
I18NCategory * ga = GetI18NCategory ( " Game " ) ;
2014-08-17 19:29:36 +00:00
Thin3DContext * thin3d = screenManager ( ) - > getThin3DContext ( ) ;
GameInfo * info = g_gameInfoCache . GetInfo ( thin3d , gamePath_ , GAMEINFO_WANTBG | GAMEINFO_WANTSIZE ) ;
2013-06-09 11:41:15 +00:00
2013-06-08 20:42:31 +00:00
if ( tvTitle_ )
2013-08-24 11:08:02 +00:00
tvTitle_ - > SetText ( info - > title + " ( " + info - > id + " ) " ) ;
2013-06-09 11:41:15 +00:00
if ( info - > iconTexture & & texvGameIcon_ ) {
texvGameIcon_ - > SetTexture ( info - > iconTexture ) ;
2014-06-21 21:03:50 +00:00
// Fade the icon with the background.
double loadTime = info - > timeIconWasLoaded ;
if ( info - > pic1Texture ) {
loadTime = std : : max ( loadTime , info - > timePic1WasLoaded ) ;
}
if ( info - > pic0Texture ) {
loadTime = std : : max ( loadTime , info - > timePic0WasLoaded ) ;
}
uint32_t color = whiteAlpha ( ease ( ( time_now_d ( ) - loadTime ) * 3 ) ) ;
2013-06-09 11:41:15 +00:00
texvGameIcon_ - > SetColor ( color ) ;
}
2013-06-09 10:41:12 +00:00
if ( info - > gameSize ) {
char temp [ 256 ] ;
2013-08-30 17:00:25 +00:00
sprintf ( temp , " %s: %1.1f %s " , ga - > T ( " Game " ) , ( float ) ( info - > gameSize ) / 1024.f / 1024.f , ga - > T ( " MB " ) ) ;
2013-06-09 10:41:12 +00:00
tvGameSize_ - > SetText ( temp ) ;
2013-08-30 17:00:25 +00:00
sprintf ( temp , " %s: %1.2f %s " , ga - > T ( " SaveData " ) , ( float ) ( info - > saveDataSize ) / 1024.f / 1024.f , ga - > T ( " MB " ) ) ;
2013-06-09 10:41:12 +00:00
tvSaveDataSize_ - > SetText ( temp ) ;
2013-10-03 12:44:16 +00:00
if ( info - > installDataSize > 0 ) {
sprintf ( temp , " %s: %1.2f %s " , ga - > T ( " InstallData " ) , ( float ) ( info - > installDataSize ) / 1024.f / 1024.f , ga - > T ( " MB " ) ) ;
tvInstallDataSize_ - > SetText ( temp ) ;
}
2013-06-09 10:41:12 +00:00
}
2013-12-10 16:23:03 +00:00
if ( info - > region > = 0 & & info - > region < GAMEREGION_MAX & & info - > region ! = GAMEREGION_OTHER ) {
static const char * regionNames [ GAMEREGION_MAX ] = {
" Japan " ,
" USA " ,
" Europe " ,
" Hong Kong " ,
" Asia "
} ;
tvRegion_ - > SetText ( ga - > T ( regionNames [ info - > region ] ) ) ;
}
2013-06-09 10:41:12 +00:00
}
2013-12-11 19:19:30 +00:00
UI : : EventReturn GameScreen : : OnShowInFolder ( UI : : EventParams & e ) {
# ifdef _WIN32
std : : string str = std : : string ( " explorer.exe /select, \" " ) + ReplaceAll ( gamePath_ , " / " , " \\ " ) + " \" " ;
_wsystem ( ConvertUTF8ToWString ( str ) . c_str ( ) ) ;
# endif
return UI : : EVENT_DONE ;
}
2013-06-09 10:41:12 +00:00
UI : : EventReturn GameScreen : : OnSwitchBack ( UI : : EventParams & e ) {
2013-06-27 14:28:11 +00:00
screenManager ( ) - > finishDialog ( this , DR_OK ) ;
2013-06-09 10:41:12 +00:00
return UI : : EVENT_DONE ;
2013-06-08 20:42:31 +00:00
}
UI : : EventReturn GameScreen : : OnPlay ( UI : : EventParams & e ) {
screenManager ( ) - > switchScreen ( new EmuScreen ( gamePath_ ) ) ;
return UI : : EVENT_DONE ;
}
UI : : EventReturn GameScreen : : OnGameSettings ( UI : : EventParams & e ) {
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , GAMEINFO_WANTBG | GAMEINFO_WANTSIZE ) ;
2013-06-08 20:42:31 +00:00
if ( info & & info - > paramSFOLoaded ) {
std : : string discID = info - > paramSFO . GetValueString ( " DISC_ID " ) ;
2014-12-14 19:33:20 +00:00
screenManager ( ) - > push ( new GameSettingsScreen ( gamePath_ , discID , true ) ) ;
2013-06-08 20:42:31 +00:00
}
return UI : : EVENT_DONE ;
}
UI : : EventReturn GameScreen : : OnDeleteSaveData ( UI : : EventParams & e ) {
2013-08-13 11:18:01 +00:00
I18NCategory * d = GetI18NCategory ( " Dialog " ) ;
2013-08-30 17:00:25 +00:00
I18NCategory * ga = GetI18NCategory ( " Game " ) ;
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , GAMEINFO_WANTBG | GAMEINFO_WANTSIZE ) ;
2013-06-08 20:42:31 +00:00
if ( info ) {
2014-07-21 18:59:03 +00:00
// Check that there's any savedata to delete
std : : vector < std : : string > saveDirs = info - > GetSaveDataDirectories ( ) ;
if ( saveDirs . size ( ) ) {
screenManager ( ) - > push (
new PromptScreen ( d - > T ( " DeleteConfirmAll " , " Do you really want to delete all \n your save data for this game? " ) , ga - > T ( " ConfirmDelete " ) , d - > T ( " Cancel " ) ,
std : : bind ( & GameScreen : : CallbackDeleteSaveData , this , placeholder : : _1 ) ) ) ;
}
2013-06-08 20:42:31 +00:00
}
RecreateViews ( ) ;
return UI : : EVENT_DONE ;
}
2013-06-09 10:41:12 +00:00
void GameScreen : : CallbackDeleteSaveData ( bool yes ) {
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , 0 ) ;
2013-06-09 10:41:12 +00:00
if ( yes ) {
info - > DeleteAllSaveData ( ) ;
2013-10-09 11:34:36 +00:00
info - > saveDataSize = 0 ;
info - > installDataSize = 0 ;
2013-06-09 10:41:12 +00:00
}
}
2013-06-08 20:42:31 +00:00
UI : : EventReturn GameScreen : : OnDeleteGame ( UI : : EventParams & e ) {
2013-08-13 11:18:01 +00:00
I18NCategory * d = GetI18NCategory ( " Dialog " ) ;
2013-08-30 17:00:25 +00:00
I18NCategory * ga = GetI18NCategory ( " Game " ) ;
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , GAMEINFO_WANTBG | GAMEINFO_WANTSIZE ) ;
2013-06-08 20:42:31 +00:00
if ( info ) {
2013-06-09 10:41:12 +00:00
screenManager ( ) - > push (
2013-09-22 10:43:54 +00:00
new PromptScreen ( d - > T ( " DeleteConfirmGame " , " Do you really want to delete this game \n from your device? You can't undo this. " ) , ga - > T ( " ConfirmDelete " ) , d - > T ( " Cancel " ) ,
2013-06-09 10:41:12 +00:00
std : : bind ( & GameScreen : : CallbackDeleteGame , this , placeholder : : _1 ) ) ) ;
2013-06-08 20:42:31 +00:00
}
2013-06-09 10:41:12 +00:00
return UI : : EVENT_DONE ;
}
void GameScreen : : CallbackDeleteGame ( bool yes ) {
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , 0 ) ;
2013-06-09 10:41:12 +00:00
if ( yes ) {
info - > DeleteGame ( ) ;
g_gameInfoCache . Clear ( ) ;
2013-06-10 20:06:51 +00:00
screenManager ( ) - > switchScreen ( new MainScreen ( ) ) ;
2013-06-09 10:41:12 +00:00
}
}
2013-08-26 17:00:16 +00:00
UI : : EventReturn GameScreen : : OnCreateShortcut ( UI : : EventParams & e ) {
2014-08-17 19:29:36 +00:00
GameInfo * info = g_gameInfoCache . GetInfo ( NULL , gamePath_ , 0 ) ;
2013-08-26 17:00:16 +00:00
if ( info ) {
host - > CreateDesktopShortcut ( gamePath_ , info - > title ) ;
}
return UI : : EVENT_DONE ;
}
2013-09-19 08:10:31 +00:00
2014-02-09 21:15:53 +00:00
bool GameScreen : : isRecentGame ( const std : : string & gamePath ) {
2014-06-29 03:44:24 +00:00
if ( g_Config . iMaxRecent < = 0 )
return false ;
2013-09-19 08:10:31 +00:00
for ( auto it = g_Config . recentIsos . begin ( ) ; it ! = g_Config . recentIsos . end ( ) ; + + it ) {
2013-11-19 12:46:33 +00:00
# ifdef _WIN32
2013-11-23 17:11:33 +00:00
if ( ! strcmpIgnore ( ( * it ) . c_str ( ) , gamePath . c_str ( ) , " \\ " , " / " ) )
2013-11-19 12:46:33 +00:00
# else
2013-11-23 17:11:33 +00:00
if ( ! strcmp ( ( * it ) . c_str ( ) , gamePath . c_str ( ) ) )
2013-11-19 12:46:33 +00:00
# endif
2013-09-19 08:10:31 +00:00
return true ;
}
return false ;
}
UI : : EventReturn GameScreen : : OnRemoveFromRecent ( UI : : EventParams & e ) {
2014-06-29 03:44:24 +00:00
if ( g_Config . iMaxRecent < = 0 )
return UI : : EVENT_DONE ;
2013-09-19 08:10:31 +00:00
for ( auto it = g_Config . recentIsos . begin ( ) ; it ! = g_Config . recentIsos . end ( ) ; + + it ) {
2013-11-19 12:46:33 +00:00
# ifdef _WIN32
2013-11-18 15:42:38 +00:00
if ( ! strcmpIgnore ( ( * it ) . c_str ( ) , gamePath_ . c_str ( ) , " \\ " , " / " ) ) {
2013-11-19 12:46:33 +00:00
# else
2013-11-23 17:11:33 +00:00
if ( ! strcmp ( ( * it ) . c_str ( ) , gamePath_ . c_str ( ) ) ) {
2013-11-19 12:46:33 +00:00
# endif
2013-09-19 08:10:31 +00:00
g_Config . recentIsos . erase ( it ) ;
screenManager ( ) - > switchScreen ( new MainScreen ( ) ) ;
return UI : : EVENT_DONE ;
}
}
return UI : : EVENT_DONE ;
2013-09-21 16:56:34 +00:00
}