changed dolphinWX a bit and added memcard manager

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@234 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2008-08-17 16:41:53 +00:00
parent 9ca343743a
commit 51317997f5
9 changed files with 1059 additions and 262 deletions

View File

@ -26,6 +26,7 @@
#include "Core.h"
#include "PluginOptions.h"
#include "PluginManager.h"
#include "MemcardManager.h"
#include "wx/mstream.h"
@ -88,9 +89,11 @@ EVT_MENU(IDM_CONFIG_GFX_PLUGIN, CFrame::OnPluginGFX)
EVT_MENU(IDM_CONFIG_DSP_PLUGIN, CFrame::OnPluginDSP)
EVT_MENU(IDM_CONFIG_PAD_PLUGIN, CFrame::OnPluginPAD)
EVT_MENU(IDM_BROWSE, CFrame::OnBrowse)
EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen)
EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore)
EVT_MENU(IDM_TOGGLE_THROTTLE, CFrame::OnToggleThrottle)
EVT_MENU(IDM_TOGGLE_TOOLBAR, CFrame::OnToggleToolbar)
EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage)
END_EVENT_TABLE()
@ -154,136 +157,68 @@ CFrame::CFrame(wxFrame* parent,
}
void
CFrame::CreateMenu()
void CFrame::CreateMenu()
{
delete m_pMenuBar;
m_pMenuBar = new wxMenuBar(wxMB_DOCKABLE);
// file menu
{
wxMenu* fileMenu = new wxMenu;
{
wxMenuItem* pItem = fileMenu->Append(wxID_OPEN, _T("&Open..."));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_FileOpen]);
}
{
wxMenuItem* pItem = fileMenu->Append(wxID_REFRESH, _T("&Refresh"));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_Refresh]);
}
wxMenu* fileMenu = new wxMenu;
fileMenu->Append(wxID_OPEN, _T("&Open..."));
fileMenu->Append(wxID_REFRESH, _T("&Refresh"));
fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs..."));
fileMenu->AppendSeparator();
m_pMenuItemPlay = new wxMenuItem(fileMenu, IDM_PLAY, _T("&Play"));
fileMenu->Append(m_pMenuItemPlay);
m_pMenuItemStop = new wxMenuItem(fileMenu, IDM_STOP, _T("&Stop"));
fileMenu->Append(m_pMenuItemStop);
{
wxMenuItem* pItem = fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs..."));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_Browse]);
}
/*
fileMenu->AppendSeparator();
wxMenuItem* LoadState = fileMenu->Append(IDM_LOADSTATE, _T("&Load State..."));
LoadState->Enable(false);
wxMenuItem* SaveState = fileMenu->Append(IDM_SAVESTATE, _T("&Save State..."));
SaveState->Enable(false);
*/
fileMenu->AppendSeparator();
fileMenu->Append(wxID_EXIT, _T("E&xit"), _T(""));
m_pMenuBar->Append(fileMenu, _T("&File"));
}
/*fileMenu->AppendSeparator();
wxMenuItem* LoadState = fileMenu->Append(IDM_LOADSTATE, _T("&Load State..."));
LoadState->Enable(false);
wxMenuItem* SaveState = fileMenu->Append(IDM_SAVESTATE, _T("&Save State..."));
SaveState->Enable(false);*/
// Game menu
{
wxMenu* pGameMenu = new wxMenu;
{
wxMenuItem *pItem = new wxMenuItem(pGameMenu, IDM_EDITPATCHFILE, wxString::FromAscii("Edit patch file"));
pGameMenu->Append(pItem);
}
}
fileMenu->AppendSeparator();
fileMenu->Append(wxID_EXIT, _T("E&xit"), _T(""));
m_pMenuBar->Append(fileMenu, _T("&File"));
// emulation menu
{
wxMenu* pEmulationMenu = new wxMenu;
// play
{
m_pMenuItemPlay = new wxMenuItem(pEmulationMenu, IDM_PLAY, _T("&Play"));
m_pMenuItemPlay->SetBitmap(m_BitmapsMenu[Toolbar_Play]);
#ifdef WIN32
m_pMenuItemPlay->SetDisabledBitmap(m_BitmapsMenu[Toolbar_Play_Dis]); //Linux Doesn't have
#endif
pEmulationMenu->Append(m_pMenuItemPlay);
}
// stop
{
m_pMenuItemStop = new wxMenuItem(pEmulationMenu, IDM_STOP, _T("&Stop"));
m_pMenuItemStop->SetBitmap(m_BitmapsMenu[Toolbar_Stop]);
#ifdef WIN32
m_pMenuItemStop->SetDisabledBitmap(m_BitmapsMenu[Toolbar_Stop_Dis]); //Linux doesn't have
#endif
pEmulationMenu->Append(m_pMenuItemStop);
}
pEmulationMenu->AppendSeparator();
{
// full screen
wxMenuItem* pItem = new wxMenuItem(pEmulationMenu, IDM_TOGGLE_FULLSCREEN, _T("&Fullscreen"));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_FullScreen]);
pEmulationMenu->Append(pItem);
}
{
// dual core
wxMenuItem* pItem = new wxMenuItem(pEmulationMenu, IDM_TOGGLE_DUALCORE, _T("&Dual Core (instable!)"), wxEmptyString, wxITEM_CHECK);
pEmulationMenu->Append(pItem);
pItem->Check(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore);
}
{
// throttling
wxMenuItem* pItem = new wxMenuItem(pEmulationMenu, IDM_TOGGLE_THROTTLE, _T("&Speed throttle"), wxEmptyString, wxITEM_CHECK);
pEmulationMenu->Append(pItem);
pItem->Check(SConfig::GetInstance().m_LocalCoreStartupParameter.bThrottle);
}
m_pMenuBar->Append(pEmulationMenu, _T("&Emulation"));
}
// options menu
wxMenu* pOptionsMenu = new wxMenu;
m_pPluginOptions = new wxMenuItem(pOptionsMenu, IDM_PLUGIN_OPTIONS, _T("&Select plugins"));
pOptionsMenu->Append(m_pPluginOptions);
pOptionsMenu->AppendSeparator();
pOptionsMenu->Append(IDM_CONFIG_GFX_PLUGIN, _T("&GFX settings"));
pOptionsMenu->Append(IDM_CONFIG_DSP_PLUGIN, _T("&DSP settings"));
pOptionsMenu->Append(IDM_CONFIG_PAD_PLUGIN, _T("&PAD settings"));
pOptionsMenu->AppendSeparator();
pOptionsMenu->Append(IDM_TOGGLE_FULLSCREEN, _T("&Fullscreen"));
pOptionsMenu->AppendCheckItem(IDM_TOGGLE_DUALCORE, _T("&Dual-core (instable!)"));
pOptionsMenu->Check(IDM_TOGGLE_DUALCORE, SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore);
pOptionsMenu->AppendCheckItem(IDM_TOGGLE_THROTTLE, _T("&Enable throttle"));
pOptionsMenu->Check(IDM_TOGGLE_THROTTLE, SConfig::GetInstance().m_LocalCoreStartupParameter.bThrottle);
m_pMenuBar->Append(pOptionsMenu, _T("&Options"));
// plugin menu
{
wxMenu* pPluginMenu = new wxMenu;
{
m_pPluginOptions = pPluginMenu->Append(IDM_PLUGIN_OPTIONS, _T("&Choose Plugins..."));
m_pPluginOptions->SetBitmap(m_BitmapsMenu[Toolbar_PluginOptions]);
#ifdef WIN32
m_pPluginOptions->SetDisabledBitmap(m_BitmapsMenu[Toolbar_PluginOptions_Dis]); //Linux doesn't have
#endif
}
pPluginMenu->AppendSeparator();
{
wxMenuItem* pItem = pPluginMenu->Append(IDM_CONFIG_GFX_PLUGIN, _T("&GFX plugin settings..."));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_PluginGFX]);
}
{
wxMenuItem* pItem = pPluginMenu->Append(IDM_CONFIG_DSP_PLUGIN, _T("&DSP plugin settings..."));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_PluginDSP]);
}
{
wxMenuItem* pItem = pPluginMenu->Append(IDM_CONFIG_PAD_PLUGIN, _T("&PAD plugin settings..."));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_PluginPAD]);
}
m_pMenuBar->Append(pPluginMenu, _T("&Plugins"));
}
// misc menu
wxMenu* miscMenu = new wxMenu;
miscMenu->Append(IDM_MEMCARD, _T("&Memory card manager"));
miscMenu->AppendCheckItem(IDM_TOGGLE_TOOLBAR, _T("&Enable toolbar"));
miscMenu->Check(IDM_TOGGLE_TOOLBAR, true);
m_pMenuBar->Append(miscMenu, _T("&Misc"));
// help menu
{
wxMenu* helpMenu = new wxMenu;
{
wxMenuItem* pItem = helpMenu->Append(wxID_HELP, _T("&Help"));
pItem->SetBitmap(m_BitmapsMenu[Toolbar_Help]);
}
helpMenu->Append(wxID_HELP, _T("&About..."));
m_pMenuBar->Append(helpMenu, _T("&Help"));
}
wxMenu* helpMenu = new wxMenu;
/*helpMenu->Append(wxID_HELP, _T("&Help"));
re-enable when there's something useful to display*/
helpMenu->Append(wxID_HELP, _T("&About..."));
m_pMenuBar->Append(helpMenu, _T("&Help"));
// Associate the menu bar with the frame
SetMenuBar(m_pMenuBar);
}
void
CFrame::PopulateToolbar(wxToolBar* toolBar)
void CFrame::PopulateToolbar(wxToolBar* toolBar)
{
int w = m_Bitmaps[Toolbar_FileOpen].GetWidth(),
h = m_Bitmaps[Toolbar_FileOpen].GetHeight();
@ -299,11 +234,11 @@ CFrame::PopulateToolbar(wxToolBar* toolBar)
toolBar->SetToolDisabledBitmap(IDM_STOP, m_Bitmaps[Toolbar_Stop_Dis]);
toolBar->AddTool(IDM_TOGGLE_FULLSCREEN, _T("Fullscr."), m_Bitmaps[Toolbar_FullScreen], _T("Toggle Fullscreen"));
toolBar->AddSeparator();
toolBar->AddTool(IDM_PLUGIN_OPTIONS, _T("Plugins"), m_Bitmaps[Toolbar_PluginOptions], _T("Plugin Selection..."));
toolBar->AddTool(IDM_PLUGIN_OPTIONS, _T("Plugins"), m_Bitmaps[Toolbar_PluginOptions], _T("Select plugins"));
toolBar->SetToolDisabledBitmap(IDM_PLUGIN_OPTIONS, m_Bitmaps[Toolbar_PluginOptions_Dis]);
toolBar->AddTool(IDM_CONFIG_GFX_PLUGIN, _T("GFX"), m_Bitmaps[Toolbar_PluginGFX], _T("GFX Plugin..."));
toolBar->AddTool(IDM_CONFIG_DSP_PLUGIN, _T("DSP"), m_Bitmaps[Toolbar_PluginDSP], _T("DSP Plugin..."));
toolBar->AddTool(IDM_CONFIG_PAD_PLUGIN, _T("PAD"), m_Bitmaps[Toolbar_PluginPAD], _T("PAD Plugin..."));
toolBar->AddTool(IDM_CONFIG_GFX_PLUGIN, _T("GFX"), m_Bitmaps[Toolbar_PluginGFX], _T("GFX settings"));
toolBar->AddTool(IDM_CONFIG_DSP_PLUGIN, _T("DSP"), m_Bitmaps[Toolbar_PluginDSP], _T("DSP settings"));
toolBar->AddTool(IDM_CONFIG_PAD_PLUGIN, _T("PAD"), m_Bitmaps[Toolbar_PluginPAD], _T("PAD settings"));
toolBar->AddSeparator();
toolBar->AddTool(wxID_HELP, _T("About"), m_Bitmaps[Toolbar_Help], _T("About Dolphin"));
@ -313,8 +248,7 @@ CFrame::PopulateToolbar(wxToolBar* toolBar)
}
void
CFrame::RecreateToolbar()
void CFrame::RecreateToolbar()
{
// delete and recreate the toolbar
wxToolBarBase* toolBar = GetToolBar();
@ -331,8 +265,7 @@ CFrame::RecreateToolbar()
}
void
CFrame::InitBitmaps()
void CFrame::InitBitmaps()
{
// load orignal size 48x48
m_Bitmaps[Toolbar_FileOpen] = wxGetBitmapFromMemory(toolbar_file_open_png);
@ -356,17 +289,10 @@ CFrame::InitBitmaps()
{
m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(24, 24));
}
// scale to 15x15 for menu
for (size_t n = Toolbar_FileOpen; n < WXSIZEOF(m_Bitmaps); n++)
{
m_BitmapsMenu[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(15, 15));
}
}
void
CFrame::OnOpen(wxCommandEvent& WXUNUSED (event))
void CFrame::OnOpen(wxCommandEvent& WXUNUSED (event))
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
return;
@ -391,8 +317,7 @@ CFrame::OnOpen(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnQuit(wxCommandEvent& WXUNUSED (event))
void CFrame::OnQuit(wxCommandEvent& WXUNUSED (event))
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
@ -404,8 +329,7 @@ CFrame::OnQuit(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnAbout(wxCommandEvent& WXUNUSED (event))
void CFrame::OnAbout(wxCommandEvent& WXUNUSED (event))
{
wxAboutDialogInfo info;
info.AddDeveloper(_T("ector"));
@ -424,15 +348,13 @@ CFrame::OnAbout(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnHelp(wxCommandEvent& WXUNUSED (event))
void CFrame::OnHelp(wxCommandEvent& WXUNUSED (event))
{
wxMessageBox(wxString::FromAscii("missing OnHelp()"));
}
void
CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
@ -450,8 +372,7 @@ CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnStop(wxCommandEvent& WXUNUSED (event))
void CFrame::OnStop(wxCommandEvent& WXUNUSED (event))
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
@ -461,8 +382,7 @@ CFrame::OnStop(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event))
void CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event))
{
if (m_GameListCtrl)
{
@ -471,16 +391,14 @@ CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnPluginOptions(wxCommandEvent& WXUNUSED (event))
void CFrame::OnPluginOptions(wxCommandEvent& WXUNUSED (event))
{
CPluginOptions PluginOptions(this);
PluginOptions.ShowModal();
}
void
CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event))
void CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event))
{
CPluginManager::GetInstance().OpenConfig(
GetHandle(),
@ -489,8 +407,7 @@ CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnPluginDSP(wxCommandEvent& WXUNUSED (event))
void CFrame::OnPluginDSP(wxCommandEvent& WXUNUSED (event))
{
CPluginManager::GetInstance().OpenConfig(
GetHandle(),
@ -499,8 +416,7 @@ CFrame::OnPluginDSP(wxCommandEvent& WXUNUSED (event))
}
void
CFrame::OnPluginPAD(wxCommandEvent& WXUNUSED (event))
void CFrame::OnPluginPAD(wxCommandEvent& WXUNUSED (event))
{
CPluginManager::GetInstance().OpenConfig(
GetHandle(),
@ -508,16 +424,18 @@ CFrame::OnPluginPAD(wxCommandEvent& WXUNUSED (event))
);
}
void
CFrame::OnBrowse(wxCommandEvent& WXUNUSED (event))
void CFrame::OnBrowse(wxCommandEvent& WXUNUSED (event))
{
m_GameListCtrl->BrowseForDirectory();
}
void CFrame::OnMemcard(wxCommandEvent& WXUNUSED (event))
{
CMemcardManager MemcardManager(this);
MemcardManager.ShowModal();
}
void
CFrame::OnHostMessage(wxCommandEvent& event)
void CFrame::OnHostMessage(wxCommandEvent& event)
{
switch (event.GetId())
{
@ -561,14 +479,12 @@ CFrame::OnHostMessage(wxCommandEvent& event)
}
}
void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event))
{
ShowFullScreen(true);
UpdateGUI();
}
void CFrame::OnToggleDualCore(wxCommandEvent& WXUNUSED (event))
{
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore = !SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore;
@ -581,6 +497,21 @@ void CFrame::OnToggleThrottle(wxCommandEvent& WXUNUSED (event))
SConfig::GetInstance().SaveSettings();
}
void CFrame::OnToggleToolbar(wxCommandEvent& event)
{
wxToolBarBase* toolBar = GetToolBar();
if (event.IsChecked())
{
CFrame::RecreateToolbar();
}
else
{
delete toolBar;
SetToolBar(NULL);
}
}
void CFrame::OnKeyDown(wxKeyEvent& event)
{
if (((event.GetKeyCode() == WXK_RETURN) && (event.GetModifiers() == wxMOD_ALT)) ||
@ -595,7 +526,6 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
}
}
void CFrame::UpdateGUI()
{
// buttons
@ -627,7 +557,6 @@ void CFrame::UpdateGUI()
GetToolBar()->SetToolNormalBitmap(IDM_PLAY, m_Bitmaps[Toolbar_Pause]);
GetToolBar()->SetToolShortHelp(IDM_PLAY, _T("Pause"));
m_pMenuItemPlay->SetBitmap(m_BitmapsMenu[Toolbar_Pause]);
m_pMenuItemPlay->SetText(_T("Pause"));
}
else
@ -635,7 +564,6 @@ void CFrame::UpdateGUI()
GetToolBar()->SetToolNormalBitmap(IDM_PLAY, m_Bitmaps[Toolbar_Play]);
GetToolBar()->SetToolShortHelp(IDM_PLAY, _T("Play"));
m_pMenuItemPlay->SetBitmap(m_BitmapsMenu[Toolbar_Play]);
m_pMenuItemPlay->SetText(_T("Play"));
}
}
@ -661,5 +589,3 @@ void CFrame::UpdateGUI()
}
}
}

View File

@ -64,9 +64,11 @@ class CFrame
void OnPlay(wxCommandEvent& event);
void OnStop(wxCommandEvent& event);
void OnBrowse(wxCommandEvent& event);
void OnMemcard(wxCommandEvent& event);
void OnToggleFullscreen(wxCommandEvent& event);
void OnToggleDualCore(wxCommandEvent& event);
void OnToggleThrottle(wxCommandEvent& event);
void OnToggleToolbar(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnHostMessage(wxCommandEvent& event);
@ -90,4 +92,3 @@ class CFrame
#endif // __FRAME_H_

View File

@ -25,6 +25,7 @@ enum
IDM_PLAY,
IDM_STOP,
IDM_BROWSE,
IDM_MEMCARD,
IDM_EDITPATCHFILE,
IDM_OPENCONTAININGFOLDER,
IDM_PLUGIN_OPTIONS,
@ -34,6 +35,7 @@ enum
IDM_TOGGLE_FULLSCREEN,
IDM_TOGGLE_DUALCORE,
IDM_TOGGLE_THROTTLE,
IDM_TOGGLE_TOOLBAR,
IDM_NOTIFYMAPLOADED,
IDM_UPDATELOGDISPLAY,
IDM_UPDATEDISASMDIALOG,

View File

@ -0,0 +1,254 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Globals.h"
#include "MemcardManager.h"
BEGIN_EVENT_TABLE(CMemcardManager, wxDialog)
EVT_CLOSE(CMemcardManager::OnClose)
EVT_RIGHT_DOWN(CMemcardManager::OnRightClick)
EVT_BUTTON(ID_COPYRIGHT,CMemcardManager::CopyClick)
EVT_BUTTON(ID_COPYLEFT,CMemcardManager::CopyClick)
EVT_BUTTON(ID_DELETERIGHT,CMemcardManager::DeleteClick)
EVT_BUTTON(ID_DELETELEFT,CMemcardManager::DeleteClick)
EVT_FILEPICKER_CHANGED(ID_MEMCARD1PATH,CMemcardManager::OnPathChange)
EVT_FILEPICKER_CHANGED(ID_MEMCARD2PATH,CMemcardManager::OnPathChange)
END_EVENT_TABLE()
CMemcardManager::CMemcardManager(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
: wxDialog(parent, id, title, position, size, style)
{
CreateGUIControls();
}
CMemcardManager::~CMemcardManager()
{
}
void CMemcardManager::CreateGUIControls()
{
// buttons
m_CopyRight = new wxButton(this, ID_COPYRIGHT, wxT("->Copy->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CopyLeft = new wxButton(this, ID_COPYLEFT, wxT("<-Copy<-"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_DeleteRight = new wxButton(this, ID_DELETERIGHT, wxT("Delete->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_DeleteLeft = new wxButton(this, ID_DELETELEFT, wxT("<-Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// sizers that double as wxStaticBoxes
sMemcard1 = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card 1"));
sMemcard2 = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card 2"));
// create the controls for both memcards
// will change Mem*.raw to *.raw, when loading invalid .raw files doesn't crash the app :/
m_Memcard1Path = new wxFilePickerCtrl(this, ID_MEMCARD1PATH, wxEmptyString, wxT("Choose a memory card:"),
wxT("Dolphin memcards (Mem*.raw)|Mem*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN);
m_Memcard2Path = new wxFilePickerCtrl(this, ID_MEMCARD2PATH, wxEmptyString, wxT("Choose a memory card:"),
wxT("Dolphin memcards (Mem*.raw)|Mem*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN);
m_Memcard1List = new wxListCtrl(this, ID_MEMCARD1LIST, wxDefaultPosition, wxSize(500,400),
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
m_Memcard2List = new wxListCtrl(this, ID_MEMCARD2LIST, wxDefaultPosition, wxSize(500,400),
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
// mmmm sizer goodness
wxBoxSizer* sButtons;
sButtons = new wxBoxSizer(wxVERTICAL);
sButtons->AddStretchSpacer(1);
sButtons->Add(m_CopyRight, 0, 0, 5);
sButtons->Add(m_CopyLeft, 0, 0, 5);
sButtons->Add(m_DeleteRight, 0, 0, 5);
sButtons->Add(m_DeleteLeft, 0, 0, 5);
sButtons->AddStretchSpacer(1);
sMemcard1->Add(m_Memcard1Path, 0, wxEXPAND|wxALL, 5);
sMemcard1->Add(m_Memcard1List, 1, wxEXPAND|wxALL, 5);
sMemcard2->Add(m_Memcard2Path, 0, wxEXPAND|wxALL, 5);
sMemcard2->Add(m_Memcard2List, 1, wxEXPAND|wxALL, 5);
//wxBoxSizer* sMain;
sMain = new wxBoxSizer(wxHORIZONTAL);
sMain->Add(sMemcard1, 1, wxEXPAND|wxALL, 5);
sMain->Add(sButtons, 0, wxEXPAND, 0);
sMain->Add(sMemcard2, 1, wxEXPAND|wxALL, 5);
CenterOnParent();
this->SetSizer(sMain);
sMain->SetSizeHints(this);
}
void CMemcardManager::OnClose(wxCloseEvent& WXUNUSED (event))
{
Destroy();
}
void CMemcardManager::OnPathChange(wxFileDirPickerEvent& event)
{
switch(event.GetId())
{
case ID_MEMCARD1PATH:
LoadMemcard1(event.GetPath());
break;
case ID_MEMCARD2PATH:
LoadMemcard2(event.GetPath());
break;
default:
break;
}
}
void CMemcardManager::OnRightClick(wxMouseEvent& event)
{
// Focus the clicked item.
//int flags;
//long item = HitTest(event.GetPosition(), flags);
//if (item != wxNOT_FOUND) {
// SetItemState(item, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
// wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
//}
//int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
//if (item == -1)
//{
// //not found
//}
//else
//{
// //found
//}
}
void CMemcardManager::CopyClick(wxCommandEvent& WXUNUSED (event))
{
}
void CMemcardManager::DeleteClick(wxCommandEvent& WXUNUSED (event))
{
}
// These next two functions really need to be merged - yet
// retain ability to only (re)load one card at a time.
void CMemcardManager::LoadMemcard1(const char *card1)
{
//wtf do these lines crash the app?
//if(memoryCard1) delete memoryCard1;
//if(memoryCard2) delete memoryCard2;
// WARNING: the memcards don't have much error checking, yet!
if(card1 && strlen(card1))
{
memoryCard1 = new GCMemcard(card1);
}
if(memoryCard1)
{
m_Memcard1List->Hide();
m_Memcard1List->ClearAll();
m_Memcard1List->InsertColumn(COLUMN_FILENAME, _T("filename"));
m_Memcard1List->InsertColumn(COLUMN_COMMENT1, _T("comment1"));
m_Memcard1List->InsertColumn(COLUMN_COMMENT2, _T("comment2"));
int nFiles = memoryCard1->GetNumFiles();
for(int i=0;i<nFiles;i++)
{
char fileName[32];
char comment1[32];
char comment2[32];
if(!memoryCard1->GetFileName(i,fileName)) fileName[0]=0;
if(!memoryCard1->GetComment1(i,comment1)) comment1[0]=0;
if(!memoryCard1->GetComment2(i,comment2)) comment2[0]=0;
// Add to list control
int index = m_Memcard1List->InsertItem(i, "row");
m_Memcard1List->SetItem(index, 0, fileName);
m_Memcard1List->SetItem(index, 1, comment1);
m_Memcard1List->SetItem(index, 2, comment2);
}
m_Memcard1List->Show();
}
else
{
m_Memcard2List->InsertColumn(COLUMN_FILENAME, _T("Error"));
char tmp[128];
sprintf(tmp, "Unable to load %s", card1);
long item = m_Memcard1List->InsertItem(0, tmp);
m_Memcard1List->SetItemFont(item, *wxITALIC_FONT);
m_Memcard1List->SetColumnWidth(item, wxLIST_AUTOSIZE);
m_Memcard1List->SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
// automatic column width
for (int i = 0; i < m_Memcard1List->GetColumnCount(); i++)
{
m_Memcard1List->SetColumnWidth(i, wxLIST_AUTOSIZE);
}
}
void CMemcardManager::LoadMemcard2(const char *card2)
{
if(card2 && strlen(card2))
{
memoryCard2 = new GCMemcard(card2);
}
if(memoryCard2)
{
m_Memcard2List->Hide();
m_Memcard2List->ClearAll();
m_Memcard2List->InsertColumn(COLUMN_FILENAME, _T("filename"));
m_Memcard2List->InsertColumn(COLUMN_COMMENT1, _T("comment1"));
m_Memcard2List->InsertColumn(COLUMN_COMMENT2, _T("comment2"));
int nFiles = memoryCard2->GetNumFiles();
for(int i=0;i<nFiles;i++)
{
char fileName[32];
char comment1[32];
char comment2[32];
if(!memoryCard2->GetFileName(i,fileName)) fileName[0]=0;
if(!memoryCard2->GetComment1(i,comment1)) comment1[0]=0;
if(!memoryCard2->GetComment2(i,comment2)) comment2[0]=0;
int index = m_Memcard2List->InsertItem(i, "row");
m_Memcard2List->SetItem(index, 0, fileName);
m_Memcard2List->SetItem(index, 1, comment1);
m_Memcard2List->SetItem(index, 2, comment2);
}
m_Memcard2List->Show();
}
else
{
m_Memcard2List->InsertColumn(COLUMN_FILENAME, _T("Error"));
char tmp[128];
sprintf(tmp, "Unable to load %s", card2);
long item = m_Memcard2List->InsertItem(0, tmp);
m_Memcard2List->SetItemFont(item, *wxITALIC_FONT);
m_Memcard2List->SetColumnWidth(item, wxLIST_AUTOSIZE);
m_Memcard2List->SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
// automatic column width
for (int i = 0; i < m_Memcard2List->GetColumnCount(); i++)
{
m_Memcard2List->SetColumnWidth(i, wxLIST_AUTOSIZE);
}
}

View File

@ -0,0 +1,91 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef __MEMCARD_MANAGER_h__
#define __MEMCARD_MANAGER_h__
#include <wx/sizer.h>
#include <wx/filepicker.h>
#include <wx/statbmp.h>
#include <wx/stattext.h>
#include <wx/listctrl.h>
#include "MemoryCards/GCMemcard.h"
#undef MEMCARD_MANAGER_STYLE
#define MEMCARD_MANAGER_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxCLOSE_BOX | wxRESIZE_BORDER
class CMemcardManager
: public wxDialog
{
public:
CMemcardManager(wxWindow* parent, wxWindowID id = 1, const wxString& title = wxT("Memory Card Manager WARNING-In development, make backups first!"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = MEMCARD_MANAGER_STYLE);
virtual ~CMemcardManager();
private:
DECLARE_EVENT_TABLE();
wxBoxSizer* sMain;
wxButton* m_CopyRight;
wxButton* m_CopyLeft;
wxButton* m_DeleteRight;
wxButton* m_DeleteLeft;
wxStaticBoxSizer* sMemcard1;
wxStaticBoxSizer* sMemcard2;
wxFilePickerCtrl* m_Memcard1Path;
wxFilePickerCtrl* m_Memcard2Path;
wxListCtrl* m_Memcard1List;
wxListCtrl* m_Memcard2List;
enum
{
ID_COPYRIGHT = 1000,
ID_COPYLEFT = 1001,
ID_DELETERIGHT = 1002,
ID_DELETELEFT = 1003,
ID_MEMCARD1PATH = 1004,
ID_MEMCARD2PATH = 1005,
ID_MEMCARD1LIST = 1006,
ID_MEMCARD2LIST = 1007,
ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values
};
enum
{
COLUMN_FILENAME = 0,
COLUMN_COMMENT1,
COLUMN_COMMENT2,
NUMBER_OF_COLUMN
};
GCMemcard *memoryCard1;
GCMemcard *memoryCard2;
void LoadMemcard1(const char *card1);
void LoadMemcard2(const char *card2);
void OnPathChange(wxFileDirPickerEvent& event);
void CreateGUIControls();
void OnRightClick(wxMouseEvent& event);
void OnClose(wxCloseEvent& event);
void CopyClick(wxCommandEvent& event);
void DeleteClick(wxCommandEvent& event);
};
#endif

View File

@ -0,0 +1,394 @@
// gcmc.cpp: define el punto de entrada de la aplicación de consola.
//
#include "stdafx.h"
#include <assert.h>
#include "GCMemcard.h"
void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
{
*c1 = 0;*c2 = 0;
for (u32 i = 0; i < num; ++i)
{
*c1 += bswap16(buf[i]);
*c2 += bswap16((u16)(buf[i] ^ 0xffff));
}
if (*c1 == 0xffff)
{
*c1 = 0;
}
if (*c2 == 0xffff)
{
*c2 = 0;
}
}
u32 GCMemcard::GetNumFiles()
{
if(!mcdFile) return 0;
for(int i=0;i<127;i++)
{
if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF)
return i;
}
return 127;
}
bool GCMemcard::DeleteFile(u32 index) //index in the directory array
{
if(!mcdFile) return false;
//backup the directory and bat (not really needed here but meh :P
dir_backup=dir;
bat_backup=bat;
int totalspace = (((u32)BE16(hdr.Size)*16)-5);
//free the blocks
int blocks_left = BE16(dir.Dir[index].BlockCount);
int block = BE16(dir.Dir[index].FirstBlock);
do
{
int cbi = block-5;
int nextblock=bswap16(bat.Map[cbi]);
//assert(nextblock!=0);
if(nextblock==0)
{
nextblock = block+1;
}
bat.Map[cbi]=0;
block=nextblock;
blocks_left--;
}
while((block!=0xffff)&&(blocks_left>0));
//delete directory entry
for(int i=index;i<126;i++)
{
dir.Dir[i]=dir.Dir[i+1];
}
memset(&(dir.Dir[126]),0xFF,sizeof(DEntry));
//pack blocks to remove free space partitioning, assume no fragmentation.
u8 *mc_data2 = new u8[mc_data_size];
int firstFree=0;
for(int i=0;i<127;i++)
{
if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF)
{
break;
}
int fb = BE16(dir.Dir[i].FirstBlock);
int bc = BE16(dir.Dir[i].BlockCount);
u8* src = mc_data + (fb-5)*0x2000;
u8* dst = mc_data2 + firstFree*0x2000;
memcpy(dst,src,bc*0x2000);
for(int j=0;j<bc;j++)
{
bat.Map[firstFree+j] = bswap16(u16(firstFree+j+6));
}
bat.Map[firstFree+bc-1] = 0xFFFF;
dir.Dir[i].FirstBlock[0] = u8(firstFree>>8);
dir.Dir[i].FirstBlock[1] = u8(firstFree);
firstFree += bc;
}
for(int j=firstFree;j<totalspace;j++)
{
bat.Map[j] = 0;
}
firstFree+=4;
bat.LastAllocated[0] = u8(firstFree>>8);
bat.LastAllocated[1] = u8(firstFree);
delete mc_data;
mc_data=mc_data2;
//--
//update freespace counter
int freespace1 = totalspace - firstFree;
bat.FreeBlocks[0] = u8(freespace1>>8);
bat.FreeBlocks[1] = u8(freespace1);
//fix checksums
u16 csum1=0,csum2=0;
calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2);
dir.CheckSum1[0]=u8(csum1>>8);
dir.CheckSum1[1]=u8(csum1);
dir.CheckSum2[0]=u8(csum2>>8);
dir.CheckSum2[1]=u8(csum2);
calc_checksumsBE((u16*)(((u8*)&bat)+4),0xFFE,&csum1,&csum2);
bat.CheckSum1[0]=u8(csum1>>8);
bat.CheckSum1[1]=u8(csum1);
bat.CheckSum2[0]=u8(csum2>>8);
bat.CheckSum2[1]=u8(csum2);
return true;
}
u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents)
{
if(!mcdFile) return 0;
if(BE16(bat.FreeBlocks)<BE16(direntry.BlockCount))
{
return 0;
}
// find first free data block -- assume no freespace fragmentation
int totalspace = (((u32)BE16(hdr.Size)*16)-5);
int firstFree1 = BE16(bat.LastAllocated)+1;
int firstFree2 = 0;
for(int i=0;i<totalspace;i++)
{
if(bat.Map[i]==0)
{
firstFree2=i+5;
break;
}
}
int firstFree3 = 0;
for(int i=0;i<127;i++)
{
if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF)
{
break;
}
else
{
firstFree3 = max(firstFree3,BE16(dir.Dir[i].FirstBlock) + BE16(dir.Dir[i].BlockCount));
}
}
if(firstFree2 > firstFree1) firstFree1 = firstFree2;
if(firstFree3 > firstFree1) firstFree1 = firstFree3;
// find first free dir entry
int index=-1;
for(int i=0;i<127;i++)
{
if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF)
{
index=i;
dir.Dir[i] = direntry;
dir.Dir[i].FirstBlock[0] = u8(firstFree1>>8);
dir.Dir[i].FirstBlock[1] = u8(firstFree1);
break;
}
}
// keep assuming no freespace fragmentation, and copy over all the data
u8*destination = mc_data + (firstFree1-5)*0x2000;
int fileBlocks=BE16(direntry.BlockCount);
memcpy(destination,contents,0x2000*fileBlocks);
//update freespace counter
int freespace1 = totalspace - firstFree1;
bat.FreeBlocks[0] = u8(freespace1>>8);
bat.FreeBlocks[1] = u8(freespace1);
//fix checksums
u16 csum1=0,csum2=0;
calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2);
dir.CheckSum1[0]=u8(csum1>>8);
dir.CheckSum1[1]=u8(csum1);
dir.CheckSum2[0]=u8(csum2>>8);
dir.CheckSum2[1]=u8(csum2);
calc_checksumsBE((u16*)(((u8*)&bat)+4),0xFFE,&csum1,&csum2);
bat.CheckSum1[0]=u8(csum1>>8);
bat.CheckSum1[1]=u8(csum1);
bat.CheckSum2[0]=u8(csum2>>8);
bat.CheckSum2[1]=u8(csum2);
return fileBlocks;
}
bool GCMemcard::GetFileData(u32 index, u8*dest) //index in the directory array
{
if(!mcdFile) return false;
int block = BE16(dir.Dir[index].FirstBlock);
assert((block!=0xFFFF)&&(block>0));
do
{
int nextblock=bswap16(bat.Map[block-5]);
assert(nextblock>0);
memcpy(dest,mc_data + 0x2000*(block-5),0x2000);
dest+=0x2000;
block=nextblock;
}
while(block!=0xffff);
return true;
}
u32 GCMemcard::GetFileSize(u32 index) //index in the directory array
{
if(!mcdFile) return 0;
return BE16(dir.Dir[index].BlockCount);
}
bool GCMemcard::GetFileInfo(u32 index, GCMemcard::DEntry& info) //index in the directory array
{
if(!mcdFile) return false;
info = dir.Dir[index];
return true;
}
bool GCMemcard::GetFileName(u32 index, char *fn) //index in the directory array
{
if(!mcdFile) return false;
memcpy(fn,(const char*)dir.Dir[index].Filename,32);
fn[31]=0;
return true;
}
bool GCMemcard::GetComment1(u32 index, char *fn) //index in the directory array
{
if(!mcdFile) return false;
u32 Comment1 =BE32(dir.Dir[index].CommentsAddr);
u32 DataBlock =BE16(dir.Dir[index].FirstBlock)-5;
if(Comment1==0xFFFFFFFF)
{
fn[0]=0;
return false;
}
memcpy(fn,mc_data +(DataBlock*0x2000) + Comment1,32);
fn[31]=0;
return true;
}
bool GCMemcard::GetComment2(u32 index, char *fn) //index in the directory array
{
if(!mcdFile) return false;
u32 Comment1 =BE32(dir.Dir[index].CommentsAddr);
u32 Comment2 =Comment1+32;
u32 DataBlock =BE16(dir.Dir[index].FirstBlock)-5;
if(Comment1==0xFFFFFFFF)
{
fn[0]=0;
return false;
}
memcpy(fn,mc_data +(DataBlock*0x2000) + Comment2,32);
fn[31]=0;
return true;
}
u32 GCMemcard::TestChecksums()
{
if(!mcdFile) return 0xFFFFFFFF;
u16 csum1=0,csum2=0;
calc_checksumsBE((u16*)&hdr, 0xFE ,&csum1,&csum2);
if(BE16(hdr.CheckSum1)!=csum1) return 1;
if(BE16(hdr.CheckSum2)!=csum2) return 1;
calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2);
if(BE16(dir.CheckSum1)!=csum1) return 2;
if(BE16(dir.CheckSum2)!=csum2) return 2;
calc_checksumsBE((u16*)&dir_backup,0xFFE,&csum1,&csum2);
if(BE16(dir_backup.CheckSum1)!=csum1) return 3;
if(BE16(dir_backup.CheckSum2)!=csum2) return 3;
calc_checksumsBE((u16*)(((u8*)&bat)+4),0xFFE,&csum1,&csum2);
if(BE16(bat.CheckSum1)!=csum1) return 4;
if(BE16(bat.CheckSum2)!=csum2) return 4;
calc_checksumsBE((u16*)(((u8*)&bat_backup)+4),0xFFE,&csum1,&csum2);
if(BE16(bat_backup.CheckSum1)!=csum1) return 5;
if(BE16(bat_backup.CheckSum2)!=csum2) return 5;
return 0;
}
u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
{
if(!mcdFile) return 0;
DEntry d;
if(!source.GetFileInfo(index,d)) return 0;
u8 *t = new u8[source.GetFileSize(index)*0x2000];
if(!source.GetFileData(index,t)) return 0;
u32 ret = ImportFile(d,t);
delete t;
return ret;
}
bool GCMemcard::Save()
{
if(!mcdFile) return false;
FILE *mcd=(FILE*)mcdFile;
fseek(mcd,0,SEEK_SET);
fwrite(&hdr,1,0x2000,mcd);
fwrite(&dir,1,0x2000,mcd);
fwrite(&dir_backup,1,0x2000,mcd);
fwrite(&bat,1,0x2000,mcd);
fwrite(&bat_backup,1,0x2000,mcd);
fwrite(mc_data,1,mc_data_size,mcd);
return true;
}
bool GCMemcard::IsOpen()
{
return (mcdFile!=NULL);
}
GCMemcard::GCMemcard(const char *filename)
{
FILE *mcd=fopen(filename,"r+b");
mcdFile=mcd;
if(!mcd) return;
fseek(mcd,0x0000,SEEK_SET);
assert(fread(&hdr, 1,0x2000,mcd)==0x2000);
assert(fread(&dir, 1,0x2000,mcd)==0x2000);
assert(fread(&dir_backup,1,0x2000,mcd)==0x2000);
assert(fread(&bat, 1,0x2000,mcd)==0x2000);
assert(fread(&bat_backup,1,0x2000,mcd)==0x2000);
fseek(mcd,0xa000,SEEK_SET);
mc_data_size=(((u32)BE16(hdr.Size)*16)-5)*0x2000;
mc_data = new u8[mc_data_size];
u32 read = fread(mc_data,1,mc_data_size,mcd);
assert(mc_data_size==read);
}
GCMemcard::~GCMemcard()
{
fclose((FILE*)mcdFile);
}

View File

@ -0,0 +1,159 @@
#pragma once
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
u16 __inline bswap16(u16 s)
{
return (s>>8) | (s<<8);
}
u32 __inline bswap32(u32 s)
{
return (u32)bswap16((u16)(s>>16)) | ((u32)bswap16((u16)s)<<16);
}
#ifndef max
template<class T>
T __inline max(T a, T b)
{
return (b>a)?b:a;
}
#endif
#define BE16(x) (((x)[0]<<8) | (x)[1])
#define BE32(x) (((x)[0]<<24) | ((x)[1]<<16) | ((x)[2]<<8) | (x)[3])
class GCMemcard
{
void* mcdFile;
u32 mc_data_size;
u8* mc_data;
void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2);
public:
#pragma pack(push,1)
struct OSTime {
u32 low;
u32 high;
};
struct Header { //Offset Size Description
u8 Unk[12]; //0x0000 12 ?
OSTime fmtTime; //0x000c 8 time of format (OSTime value)
u8 UID[12]; //0x0014 12 unique card id (?)
u8 Pad1[2]; //0x0020 2 padding zeroes
u8 Size[2]; //0x0022 2 size of memcard in Mbits
u8 Encoding[2]; //0x0024 2 encoding (ASCII or japanese)
u8 Unused1[468]; //0x0026 468 unused (0xff)
u8 UpdateCounter[2];//0x01fa 2 update Counter (?, probably unused)
u8 CheckSum1[2]; //0x01fc 2 Checksum 1 (?)
u8 CheckSum2[2]; //0x01fe 2 Checksum 2 (?)
u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff)
} hdr;
struct DEntry {
u8 Gamecode[4]; //0x00 0x04 Gamecode
u8 Markercode[2]; //0x04 0x02 Makercode
u8 Unused1; //0x06 0x01 reserved/unused (always 0xff, has no effect)
u8 BIFlags; //0x07 0x01 banner gfx format and icon animation (Image Key)
// bit(s) description
// 2 Icon Animation 0: forward 1: ping-pong
// 1 0: No Banner 1: Banner present
// 0 Banner Color 0: RGB5A3 1: CI8
//
u8 Filename[32]; //0x08 0x20 filename
u8 ModTime[4]; //0x28 0x04 Time of file's last modification in seconds since 12am, January 1st, 2000
u8 ImageOffset[4]; //0x2c 0x04 image data offset
u8 IconFmt[2]; //0x30 0x02 icon gfx format (2bits per icon)
// bits Description
// 00 no icon
// 01 CI8 with a shared color palette after the last frame
// 10 RGB5A3
// 11 CI8 with a unique color palette after itself
//
u8 AnimSpeed[2]; //0x32 0x02 animation speed (2bits per icon) (*1)
// bits Description
// 00 no icon
// 01 Icon lasts for 4 frames
// 10 Icon lasts for 8 frames
// 11 Icon lasts for 12 frames
//
u8 Permissions; //0x34 0x01 file-permissions
// bit permission Description
// 4 no move File cannot be moved by the IPL
// 3 no copy File cannot be copied by the IPL
// 2 public Can be read by any game
//
u8 CopyCounter; //0x35 0x01 copy counter (*2)
u8 FirstBlock[2]; //0x36 0x02 block no of first block of file (0 == offset 0)
u8 BlockCount[2]; //0x38 0x02 file-length (number of blocks in file)
u8 Unused2[2]; //0x3a 0x02 reserved/unused (always 0xffff, has no effect)
u8 CommentsAddr[4]; //0x3c 0x04 Address of the two comments within the file data (*3)
};
struct Directory {
DEntry Dir[127]; //0x0000 Directory Entries (max 127)
u8 Padding[0x3a];
u8 UpdateCounter[2];//0x1ffa 2 update Counter
u8 CheckSum1[2]; //0x1ffc 2 Checksum 1
u8 CheckSum2[2]; //0x1ffe 2 Checksum 2
} dir, dir_backup;
struct BlockAlloc {
u8 CheckSum1[2]; //0x0000 2 Checksum 1
u8 CheckSum2[2]; //0x0002 2 Checksum 2
u8 UpdateCounter[2];//0x0004 2 update Counter
u8 FreeBlocks[2]; //0x0006 2 free Blocks
u8 LastAllocated[2];//0x0008 2 last allocated Block
u16 Map[0xFFB]; //0x000a 0x1ff8 Map of allocated Blocks
} bat,bat_backup;
#pragma pack(pop)
// constructor
GCMemcard(const char* fileName);
// destructor
~GCMemcard();
bool IsOpen();
u32 TestChecksums();
// get number of file entries in the directory
u32 GetNumFiles();
// read directory entry
bool GetFileInfo(u32 index, DEntry& data);
// buffer needs to be a char[32] or bigger
bool GetFileName(u32 index, char* buffer);
// buffer needs to be a char[32] or bigger
bool GetComment1(u32 index, char* buffer);
// buffer needs to be a char[32] or bigger
bool GetComment2(u32 index, char* buffer);
// get file length un bytes
u32 GetFileSize(u32 index);
// assumes there's enough space in buffer
bool GetFileData(u32 index, u8* buffer);
// delete a file from the directory
bool DeleteFile(u32 index);
// adds the file to the directory and copies its contents
u32 ImportFile(DEntry& direntry, u8* contents);
// reads a save from another memcard, and imports the data into this memcard
u32 CopyFrom(GCMemcard& source, u32 index);
bool Save();
};

View File

@ -57,100 +57,77 @@ CPluginOptions::~CPluginOptions()
void CPluginOptions::CreateGUIControls()
{
SetTitle(wxT("Plugin Selection"));
SetIcon(wxNullIcon);
SetSize(0, 8, 440, 295);
Center();
const wxChar* font_name = 0;
int font_size = 8;
#ifdef _WIN32
OSVERSIONINFOEX os;
os.dwOSVersionInfoSize = sizeof(os);
GetVersionEx((OSVERSIONINFO*)&os);
if (os.dwMajorVersion >= 6)
{
font_name = wxT("Segoe UI");
font_size = 9;
}
else
{
font_name = wxT("Tahoma");
}
//
#endif
wxFont font(font_size, wxSWISS, wxNORMAL, wxNORMAL, false, font_name);
OK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(188, 240), wxSize(73, 25), 0, wxDefaultValidator, wxT("OK"));
OK->SetFont(font);
Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxPoint(268, 240), wxSize(73, 25), 0, wxDefaultValidator, wxT("Cancel"));
Cancel->SetFont(font);
Apply = new wxButton(this, ID_APPLY, wxT("Apply"), wxPoint(348, 240), wxSize(73, 25), 0, wxDefaultValidator, wxT("Apply"));
Apply->SetFont(font);
OK = new wxButton(this, ID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
Apply = new wxButton(this, ID_APPLY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
Apply->Disable();
{
GraphicSelection = new wxChoice(this, ID_GRAPHIC_CB, wxPoint(88, 16), wxSize(333, 23), NULL, 0, wxDefaultValidator, wxT("GraphicSelection"));
GraphicSelection->SetFont(font);
GraphicSelection = new wxChoice(this, ID_GRAPHIC_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator);
GraphicAbout = new wxButton(this, ID_GRAPHIC_ABOUT, wxT("About..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
GraphicConfig = new wxButton(this, ID_GRAPHIC_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
GraphicText = new wxStaticText(this, ID_GRAPHIC_TEXT, wxT("GFX:"), wxDefaultPosition, wxDefaultSize);
GraphicAbout = new wxButton(this, ID_GRAPHIC_ABOUT, wxT("About..."), wxPoint(168, 48), wxSize(73, 25), 0, wxDefaultValidator, wxT("GraphicAbout"));
GraphicAbout->SetFont(font);
FillChoiceBox(GraphicSelection, PLUGIN_TYPE_VIDEO, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin);
GraphicConfig = new wxButton(this, ID_GRAPHIC_CONFIG, wxT("Config..."), wxPoint(88, 48), wxSize(73, 25), 0, wxDefaultValidator, wxT("GraphicConfig"));
GraphicConfig->SetFont(font);
DSPSelection = new wxChoice(this, ID_DSP_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator);
DSPAbout = new wxButton(this, ID_DSP_ABOUT, wxT("About..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
DSPConfig = new wxButton(this, ID_DSP_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
DSPText = new wxStaticText(this, ID_DSP_TEXT, wxT("DSP:"), wxDefaultPosition, wxDefaultSize);
WxStaticText1 = new wxStaticText(this, ID_WXSTATICTEXT1, wxT("Graphic"), wxPoint(16, 21), wxDefaultSize, 0, wxT("WxStaticText1"));
WxStaticText1->SetFont(font);
FillChoiceBox(DSPSelection, PLUGIN_TYPE_DSP, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin);
FillChoiceBox(GraphicSelection, PLUGIN_TYPE_VIDEO, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin);
}
PADSelection = new wxChoice(this, ID_PAD_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator);
PADAbout = new wxButton(this, ID_PAD_ABOUT, wxT("About..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
PADConfig = new wxButton(this, ID_PAD_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
PADText = new wxStaticText(this, ID_PAD_TEXT, wxT("PAD:"), wxDefaultPosition, wxDefaultSize);
{
DSPSelection = new wxChoice(this, ID_DSP_CB, wxPoint(88, 88), wxSize(333, 23), NULL, 0, wxDefaultValidator, wxT("DSPSelection"));
DSPSelection->SetFont(font);
FillChoiceBox(PADSelection, PLUGIN_TYPE_PAD, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin);
wxGridBagSizer* sConfig;
sConfig = new wxGridBagSizer(0, 0);
sConfig->SetFlexibleDirection(wxBOTH);
sConfig->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
sConfig->Add(GraphicText, wxGBPosition(0, 0), wxGBSpan(2, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sConfig->Add(GraphicSelection, wxGBPosition(0, 1), wxGBSpan(1, 2), wxEXPAND|wxALL, 5);
sConfig->Add(GraphicConfig, wxGBPosition(0, 3), wxGBSpan(1, 1), wxALL, 5);
sConfig->Add(GraphicAbout, wxGBPosition(0, 4), wxGBSpan(1, 1), wxALL, 5);
DSPAbout = new wxButton(this, ID_DSP_ABOUT, wxT("About..."), wxPoint(168, 120), wxSize(73, 25), 0, wxDefaultValidator, wxT("DSPAbout"));
DSPAbout->SetFont(font);
sConfig->Add(DSPText, wxGBPosition(2, 0), wxGBSpan(2, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sConfig->Add(DSPSelection, wxGBPosition(2, 1), wxGBSpan(1, 2), wxEXPAND|wxALL, 5);
sConfig->Add(DSPConfig, wxGBPosition(2, 3), wxGBSpan(1, 1), wxALL, 5);
sConfig->Add(DSPAbout, wxGBPosition(2, 4), wxGBSpan(1, 1), wxALL, 5);
DSPConfig = new wxButton(this, ID_DSP_CONFIG, wxT("Config..."), wxPoint(88, 120), wxSize(73, 25), 0, wxDefaultValidator, wxT("DSPConfig"));
DSPConfig->SetFont(font);
sConfig->Add(PADText, wxGBPosition(4, 0), wxGBSpan(2, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sConfig->Add(PADSelection, wxGBPosition(4, 1), wxGBSpan(1, 2), wxEXPAND|wxALL, 5);
sConfig->Add(PADConfig, wxGBPosition(4, 3), wxGBSpan(1, 1), wxALL, 5);
sConfig->Add(PADAbout, wxGBPosition(4, 4), wxGBSpan(1, 1), wxALL, 5);
sConfig->Layout();
WxStaticText2 = new wxStaticText(this, ID_WXSTATICTEXT2, wxT("DSP"), wxPoint(16, 93), wxDefaultSize, 0, wxT("WxStaticText2"));
WxStaticText2->SetFont(font);
FillChoiceBox(DSPSelection, PLUGIN_TYPE_DSP, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin);
}
{
PADSelection = new wxChoice(this, ID_PAD_CB, wxPoint(88, 160), wxSize(333, 23), NULL, 0, wxDefaultValidator, wxT("PADSelection"));
PADSelection->SetFont(font);
PADAbout = new wxButton(this, ID_PAD_ABOUT, wxT("About..."), wxPoint(168, 192), wxSize(73, 25), 0, wxDefaultValidator, wxT("PADAbout"));
PADAbout->SetFont(font);
PADConfig = new wxButton(this, ID_PAD_CONFIG, wxT("Config..."), wxPoint(88, 192), wxSize(73, 25), 0, wxDefaultValidator, wxT("PADConfig"));
PADConfig->SetFont(font);
WxStaticText3 = new wxStaticText(this, ID_WXSTATICTEXT3, wxT("Pad"), wxPoint(16, 165), wxDefaultSize, 0, wxT("WxStaticText3"));
WxStaticText3->SetFont(font);
FillChoiceBox(PADSelection, PLUGIN_TYPE_PAD, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin);
}
wxBoxSizer* sButtons;
sButtons = new wxBoxSizer(wxHORIZONTAL);
sButtons->Add(0, 0, 1, wxEXPAND, 5);
sButtons->Add(OK, 0, wxALL, 5);
sButtons->Add(Cancel, 0, wxALL, 5);
sButtons->Add(Apply, 0, wxALL, 5);
wxBoxSizer* sMain;
sMain = new wxBoxSizer(wxVERTICAL);
sMain->Add(sConfig, 1, wxEXPAND|wxALL, 5);
sMain->Add(sButtons, 0, wxEXPAND, 5);
Center();
this->SetSizer(sMain);
sMain->SetSizeHints(this);
}
void
CPluginOptions::OnClose(wxCloseEvent& WXUNUSED (event))
void CPluginOptions::OnClose(wxCloseEvent& WXUNUSED (event))
{
Destroy();
}
void
CPluginOptions::OKClick(wxCommandEvent& event)
void CPluginOptions::OKClick(wxCommandEvent& event)
{
switch (event.GetId())
{
@ -170,15 +147,13 @@ CPluginOptions::OKClick(wxCommandEvent& event)
}
void
CPluginOptions::OnSelectionChanged(wxCommandEvent& WXUNUSED (event))
void CPluginOptions::OnSelectionChanged(wxCommandEvent& WXUNUSED (event))
{
Apply->Enable();
}
void
CPluginOptions::OnAbout(wxCommandEvent& event)
void CPluginOptions::OnAbout(wxCommandEvent& event)
{
switch (event.GetId())
{
@ -197,8 +172,7 @@ CPluginOptions::OnAbout(wxCommandEvent& event)
}
void
CPluginOptions::OnConfig(wxCommandEvent& event)
void CPluginOptions::OnConfig(wxCommandEvent& event)
{
switch (event.GetId())
{
@ -217,8 +191,7 @@ CPluginOptions::OnConfig(wxCommandEvent& event)
}
void
CPluginOptions::FillChoiceBox(wxChoice* _pChoice, int _PluginType, const std::string& _SelectFilename)
void CPluginOptions::FillChoiceBox(wxChoice* _pChoice, int _PluginType, const std::string& _SelectFilename)
{
_pChoice->Clear();
@ -246,8 +219,7 @@ CPluginOptions::FillChoiceBox(wxChoice* _pChoice, int _PluginType, const std::st
}
void
CPluginOptions::CallConfig(wxChoice* _pChoice)
void CPluginOptions::CallConfig(wxChoice* _pChoice)
{
int Index = _pChoice->GetSelection();
@ -263,8 +235,7 @@ CPluginOptions::CallConfig(wxChoice* _pChoice)
}
void
CPluginOptions::CallAbout(wxChoice* _pChoice)
void CPluginOptions::CallAbout(wxChoice* _pChoice)
{
int Index = _pChoice->GetSelection();
@ -280,8 +251,7 @@ CPluginOptions::CallAbout(wxChoice* _pChoice)
}
void
CPluginOptions::DoApply()
void CPluginOptions::DoApply()
{
Apply->Disable();
@ -293,8 +263,7 @@ CPluginOptions::DoApply()
}
bool
CPluginOptions::GetFilename(wxChoice* _pChoice, std::string& _rFilename)
bool CPluginOptions::GetFilename(wxChoice* _pChoice, std::string& _rFilename)
{
_rFilename.clear();
@ -312,4 +281,3 @@ CPluginOptions::GetFilename(wxChoice* _pChoice, std::string& _rFilename)
return(false);
}

View File

@ -18,6 +18,8 @@
#ifndef __PLUGIN_OPTIONS_h__
#define __PLUGIN_OPTIONS_h__
#include <wx/gbsizer.h>
#undef PLUGIN_OPTIONS_STYLE
#define PLUGIN_OPTIONS_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxCLOSE_BOX
@ -30,7 +32,7 @@ class CPluginOptions
public:
CPluginOptions(wxWindow* parent, wxWindowID id = 1, const wxString& title = wxT("Untitled1"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = PLUGIN_OPTIONS_STYLE);
CPluginOptions(wxWindow* parent, wxWindowID id = 1, const wxString& title = wxT("Plugin Selection"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = PLUGIN_OPTIONS_STYLE);
virtual ~CPluginOptions();
void OKClick(wxCommandEvent& event);
void OnSelectionChanged(wxCommandEvent& event);
@ -47,17 +49,17 @@ class CPluginOptions
wxButton* OK;
wxButton* Cancel;
wxButton* Apply;
wxStaticText* WxStaticText3;
wxStaticText* PADText;
wxButton* PADAbout;
wxButton* PADConfig;
wxChoice* PADSelection;
wxButton* DSPAbout;
wxButton* DSPConfig;
wxStaticText* WxStaticText2;
wxStaticText* DSPText;
wxChoice* DSPSelection;
wxButton* GraphicAbout;
wxButton* GraphicConfig;
wxStaticText* WxStaticText1;
wxStaticText* GraphicText;
wxChoice* GraphicSelection;
////GUI Control Declaration End
@ -73,17 +75,17 @@ class CPluginOptions
ID_CANCEL = 1034,
ID_APPLY = 1033,
ID_OK = 1032,
ID_WXSTATICTEXT3 = 1031,
ID_PAD_TEXT = 1031,
ID_PAD_ABOUT = 1030,
ID_PAD_CONFIG = 1029,
ID_PAD_CB = 1028,
ID_DSP_ABOUT = 1027,
ID_DSP_CONFIG = 1026,
ID_WXSTATICTEXT2 = 1025,
ID_DSP_TEXT = 1025,
ID_DSP_CB = 1024,
ID_GRAPHIC_ABOUT = 1007,
ID_GRAPHIC_CONFIG = 1006,
ID_WXSTATICTEXT1 = 1005,
ID_GRAPHIC_TEXT = 1005,
ID_GRAPHIC_CB = 1003,
////GUI Enum Control ID End
ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values