mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
407 lines
9.7 KiB
C++
407 lines
9.7 KiB
C++
/*
|
|
Copyright (C) 2006 StrmnNrmn
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
#include "BuildOptions.h"
|
|
#include "Base/Types.h"
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <pspctrl.h>
|
|
#include <pspgu.h>
|
|
|
|
#include "Core/CPU.h"
|
|
#include "Core/ROM.h"
|
|
#include "Core/RomSettings.h"
|
|
#include "Interface/SaveState.h"
|
|
#include "Graphics/ColourValue.h"
|
|
#include "Graphics/GraphicsContext.h"
|
|
#include "Base/MathUtil.h"
|
|
#include "SysPSP/Graphics/DrawText.h"
|
|
#include "SysPSP/UI/AboutComponent.h"
|
|
#include "SysPSP/UI/GlobalSettingsComponent.h"
|
|
#include "SysPSP/UI/MainMenuScreen.h"
|
|
#include "SysPSP/UI/PSPMenu.h"
|
|
#include "SysPSP/UI/RomSelectorComponent.h"
|
|
#include "SysPSP/UI/SelectedRomComponent.h"
|
|
#include "SysPSP/UI/SavestateSelectorComponent.h"
|
|
#include "SysPSP/UI/UIContext.h"
|
|
#include "SysPSP/UI/UIScreen.h"
|
|
#include "SysPSP/UI/SplashScreen.h"
|
|
#include "System/SystemInit.h"
|
|
#include "Interface/Preferences.h"
|
|
|
|
|
|
namespace
|
|
{
|
|
|
|
enum EMenuOption
|
|
{
|
|
MO_GLOBAL_SETTINGS = 0,
|
|
MO_ROMS,
|
|
MO_SELECTED_ROM,
|
|
MO_SAVESTATES,
|
|
MO_ABOUT,
|
|
};
|
|
const s16 NUM_MENU_OPTIONS {MO_ABOUT+1};
|
|
|
|
const EMenuOption MO_FIRST_OPTION = MO_GLOBAL_SETTINGS;
|
|
const EMenuOption MO_LAST_OPTION = MO_ABOUT;
|
|
|
|
const char * const gMenuOptionNames[ NUM_MENU_OPTIONS ] =
|
|
{
|
|
"Global Settings",
|
|
"Roms",
|
|
"Selected Rom",
|
|
"Savestates",
|
|
"About",
|
|
};
|
|
}
|
|
|
|
class IMainMenuScreen : public CMainMenuScreen, public CUIScreen
|
|
{
|
|
public:
|
|
|
|
IMainMenuScreen( CUIContext * p_context );
|
|
~IMainMenuScreen();
|
|
|
|
// CMainMenuScreen
|
|
virtual void Run();
|
|
|
|
// CUIScreen
|
|
virtual void Update( float elapsed_time, const v2 & stick, u32 old_buttons, u32 new_buttons );
|
|
virtual void Render();
|
|
virtual bool IsFinished() const { return mIsFinished; }
|
|
|
|
|
|
private:
|
|
static EMenuOption AsMenuOption( s32 option );
|
|
|
|
EMenuOption GetPreviousOption() const { return AsMenuOption( mCurrentOption - 1 ); }
|
|
EMenuOption GetCurrentOption() const { return AsMenuOption( mCurrentOption ); }
|
|
EMenuOption GetNextOption() const { return AsMenuOption( mCurrentOption + 1 ); }
|
|
|
|
s32 GetPreviousValidOption() const;
|
|
s32 GetNextValidOption() const;
|
|
|
|
bool IsOptionValid( EMenuOption option ) const;
|
|
|
|
void OnRomSelected( const char * rom_filename );
|
|
void OnSavestateSelected( const char * savestate_filename );
|
|
void OnStartEmulation();
|
|
|
|
private:
|
|
bool mIsFinished;
|
|
|
|
s32 mCurrentOption;
|
|
f32 mCurrentDisplayOption;
|
|
|
|
CUIComponent * mOptionComponents[ NUM_MENU_OPTIONS ];
|
|
CSelectedRomComponent * mSelectedRomComponent;
|
|
|
|
std::string mRomFilename;
|
|
RomID mRomID;
|
|
};
|
|
|
|
|
|
CMainMenuScreen::~CMainMenuScreen() {}
|
|
|
|
CMainMenuScreen * CMainMenuScreen::Create( CUIContext * p_context )
|
|
{
|
|
return new IMainMenuScreen( p_context );
|
|
}
|
|
|
|
|
|
IMainMenuScreen::IMainMenuScreen( CUIContext * p_context )
|
|
: CUIScreen( p_context )
|
|
, mIsFinished( false )
|
|
, mCurrentOption( MO_ROMS )
|
|
, mCurrentDisplayOption( mCurrentOption )
|
|
{
|
|
for( u32 i {0}; i < NUM_MENU_OPTIONS; ++i )
|
|
{
|
|
mOptionComponents[ i ] = nullptr;
|
|
}
|
|
|
|
mSelectedRomComponent = CSelectedRomComponent::Create( mpContext, new CMemberFunctor< IMainMenuScreen >( this, &IMainMenuScreen::OnStartEmulation ) );
|
|
|
|
mOptionComponents[ MO_GLOBAL_SETTINGS ] = CGlobalSettingsComponent::Create( mpContext );
|
|
mOptionComponents[ MO_ROMS ] = CRomSelectorComponent::Create( mpContext, new CMemberFunctor1< IMainMenuScreen, const char * >( this, &IMainMenuScreen::OnRomSelected ) );
|
|
mOptionComponents[ MO_SELECTED_ROM ] = mSelectedRomComponent;
|
|
mOptionComponents[ MO_SAVESTATES ] = CSavestateSelectorComponent::Create( mpContext, CSavestateSelectorComponent::AT_LOADING, new CMemberFunctor1< IMainMenuScreen, const char * >( this, &IMainMenuScreen::OnSavestateSelected ), 0 );
|
|
mOptionComponents[ MO_ABOUT ] = CAboutComponent::Create( mpContext );
|
|
|
|
}
|
|
|
|
IMainMenuScreen::~IMainMenuScreen()
|
|
{
|
|
for( u32 i = 0; i < NUM_MENU_OPTIONS; ++i )
|
|
{
|
|
delete mOptionComponents[ i ];
|
|
}
|
|
}
|
|
|
|
EMenuOption IMainMenuScreen::AsMenuOption( s32 option )
|
|
{
|
|
s32 m( option % s32(NUM_MENU_OPTIONS) );
|
|
if( m < 0 )
|
|
m += NUM_MENU_OPTIONS;
|
|
|
|
#ifdef DAEDALUS_ENABLE_ASSERTS
|
|
DAEDALUS_ASSERT( m >= 0 && m < (s32)NUM_MENU_OPTIONS, "Whoops" );
|
|
#endif
|
|
return EMenuOption( m );
|
|
}
|
|
|
|
|
|
s32 IMainMenuScreen::GetPreviousValidOption() const
|
|
{
|
|
bool looped( false );
|
|
s32 current_option( mCurrentOption );
|
|
EMenuOption initial_option( AsMenuOption( current_option ) );
|
|
|
|
do
|
|
{
|
|
current_option--;
|
|
looped = AsMenuOption( current_option ) == initial_option;
|
|
}
|
|
while( !IsOptionValid( AsMenuOption( current_option ) ) && !looped );
|
|
|
|
return current_option;
|
|
}
|
|
|
|
|
|
//
|
|
|
|
s32 IMainMenuScreen::GetNextValidOption() const
|
|
{
|
|
bool looped( false );
|
|
s32 current_option( mCurrentOption );
|
|
EMenuOption initial_option( AsMenuOption( current_option ) );
|
|
|
|
do
|
|
{
|
|
current_option++;
|
|
looped = AsMenuOption( current_option ) == initial_option;
|
|
}
|
|
while( !IsOptionValid( AsMenuOption( current_option ) ) && !looped );
|
|
|
|
return current_option;
|
|
}
|
|
|
|
|
|
//
|
|
|
|
bool IMainMenuScreen::IsOptionValid( EMenuOption option ) const
|
|
{
|
|
// Rom Settings is only valid if a rom has already been selected
|
|
if( option == MO_SELECTED_ROM )
|
|
{
|
|
return !mRomFilename.empty();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
void IMainMenuScreen::Update( float elapsed_time, const v2 & stick, u32 old_buttons, u32 new_buttons )
|
|
{
|
|
if(old_buttons != new_buttons)
|
|
{
|
|
if(new_buttons & PSP_CTRL_LTRIGGER)
|
|
{
|
|
mCurrentOption = GetPreviousValidOption();
|
|
new_buttons &= ~PSP_CTRL_LTRIGGER;
|
|
}
|
|
if(new_buttons & PSP_CTRL_RTRIGGER)
|
|
{
|
|
mCurrentOption = GetNextValidOption();
|
|
new_buttons &= ~PSP_CTRL_RTRIGGER;
|
|
}
|
|
}
|
|
|
|
// Approach towards target
|
|
mCurrentDisplayOption = mCurrentDisplayOption + (mCurrentOption - mCurrentDisplayOption) * 0.1f;
|
|
|
|
mOptionComponents[ GetCurrentOption() ]->Update( elapsed_time, stick, old_buttons, new_buttons );
|
|
}
|
|
|
|
|
|
//
|
|
|
|
void IMainMenuScreen::Render()
|
|
{
|
|
mpContext->ClearBackground();
|
|
|
|
|
|
c32 valid_colour( mpContext->GetDefaultTextColour() );
|
|
c32 invalid_colour( 200, 200, 200 );
|
|
|
|
f32 min_scale( 0.60f );
|
|
f32 max_scale( 1.0f );
|
|
|
|
s32 SCREEN_LEFT = 20;
|
|
s32 SCREEN_RIGHT = SCREEN_WIDTH - 20;
|
|
|
|
mpContext->SetFontStyle( CUIContext::FS_HEADING );
|
|
|
|
s32 y( MENU_TOP + mpContext->GetFontHeight() );
|
|
|
|
for( s32 i = -2; i <= 2; ++i )
|
|
{
|
|
EMenuOption option( AsMenuOption( mCurrentOption + i ) );
|
|
c32 text_col( IsOptionValid( option ) ? valid_colour : invalid_colour );
|
|
const char * option_text( gMenuOptionNames[ option ] );
|
|
u32 text_width( mpContext->GetTextWidth( option_text ) );
|
|
|
|
f32 diff( f32( mCurrentOption + i ) - mCurrentDisplayOption );
|
|
f32 dist( fabsf( diff ) );
|
|
|
|
s32 centre( ( SCREEN_WIDTH - text_width ) / 2 );
|
|
s32 extreme( diff < 0 ? SCREEN_LEFT : s32( SCREEN_RIGHT - (text_width * min_scale) ) );
|
|
|
|
// Interpolate between central and extreme position and centre
|
|
f32 scale( max_scale + (min_scale - max_scale) * dist );
|
|
s32 x( s32( centre + (extreme - centre) * dist ) );
|
|
|
|
mpContext->DrawTextScale( x, y, scale, option_text, text_col );
|
|
}
|
|
|
|
mpContext->SetFontStyle( CUIContext::FS_REGULAR );
|
|
|
|
mOptionComponents[ GetCurrentOption() ]->Render();
|
|
}
|
|
|
|
|
|
//
|
|
|
|
void IMainMenuScreen::Run()
|
|
{
|
|
mIsFinished = false;
|
|
CUIScreen::Run();
|
|
|
|
// switch back to the emulator display
|
|
CGraphicsContext::Get().SwitchToChosenDisplay();
|
|
|
|
// Clear everything to black - looks a bit tidier
|
|
CGraphicsContext::Get().ClearAllSurfaces();
|
|
}
|
|
|
|
|
|
//
|
|
|
|
void IMainMenuScreen::OnRomSelected( const char * rom_filename )
|
|
{
|
|
u32 rom_size;
|
|
ECicType boot_type;
|
|
|
|
if(ROM_GetRomDetailsByFilename( rom_filename, &mRomID, &rom_size, &boot_type ))
|
|
{
|
|
mRomFilename = rom_filename;
|
|
mSelectedRomComponent->SetRomID( mRomID );
|
|
mCurrentOption = MO_SELECTED_ROM;
|
|
mCurrentDisplayOption = float( mCurrentOption ); // Snap to this
|
|
}
|
|
else
|
|
{
|
|
// XXXX Problem retrieving rom info- should report this!
|
|
mRomFilename = "";
|
|
}
|
|
}
|
|
|
|
|
|
// This feature is not really stable
|
|
|
|
void IMainMenuScreen::OnSavestateSelected( const char * savestate_filename )
|
|
{
|
|
// If the CPU is running we need to queue a request to load the state
|
|
// (and possibly switch roms). Otherwise we just load the rom directly
|
|
if( CPU_IsRunning() )
|
|
{
|
|
if( CPU_RequestLoadState( savestate_filename ) )
|
|
{
|
|
mIsFinished = true;
|
|
}
|
|
else
|
|
{
|
|
// Should report some kind of error
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const char * rom_filename = SaveState_GetRom(savestate_filename);
|
|
if( rom_filename == NULL )
|
|
{
|
|
// report error?
|
|
return;
|
|
}
|
|
|
|
System_Open(rom_filename);
|
|
|
|
if( !SaveState_LoadFromFile( savestate_filename ) )
|
|
{
|
|
// Should report some kind of error
|
|
}
|
|
|
|
mIsFinished = true;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
|
|
void IMainMenuScreen::OnStartEmulation()
|
|
{
|
|
System_Open(mRomFilename.c_str());
|
|
mIsFinished = true;
|
|
|
|
}
|
|
|
|
void DisplayRomsAndChoose(bool show_splash)
|
|
{
|
|
// switch back to the LCD display
|
|
CGraphicsContext::Get().SwitchToLcdDisplay();
|
|
|
|
CDrawText::Initialise();
|
|
|
|
CUIContext * p_context( CUIContext::Create() );
|
|
|
|
if(p_context != NULL)
|
|
{
|
|
|
|
if( show_splash )
|
|
{
|
|
CSplashScreen * p_splash( CSplashScreen::Create( p_context ) );
|
|
p_splash->Run();
|
|
delete p_splash;
|
|
}
|
|
|
|
CMainMenuScreen * p_main_menu( CMainMenuScreen::Create( p_context ) );
|
|
p_main_menu->Run();
|
|
delete p_main_menu;
|
|
}
|
|
|
|
delete p_context;
|
|
|
|
CDrawText::Destroy();
|
|
}
|
|
|