mirror of
https://github.com/0ldsk00l/nestopia.git
synced 2025-04-02 10:31:51 -04:00
326 lines
8.7 KiB
C++
326 lines
8.7 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 "NstIoLog.hpp"
|
|
#include "NstIoStream.hpp"
|
|
#include "NstIoFile.hpp"
|
|
#include "NstApplicationInstance.hpp"
|
|
#include "NstWindowParam.hpp"
|
|
#include "NstWindowDropFiles.hpp"
|
|
#include "NstManagerPaths.hpp"
|
|
#include "NstDialogNetPlay.hpp"
|
|
#include "../core/NstXml.hpp"
|
|
#include <CommCtrl.h>
|
|
|
|
namespace Nestopia
|
|
{
|
|
namespace Window
|
|
{
|
|
struct Netplay::Handlers
|
|
{
|
|
static const MsgHandler::Entry<Netplay> messages[];
|
|
static const MsgHandler::Entry<Netplay> commands[];
|
|
static const Control::NotificationHandler::Entry<Netplay> notifications[];
|
|
};
|
|
|
|
const MsgHandler::Entry<Netplay> Netplay::Handlers::messages[] =
|
|
{
|
|
{ WM_INITDIALOG, &Netplay::OnInitDialog },
|
|
{ WM_DROPFILES, &Netplay::OnDropFiles }
|
|
};
|
|
|
|
const MsgHandler::Entry<Netplay> Netplay::Handlers::commands[] =
|
|
{
|
|
{ IDC_NETPLAY_ADD, &Netplay::OnAdd },
|
|
{ IDC_NETPLAY_REMOVE, &Netplay::OnRemove },
|
|
{ IDC_NETPLAY_CLEAR, &Netplay::OnClear },
|
|
{ IDC_NETPLAY_DEFAULT, &Netplay::OnDefault },
|
|
{ IDC_NETPLAY_LAUNCH, &Netplay::OnLaunch },
|
|
{ IDC_NETPLAY_PLAY_FULLSCREEN, &Netplay::OnFullscreen }
|
|
};
|
|
|
|
const Control::NotificationHandler::Entry<Netplay> Netplay::Handlers::notifications[] =
|
|
{
|
|
{ LVN_KEYDOWN, &Netplay::OnKeyDown },
|
|
{ LVN_ITEMCHANGED, &Netplay::OnItemChanged },
|
|
{ LVN_INSERTITEM, &Netplay::OnInsertItem },
|
|
{ LVN_DELETEITEM, &Netplay::OnDeleteItem }
|
|
};
|
|
|
|
bool Netplay::Games::Less::operator () (const Path& a,const Path& b) const
|
|
{
|
|
return a.Target().File() < b.Target().File();
|
|
}
|
|
|
|
Netplay::Games::Games()
|
|
: state(UNINITIALIZED) {}
|
|
|
|
Netplay::Netplay(Managers::Emulator& e,const Managers::Paths& p,bool fullscreen)
|
|
:
|
|
dialog ( IDD_NETPLAY, this, Handlers::messages, Handlers::commands ),
|
|
doFullscreen ( fullscreen ),
|
|
paths ( p ),
|
|
emulator ( e ),
|
|
notifications ( IDC_NETPLAY_GAMELIST, dialog.Messages(), this, Handlers::notifications )
|
|
{
|
|
}
|
|
|
|
Netplay::~Netplay()
|
|
{
|
|
}
|
|
|
|
void Netplay::LoadFile()
|
|
{
|
|
try
|
|
{
|
|
//const Path path( Application::Instance::GetExePath(L"netplaylist.xml") );
|
|
const Path path( Application::Instance::GetConfigPath(L"netplaylist.xml") );//bg
|
|
|
|
if (path.FileExists())
|
|
{
|
|
typedef Nes::Core::Xml Xml;
|
|
Xml xml;
|
|
|
|
{
|
|
Io::Stream::In stream( path );
|
|
xml.Read( stream );
|
|
}
|
|
|
|
if (!xml.GetRoot().IsType( L"netplaylist" ))
|
|
throw 1;
|
|
|
|
for (Xml::Node node(xml.GetRoot().GetFirstChild()); node; node=node.GetNextSibling())
|
|
{
|
|
if (!node.IsType( L"file" ))
|
|
throw 1;
|
|
|
|
Add( node.GetValue() );
|
|
}
|
|
|
|
Io::Log() << "Netplay: loaded game list from \"netplaylist.xml\"\r\n";
|
|
}
|
|
else
|
|
{
|
|
Io::Log() << "Netplay: game list file \"netplaylist.xml\" not present..\r\n";
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
games.state = Games::DIRTY;
|
|
Io::Log() << "Netplay: warning, couldn't load game list \"netplaylist.xml\"!\r\n";
|
|
}
|
|
}
|
|
|
|
void Netplay::SaveFile() const
|
|
{
|
|
if (games.state == Games::DIRTY)
|
|
{
|
|
//const Path path( Application::Instance::GetExePath(L"netplaylist.xml") );
|
|
const Path path( Application::Instance::GetConfigPath(L"netplaylist.xml") );//bg
|
|
|
|
if (!games.paths.empty())
|
|
{
|
|
try
|
|
{
|
|
typedef Nes::Core::Xml Xml;
|
|
|
|
Xml xml;
|
|
Xml::Node root( xml.Create( L"netplaylist" ) );
|
|
root.AddAttribute( L"version", L"1.0" );
|
|
|
|
for (Games::Paths::const_iterator it(games.paths.begin()), end(games.paths.end()); it != end; ++it)
|
|
root.AddChild( L"file", it->Ptr() );
|
|
|
|
Io::Stream::Out stream( path );
|
|
xml.Write( root, stream );
|
|
|
|
Io::Log() << "Netplay: saved game list to \"netplaylist.xml\"\r\n";
|
|
}
|
|
catch (...)
|
|
{
|
|
Io::Log() << "Netplay: warning, couldn't save game list to \"netplaylist.xml\"!\r\n";
|
|
}
|
|
}
|
|
else if (path.FileExists())
|
|
{
|
|
if (Io::File::Delete( path.Ptr() ))
|
|
Io::Log() << "Netplay: game list empty, deleted \"netplaylist.xml\"\r\n";
|
|
else
|
|
Io::Log() << "Netplay: warning, couldn't delete \"netplaylist.xml\"!\r\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
wcstring Netplay::GetPath(wcstring const path) const
|
|
{
|
|
Games::Paths::const_iterator it(games.paths.find( path ));
|
|
return it != games.paths.end() ? it->Ptr() : NULL;
|
|
}
|
|
|
|
void Netplay::Add(Path path)
|
|
{
|
|
enum
|
|
{
|
|
TYPES = Managers::Paths::File::GAME|Managers::Paths::File::ARCHIVE
|
|
};
|
|
|
|
if (path.Length() && games.paths.size() < Games::LIMIT && paths.CheckFile( path, TYPES ) && games.paths.insert( path ).second)
|
|
{
|
|
games.state = Games::DIRTY;
|
|
|
|
if (dialog)
|
|
dialog.ListView( IDC_NETPLAY_GAMELIST ).Add( path.Target().File() );
|
|
}
|
|
}
|
|
|
|
ibool Netplay::OnInitDialog(Param&)
|
|
{
|
|
dialog.CheckBox( IDC_NETPLAY_PLAY_FULLSCREEN ).Check( doFullscreen );
|
|
dialog.CheckBox( IDC_NETPLAY_REMOVE ).Disable();
|
|
|
|
if (games.state == Games::UNINITIALIZED)
|
|
{
|
|
LoadFile();
|
|
}
|
|
else
|
|
{
|
|
Control::ListView list( dialog.ListView( IDC_NETPLAY_GAMELIST ) );
|
|
list.Reserve( games.paths.size() );
|
|
|
|
for (Games::Paths::const_iterator it(games.paths.begin()), end(games.paths.end()); it != end; ++it)
|
|
list.Add( it->Target().File().Ptr() );
|
|
}
|
|
|
|
dialog.CheckBox( IDC_NETPLAY_CLEAR ).Enable( games.paths.size() );
|
|
dialog.CheckBox( IDC_NETPLAY_LAUNCH ).Enable( games.paths.size() );
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnAdd(Param& param)
|
|
{
|
|
if (param.Button().Clicked())
|
|
Add( paths.BrowseLoad(Managers::Paths::File::GAME|Managers::Paths::File::ARCHIVE) );
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnRemove(Param& param)
|
|
{
|
|
if (param.Button().Clicked())
|
|
dialog.ListView( IDC_NETPLAY_GAMELIST ).Selection().Delete();
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnClear(Param& param)
|
|
{
|
|
if (param.Button().Clicked())
|
|
dialog.ListView( IDC_NETPLAY_GAMELIST ).Clear();
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnDefault(Param& param)
|
|
{
|
|
if (param.Button().Clicked())
|
|
{
|
|
doFullscreen = false;
|
|
dialog.CheckBox( IDC_NETPLAY_PLAY_FULLSCREEN ).Check( false );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnLaunch(Param& param)
|
|
{
|
|
if (param.Button().Clicked())
|
|
dialog.Close( LAUNCH );
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnFullscreen(Param& param)
|
|
{
|
|
if (param.Button().Clicked())
|
|
doFullscreen = dialog.CheckBox( IDC_NETPLAY_PLAY_FULLSCREEN ).Checked();
|
|
|
|
return true;
|
|
}
|
|
|
|
ibool Netplay::OnDropFiles(Param& param)
|
|
{
|
|
DropFiles dropFiles( param );
|
|
|
|
if (dropFiles.Inside( dialog.ListView( IDC_NETPLAY_GAMELIST ).GetWindow() ))
|
|
{
|
|
for (uint i=0, n=dropFiles.Size(); i < n; ++i)
|
|
Add( dropFiles[i] );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Netplay::OnKeyDown(const NMHDR& nmhdr)
|
|
{
|
|
switch (reinterpret_cast<const NMLVKEYDOWN&>(nmhdr).wVKey)
|
|
{
|
|
case VK_INSERT: dialog.PostCommand( IDC_NETPLAY_ADD ); break;
|
|
case VK_DELETE: dialog.PostCommand( IDC_NETPLAY_REMOVE ); break;
|
|
}
|
|
}
|
|
|
|
void Netplay::OnItemChanged(const NMHDR& nmhdr)
|
|
{
|
|
const NMLISTVIEW& nm = reinterpret_cast<const NMLISTVIEW&>(nmhdr);
|
|
|
|
if ((nm.uOldState ^ nm.uNewState) & LVIS_SELECTED)
|
|
dialog.CheckBox( IDC_NETPLAY_REMOVE ).Enable( nm.uNewState & LVIS_SELECTED );
|
|
}
|
|
|
|
void Netplay::OnInsertItem(const NMHDR&)
|
|
{
|
|
dialog.CheckBox( IDC_NETPLAY_CLEAR ).Enable();
|
|
dialog.CheckBox( IDC_NETPLAY_LAUNCH ).Enable();
|
|
}
|
|
|
|
void Netplay::OnDeleteItem(const NMHDR& nmhdr)
|
|
{
|
|
Games::Paths::iterator it(games.paths.begin());
|
|
|
|
for (int i=reinterpret_cast<const NMLISTVIEW&>(nmhdr).iItem; i > 0; --i)
|
|
++it;
|
|
|
|
games.paths.erase( it );
|
|
games.state = Games::DIRTY;
|
|
|
|
if (dialog.ListView( IDC_NETPLAY_GAMELIST ).Size() <= 1)
|
|
{
|
|
dialog.CheckBox( IDC_NETPLAY_CLEAR ).Disable();
|
|
dialog.CheckBox( IDC_NETPLAY_LAUNCH ).Disable();
|
|
dialog.CheckBox( IDC_NETPLAY_REMOVE ).Disable();
|
|
}
|
|
}
|
|
}
|
|
}
|