nestopia/source/win32/NstManagerMachine.cpp

240 lines
6.8 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
//
// This file is part of Nestopia.
//
// Nestopia 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.
//
// Nestopia 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 Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#include "NstResourceString.hpp"
#include "NstWindowUser.hpp"
#include "NstIoScreen.hpp"
#include "NstManager.hpp"
#include "NstManagerPreferences.hpp"
#include "NstManagerMachine.hpp"
#include "../core/api/NstApiMachine.hpp"
namespace Nestopia
{
namespace Managers
{
NST_COMPILE_ASSERT
(
IDM_MACHINE_SYSTEM_NTSC == IDM_MACHINE_SYSTEM_AUTO + 1 &&
IDM_MACHINE_SYSTEM_PAL == IDM_MACHINE_SYSTEM_AUTO + 2
);
Machine::Machine(Emulator& e,const Configuration& cfg,Window::Menu& m,const Preferences& p)
:
Manager ( e, m, this, &Machine::OnEmuEvent ),
preferences ( p )
{
{
static const Window::Menu::CmdHandler::Entry<Machine> commands[] =
{
{ IDM_MACHINE_POWER, &Machine::OnCmdPower },
{ IDM_MACHINE_RESET_SOFT, &Machine::OnCmdReset },
{ IDM_MACHINE_RESET_HARD, &Machine::OnCmdReset },
{ IDM_MACHINE_PAUSE, &Machine::OnCmdPause },
{ IDM_MACHINE_SYSTEM_AUTO, &Machine::OnCmdSystem },
{ IDM_MACHINE_SYSTEM_NTSC, &Machine::OnCmdSystem },
{ IDM_MACHINE_SYSTEM_PAL, &Machine::OnCmdSystem }
};
menu.Commands().Add( this, commands );
}
{
const GenericString type( cfg["machine"]["region"].Str() );
SetRegion
(
type == L"ntsc" ? IDM_MACHINE_SYSTEM_NTSC :
type == L"pal" ? IDM_MACHINE_SYSTEM_PAL :
IDM_MACHINE_SYSTEM_AUTO
);
}
UpdateMenu();
UpdateMenuPowerState();
}
void Machine::Save(Configuration& cfg) const
{
cfg["machine"]["region"].Str() =
(
menu[IDM_MACHINE_SYSTEM_AUTO].Checked() ? "auto" :
Nes::Machine(emulator).Is(Nes::Machine::NTSC) ? "ntsc" :
"pal"
);
}
void Machine::UpdateMenu() const
{
const bool on = emulator.IsOn();
const bool reset = (on && emulator.GetPlayer() == Emulator::MASTER);
const bool pause = (on && emulator.NetPlayers() == 0);
menu[IDM_MACHINE_POWER].Text() << Resource::String( on ? IDS_MENU_POWER_OFF : IDS_MENU_POWER_ON );
menu[IDM_MACHINE_RESET_SOFT].Enable( reset );
menu[IDM_MACHINE_RESET_HARD].Enable( reset );
menu[IDM_POS_MACHINE][IDM_POS_MACHINE_RESET].Enable( reset );
menu[IDM_MACHINE_PAUSE].Enable( pause );
}
void Machine::UpdateMenuPowerState() const
{
menu[IDM_MACHINE_POWER].Enable( emulator.IsImage() && emulator.NetPlayers() == 0 );
}
bool Machine::SetRegion(const uint id) const
{
const Nes::Result result = Nes::Machine(emulator).SetMode
(
id == IDM_MACHINE_SYSTEM_AUTO ? Nes::Machine(emulator).GetDesiredMode() :
id == IDM_MACHINE_SYSTEM_NTSC ? Nes::Machine::NTSC : Nes::Machine::PAL
);
if (NES_SUCCEEDED(result))
{
menu[id].Check( IDM_MACHINE_SYSTEM_AUTO, IDM_MACHINE_SYSTEM_PAL );
return result != Nes::RESULT_NOP;
}
return false;
}
void Machine::OnCmdPower(uint)
{
if (emulator.IsOn())
{
if
(
!preferences[Preferences::CONFIRM_RESET] ||
Window::User::Confirm( IDS_ARE_YOU_SURE, IDS_MACHINE_POWER_OFF_TITLE )
)
{
if (emulator.Power( false ))
Io::Screen() << Resource::String(IDS_SCREEN_POWER_OFF);
}
}
else if (emulator.Power( true ))
{
Io::Screen() << Resource::String(IDS_SCREEN_POWER_ON);
}
}
void Machine::OnCmdReset(uint hard)
{
if
(
!preferences[Preferences::CONFIRM_RESET] ||
Window::User::Confirm( IDS_ARE_YOU_SURE, IDS_MACHINE_RESET_TITLE )
)
emulator.SendCommand( Emulator::COMMAND_RESET, hard == IDM_MACHINE_RESET_HARD );
Resume();
}
void Machine::OnCmdPause(uint)
{
const bool pause = !emulator.Paused();
emulator.Pause( pause );
Io::Screen() << Resource::String(pause ? IDS_SCREEN_PAUSE : IDS_SCREEN_RESUME);
if (!pause)
Resume();
}
void Machine::OnCmdSystem(uint id)
{
if (SetRegion( id ))
Io::Screen() << Resource::String(Nes::Machine(emulator).Is(Nes::Machine::NTSC) ? IDS_SCREEN_NTSC : IDS_SCREEN_PAL);
Resume();
}
void Machine::OnEmuEvent(const Emulator::Event event,Emulator::Data)
{
switch (event)
{
case Emulator::EVENT_RESET_SOFT:
case Emulator::EVENT_RESET_HARD:
Io::Screen() << Resource::String(event == Emulator::EVENT_RESET_HARD ? IDS_SCREEN_RESET_HARD : IDS_SCREEN_RESET_SOFT);
break;
case Emulator::EVENT_MODE_NTSC:
case Emulator::EVENT_MODE_PAL:
if (menu[IDM_MACHINE_SYSTEM_AUTO].Unchecked())
menu[event == Emulator::EVENT_MODE_NTSC ? IDM_MACHINE_SYSTEM_NTSC : IDM_MACHINE_SYSTEM_PAL].Check( IDM_MACHINE_SYSTEM_AUTO, IDM_MACHINE_SYSTEM_PAL );
break;
case Emulator::EVENT_PAUSE:
case Emulator::EVENT_RESUME:
menu[IDM_MACHINE_PAUSE].Check( event == Emulator::EVENT_PAUSE );
break;
case Emulator::EVENT_MOVIE_PLAYING:
case Emulator::EVENT_MOVIE_PLAYING_STOPPED:
case Emulator::EVENT_MOVIE_RECORDING:
case Emulator::EVENT_MOVIE_RECORDING_STOPPED:
{
const bool noplay = (event != Emulator::EVENT_MOVIE_PLAYING);
const bool stopped = (event == Emulator::EVENT_MOVIE_PLAYING_STOPPED || event == Emulator::EVENT_MOVIE_RECORDING_STOPPED);
menu[IDM_MACHINE_RESET_SOFT].Enable( noplay );
menu[IDM_MACHINE_RESET_HARD].Enable( noplay );
menu[IDM_POS_MACHINE][IDM_POS_MACHINE_RESET].Enable( noplay );
for (uint i=IDM_MACHINE_SYSTEM_AUTO; i <= IDM_MACHINE_SYSTEM_PAL; ++i)
menu[i].Enable( stopped );
break;
}
case Emulator::EVENT_POWER_ON:
case Emulator::EVENT_POWER_OFF:
UpdateMenu();
break;
case Emulator::EVENT_LOAD:
case Emulator::EVENT_UNLOAD:
UpdateMenuPowerState();
if (emulator.NetPlayers())
{
const bool enable = (event == Emulator::EVENT_UNLOAD);
menu[IDM_POS_MACHINE][IDM_POS_MACHINE_REGION].Enable( enable );
for (uint i=IDM_MACHINE_SYSTEM_AUTO; i <= IDM_MACHINE_SYSTEM_PAL; ++i)
menu[i].Enable( enable );
}
break;
}
}
}
}