simplified EXI_DeviceMemoryCard.cpp,
warning fix for WII_IPC_HLE_Device_usb.cpp, codecleanup and added the ability to create a formated 16Mb memcard in MemcardManager, calibrate button is now easier to read in nJoy Testing git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1600 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
a2a8be006a
commit
c695ebd6f1
|
@ -30,6 +30,7 @@
|
||||||
#define MC_STATUS_ERASEERROR 0x10
|
#define MC_STATUS_ERASEERROR 0x10
|
||||||
#define MC_STATUS_PROGRAMEERROR 0x08
|
#define MC_STATUS_PROGRAMEERROR 0x08
|
||||||
#define MC_STATUS_READY 0x01
|
#define MC_STATUS_READY 0x01
|
||||||
|
#define SIZE_TO_Mb 1024 * 8 * 16
|
||||||
|
|
||||||
static CEXIMemoryCard *cards[2];
|
static CEXIMemoryCard *cards[2];
|
||||||
|
|
||||||
|
@ -76,34 +77,8 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
|
||||||
u64 MemFileSize = ftell(pFile);
|
u64 MemFileSize = ftell(pFile);
|
||||||
fseek(pFile, 0L, SEEK_SET);
|
fseek(pFile, 0L, SEEK_SET);
|
||||||
|
|
||||||
switch ((MemFileSize / (8 * 1024)) - 5) // Convert the filesize in bytes to the "nintendo-size"
|
memory_card_size = (int)MemFileSize;
|
||||||
{
|
nintendo_card_id = memory_card_size / SIZE_TO_Mb;
|
||||||
case 59:
|
|
||||||
nintendo_card_id = 0x00000004;
|
|
||||||
memory_card_size = 512 * 1024;
|
|
||||||
break;
|
|
||||||
case 123:
|
|
||||||
nintendo_card_id = 0x00000008;
|
|
||||||
memory_card_size = 1024 * 1024;
|
|
||||||
break;
|
|
||||||
case 251:
|
|
||||||
nintendo_card_id = 0x00000010;
|
|
||||||
memory_card_size = 2 * 1024 * 1024;
|
|
||||||
break;
|
|
||||||
case 507:
|
|
||||||
nintendo_card_id = 0x00000020;
|
|
||||||
memory_card_size = 4 * 1024 * 1024;
|
|
||||||
break;
|
|
||||||
case 1019:
|
|
||||||
nintendo_card_id = 0x00000040;
|
|
||||||
memory_card_size = 8 * 1024 * 1024;
|
|
||||||
break;
|
|
||||||
case 2043:
|
|
||||||
default:
|
|
||||||
nintendo_card_id = 0x00000080;
|
|
||||||
memory_card_size = 16 * 1024 * 1024;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memory_card_content = new u8[memory_card_size];
|
memory_card_content = new u8[memory_card_size];
|
||||||
memset(memory_card_content, 0xFF, memory_card_size);
|
memset(memory_card_content, 0xFF, memory_card_size);
|
||||||
|
@ -116,7 +91,7 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
|
||||||
{
|
{
|
||||||
// Create a new 128Mb memcard
|
// Create a new 128Mb memcard
|
||||||
nintendo_card_id = 0x00000080;
|
nintendo_card_id = 0x00000080;
|
||||||
memory_card_size = 16 * 1024 * 1024;
|
memory_card_size = nintendo_card_id * SIZE_TO_Mb;
|
||||||
|
|
||||||
memory_card_content = new u8[memory_card_size];
|
memory_card_content = new u8[memory_card_size];
|
||||||
memset(memory_card_content, 0xFF, memory_card_size);
|
memset(memory_card_content, 0xFF, memory_card_size);
|
||||||
|
|
|
@ -394,7 +394,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
|
||||||
// Why do we need this? 0 worked with the emulated wiimote in all games I tried
|
// Why do we need this? 0 worked with the emulated wiimote in all games I tried
|
||||||
static int counter = 1000;
|
static int counter = 1000;
|
||||||
|
|
||||||
if (test && !stricmp(m_LocalName, "Wii") && (m_ScanEnable & 0x2))
|
if (test && !strcasecmp(m_LocalName, "Wii") && (m_ScanEnable & 0x2))
|
||||||
{
|
{
|
||||||
counter--;
|
counter--;
|
||||||
if (counter < 0)
|
if (counter < 0)
|
||||||
|
|
|
@ -174,10 +174,10 @@ void CMemcardManager::CreateGUIControls()
|
||||||
{
|
{
|
||||||
// Create the controls for both memcards
|
// Create the controls for both memcards
|
||||||
// Loading invalid .raw files should no longer crash the app
|
// Loading invalid .raw files should no longer crash the app
|
||||||
m_MemcardPath_A = new wxFilePickerCtrl(this, ID_MEMCARDPATH_A, wxEmptyString, wxT("Choose a memory card:"),
|
m_MemcardPath[SLOT_A] = new wxFilePickerCtrl(this, ID_MEMCARDPATH_A, wxEmptyString, wxT("Choose a memory card:"),
|
||||||
wxT("Raw memcards (*.raw)|*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN);
|
wxT("Raw memcards (*.raw)|*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_OPEN);
|
||||||
m_MemcardPath_B = new wxFilePickerCtrl(this, ID_MEMCARDPATH_B, wxEmptyString, wxT("Choose a memory card:"),
|
m_MemcardPath[SLOT_B] = new wxFilePickerCtrl(this, ID_MEMCARDPATH_B, wxEmptyString, wxT("Choose a memory card:"),
|
||||||
wxT("Raw memcards (*.raw)|*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN);
|
wxT("Raw memcards (*.raw)|*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_OPEN);
|
||||||
|
|
||||||
m_MemcardList[SLOT_A] = new CMemcardListCtrl(this, ID_MEMCARDLIST_A, wxDefaultPosition, wxSize(350,400),
|
m_MemcardList[SLOT_A] = new CMemcardListCtrl(this, ID_MEMCARDLIST_A, wxDefaultPosition, wxSize(350,400),
|
||||||
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL);
|
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL);
|
||||||
|
@ -187,32 +187,32 @@ void CMemcardManager::CreateGUIControls()
|
||||||
m_MemcardList[SLOT_A]->AssignImageList(new wxImageList(96,32),wxIMAGE_LIST_SMALL);
|
m_MemcardList[SLOT_A]->AssignImageList(new wxImageList(96,32),wxIMAGE_LIST_SMALL);
|
||||||
m_MemcardList[SLOT_B]->AssignImageList(new wxImageList(96,32),wxIMAGE_LIST_SMALL);
|
m_MemcardList[SLOT_B]->AssignImageList(new wxImageList(96,32),wxIMAGE_LIST_SMALL);
|
||||||
|
|
||||||
t_Status_A = new wxStaticText(this, 0, wxEmptyString, wxDefaultPosition,wxDefaultSize, 0, wxEmptyString);
|
t_Status[SLOT_A] = new wxStaticText(this, 0, wxEmptyString, wxDefaultPosition,wxDefaultSize, 0, wxEmptyString);
|
||||||
t_Status_B = new wxStaticText(this, 0, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString);
|
t_Status[SLOT_B] = new wxStaticText(this, 0, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString);
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
m_CopyFrom_A = new wxButton(this, ID_COPYFROM_A, wxT("->Copy->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_CopyFrom[SLOT_A] = new wxButton(this, ID_COPYFROM_A, wxT("->Copy->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_CopyFrom_B = new wxButton(this, ID_COPYFROM_B, wxT("<-Copy<-"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_CopyFrom[SLOT_B] = new wxButton(this, ID_COPYFROM_B, wxT("<-Copy<-"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_FixChecksum_A = new wxButton(this, ID_FIXCHECKSUM_A, wxT("<-Fix Checksum"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_FixChecksum[SLOT_A] = new wxButton(this, ID_FIXCHECKSUM_A, wxT("<-Fix Checksum"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_FixChecksum_B = new wxButton(this, ID_FIXCHECKSUM_B, wxT("Fix Checksum->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_FixChecksum[SLOT_B] = new wxButton(this, ID_FIXCHECKSUM_B, wxT("Fix Checksum->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_SaveImport_A = new wxButton(this, ID_SAVEIMPORT_A, wxT("<-Import GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_SaveImport[SLOT_A] = new wxButton(this, ID_SAVEIMPORT_A, wxT("<-Import GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_SaveImport_B = new wxButton(this, ID_SAVEIMPORT_B, wxT("Import GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_SaveImport[SLOT_B] = new wxButton(this, ID_SAVEIMPORT_B, wxT("Import GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_SaveExport_A = new wxButton(this, ID_SAVEEXPORT_A, wxT("<-Export GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_SaveExport[SLOT_A] = new wxButton(this, ID_SAVEEXPORT_A, wxT("<-Export GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_SaveExport_B = new wxButton(this, ID_SAVEEXPORT_B, wxT("Export GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_SaveExport[SLOT_B] = new wxButton(this, ID_SAVEEXPORT_B, wxT("Export GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_ConvertToGci = new wxButton(this, ID_CONVERTTOGCI, wxT("Convert to GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_ConvertToGci = new wxButton(this, ID_CONVERTTOGCI, wxT("Convert to GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_Delete_A = new wxButton(this, ID_DELETE_A, wxT("<-Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_Delete[SLOT_A] = new wxButton(this, ID_DELETE_A, wxT("<-Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_Delete_B = new wxButton(this, ID_DELETE_B, wxT("Delete->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_Delete[SLOT_B] = new wxButton(this, ID_DELETE_B, wxT("Delete->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_PrevPage_A = new wxButton(this, ID_PREVPAGE_A, wxT("Prev Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_PrevPage[SLOT_A] = new wxButton(this, ID_PREVPAGE_A, wxT("Prev Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_PrevPage_B = new wxButton(this, ID_PREVPAGE_B, wxT("Prev Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_PrevPage[SLOT_B] = new wxButton(this, ID_PREVPAGE_B, wxT("Prev Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
m_NextPage_A = new wxButton(this, ID_NEXTPAGE_A, wxT("Next Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_NextPage[SLOT_A] = new wxButton(this, ID_NEXTPAGE_A, wxT("Next Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_NextPage_B = new wxButton(this, ID_NEXTPAGE_B, wxT("Next Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_NextPage[SLOT_B] = new wxButton(this, ID_NEXTPAGE_B, wxT("Next Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
// Sizers that double as wxStaticBoxes
|
// Sizers that double as wxStaticBoxes
|
||||||
sMemcard_A = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card A"));
|
sMemcard_A = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card A"));
|
||||||
|
@ -222,40 +222,40 @@ void CMemcardManager::CreateGUIControls()
|
||||||
wxBoxSizer* sButtons;
|
wxBoxSizer* sButtons;
|
||||||
sButtons = new wxBoxSizer(wxVERTICAL);
|
sButtons = new wxBoxSizer(wxVERTICAL);
|
||||||
sButtons->AddStretchSpacer(2);
|
sButtons->AddStretchSpacer(2);
|
||||||
sButtons->Add(m_CopyFrom_B, 0, wxEXPAND, 5);
|
sButtons->Add(m_CopyFrom[SLOT_B], 0, wxEXPAND, 5);
|
||||||
sButtons->Add(m_CopyFrom_A, 0, wxEXPAND, 5);
|
sButtons->Add(m_CopyFrom[SLOT_A], 0, wxEXPAND, 5);
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
sButtons->Add(m_FixChecksum_A, 0, wxEXPAND, 5);
|
sButtons->Add(m_FixChecksum[SLOT_A], 0, wxEXPAND, 5);
|
||||||
sButtons->Add(m_FixChecksum_B, 0, wxEXPAND, 5);
|
sButtons->Add(m_FixChecksum[SLOT_B], 0, wxEXPAND, 5);
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
sButtons->Add(m_SaveImport_A, 0, wxEXPAND, 5);
|
sButtons->Add(m_SaveImport[SLOT_A], 0, wxEXPAND, 5);
|
||||||
sButtons->Add(m_SaveExport_A, 0, wxEXPAND, 5);
|
sButtons->Add(m_SaveExport[SLOT_A], 0, wxEXPAND, 5);
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
sButtons->Add(m_ConvertToGci, 0, wxEXPAND, 5);
|
sButtons->Add(m_ConvertToGci, 0, wxEXPAND, 5);
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
sButtons->Add(m_SaveImport_B, 0, wxEXPAND, 5);
|
sButtons->Add(m_SaveImport[SLOT_B], 0, wxEXPAND, 5);
|
||||||
sButtons->Add(m_SaveExport_B, 0, wxEXPAND, 5);
|
sButtons->Add(m_SaveExport[SLOT_B], 0, wxEXPAND, 5);
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
sButtons->Add(m_Delete_A, 0, wxEXPAND, 5);
|
sButtons->Add(m_Delete[SLOT_A], 0, wxEXPAND, 5);
|
||||||
sButtons->Add(m_Delete_B, 0, wxEXPAND, 5);
|
sButtons->Add(m_Delete[SLOT_B], 0, wxEXPAND, 5);
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
|
|
||||||
sPages_A = new wxBoxSizer(wxHORIZONTAL);
|
sPages_A = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sPages_B = new wxBoxSizer(wxHORIZONTAL);
|
sPages_B = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
sPages_A->Add(m_PrevPage_A, 0, wxEXPAND|wxALL, 1);
|
sPages_A->Add(m_PrevPage[SLOT_A], 0, wxEXPAND|wxALL, 1);
|
||||||
sPages_A->Add(t_Status_A,0, wxEXPAND|wxALL, 5);
|
sPages_A->Add(t_Status[SLOT_A],0, wxEXPAND|wxALL, 5);
|
||||||
sPages_A->Add(0, 0, 1, wxEXPAND|wxALL, 0);
|
sPages_A->Add(0, 0, 1, wxEXPAND|wxALL, 0);
|
||||||
sPages_A->Add(m_NextPage_A, 0, wxEXPAND|wxALL, 1);
|
sPages_A->Add(m_NextPage[SLOT_A], 0, wxEXPAND|wxALL, 1);
|
||||||
sPages_B->Add(m_PrevPage_B, 0, wxEXPAND|wxALL, 1);
|
sPages_B->Add(m_PrevPage[SLOT_B], 0, wxEXPAND|wxALL, 1);
|
||||||
sPages_B->Add(t_Status_B, 0, wxEXPAND|wxALL, 5);
|
sPages_B->Add(t_Status[SLOT_B], 0, wxEXPAND|wxALL, 5);
|
||||||
sPages_B->Add(0, 0, 1, wxEXPAND|wxALL, 0);
|
sPages_B->Add(0, 0, 1, wxEXPAND|wxALL, 0);
|
||||||
sPages_B->Add(m_NextPage_B, 0, wxEXPAND|wxALL, 1);
|
sPages_B->Add(m_NextPage[SLOT_B], 0, wxEXPAND|wxALL, 1);
|
||||||
|
|
||||||
sMemcard_A->Add(m_MemcardPath_A, 0, wxEXPAND|wxALL, 5);
|
sMemcard_A->Add(m_MemcardPath[SLOT_A], 0, wxEXPAND|wxALL, 5);
|
||||||
sMemcard_A->Add(m_MemcardList[SLOT_A], 1, wxEXPAND|wxALL, 5);
|
sMemcard_A->Add(m_MemcardList[SLOT_A], 1, wxEXPAND|wxALL, 5);
|
||||||
sMemcard_A->Add(sPages_A, 0, wxEXPAND|wxALL, 1);
|
sMemcard_A->Add(sPages_A, 0, wxEXPAND|wxALL, 1);
|
||||||
sMemcard_B->Add(m_MemcardPath_B, 0, wxEXPAND|wxALL, 5);
|
sMemcard_B->Add(m_MemcardPath[SLOT_B], 0, wxEXPAND|wxALL, 5);
|
||||||
sMemcard_B->Add(m_MemcardList[SLOT_B], 1, wxEXPAND|wxALL, 5);
|
sMemcard_B->Add(m_MemcardList[SLOT_B], 1, wxEXPAND|wxALL, 5);
|
||||||
sMemcard_B->Add(sPages_B, 0, wxEXPAND|wxALL, 1);
|
sMemcard_B->Add(sPages_B, 0, wxEXPAND|wxALL, 1);
|
||||||
|
|
||||||
|
@ -268,20 +268,21 @@ void CMemcardManager::CreateGUIControls()
|
||||||
sMain->SetSizeHints(this);
|
sMain->SetSizeHints(this);
|
||||||
Fit();
|
Fit();
|
||||||
|
|
||||||
m_PrevPage_A->Disable();
|
m_PrevPage[SLOT_A]->Disable();
|
||||||
m_NextPage_A->Disable();
|
m_NextPage[SLOT_A]->Disable();
|
||||||
m_PrevPage_B->Disable();
|
m_PrevPage[SLOT_B]->Disable();
|
||||||
m_NextPage_B->Disable();
|
m_NextPage[SLOT_B]->Disable();
|
||||||
m_CopyFrom_A->Disable();
|
m_CopyFrom[SLOT_A]->Disable();
|
||||||
m_CopyFrom_B->Disable();
|
m_CopyFrom[SLOT_B]->Disable();
|
||||||
m_FixChecksum_A->Disable();
|
m_FixChecksum[SLOT_A]->Disable();
|
||||||
m_FixChecksum_B->Disable();
|
m_FixChecksum[SLOT_B]->Disable();
|
||||||
m_SaveImport_A->Disable();
|
m_SaveImport[SLOT_A]->Disable();
|
||||||
m_SaveExport_A->Disable();
|
m_SaveExport[SLOT_A]->Disable();
|
||||||
m_SaveImport_B->Disable();
|
m_SaveImport[SLOT_B]->Disable();
|
||||||
m_SaveExport_B->Disable();
|
m_SaveExport[SLOT_B]->Disable();
|
||||||
m_Delete_A->Disable();
|
m_Delete[SLOT_A]->Disable();
|
||||||
m_Delete_B->Disable();
|
m_Delete[SLOT_B]->Disable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemcardManager::OnClose(wxCloseEvent& WXUNUSED (event))
|
void CMemcardManager::OnClose(wxCloseEvent& WXUNUSED (event))
|
||||||
|
@ -291,158 +292,101 @@ void CMemcardManager::OnClose(wxCloseEvent& WXUNUSED (event))
|
||||||
|
|
||||||
void CMemcardManager::OnPathChange(wxFileDirPickerEvent& event)
|
void CMemcardManager::OnPathChange(wxFileDirPickerEvent& event)
|
||||||
{
|
{
|
||||||
|
int slot = SLOT_B;
|
||||||
|
int slot2 = SLOT_A;
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case ID_MEMCARDPATH_A:
|
case ID_MEMCARDPATH_A:
|
||||||
pageA = FIRSTPAGE;
|
slot = SLOT_A;
|
||||||
if (m_MemcardList[SLOT_A]->usePages && m_PrevPage_A->IsEnabled())
|
slot2 = SLOT_B;
|
||||||
{
|
|
||||||
m_PrevPage_A->Disable();
|
|
||||||
m_MemcardList[SLOT_A]->prevPage = false;
|
|
||||||
}
|
|
||||||
if (!strcasecmp(m_MemcardPath_A->GetPath().mb_str(), m_MemcardPath_B->GetPath().mb_str()))
|
|
||||||
{
|
|
||||||
PanicAlert(E_ALREADYOPENED);
|
|
||||||
}
|
|
||||||
else if (ReloadMemcard(event.GetPath().mb_str(), SLOT_A, pageA))
|
|
||||||
{
|
|
||||||
m_MemcardList[SLOT_B]->twoCardsLoaded = true;
|
|
||||||
m_FixChecksum_A->Enable();
|
|
||||||
m_SaveImport_A->Enable();
|
|
||||||
m_SaveExport_A->Enable();
|
|
||||||
m_Delete_A->Enable();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (memoryCard[SLOT_A])
|
|
||||||
{
|
|
||||||
delete memoryCard[SLOT_A];
|
|
||||||
memoryCard[SLOT_A] = NULL;
|
|
||||||
}
|
|
||||||
m_MemcardList[SLOT_B]->twoCardsLoaded = false;
|
|
||||||
m_MemcardPath_A->SetPath(wxEmptyString);
|
|
||||||
m_MemcardList[SLOT_A]->ClearAll();
|
|
||||||
t_Status_A->SetLabel(wxEmptyString);
|
|
||||||
m_FixChecksum_A->Disable();
|
|
||||||
m_SaveImport_A->Disable();
|
|
||||||
m_SaveExport_A->Disable();
|
|
||||||
m_Delete_A->Disable();
|
|
||||||
if (m_MemcardList[SLOT_A]->usePages)
|
|
||||||
{
|
|
||||||
m_PrevPage_A->Disable();
|
|
||||||
m_NextPage_A->Disable();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ID_MEMCARDPATH_B:
|
case ID_MEMCARDPATH_B:
|
||||||
pageB = FIRSTPAGE;
|
page[slot] = FIRSTPAGE;
|
||||||
if (m_MemcardList[SLOT_B]->usePages && m_PrevPage_B->IsEnabled())
|
if (m_MemcardList[slot]->usePages && m_PrevPage[slot]->IsEnabled())
|
||||||
{
|
{
|
||||||
m_PrevPage_B->Disable();
|
m_PrevPage[slot]->Disable();
|
||||||
m_MemcardList[SLOT_B]->prevPage = false;
|
m_MemcardList[slot]->prevPage = false;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(m_MemcardPath_A->GetPath().mb_str(), m_MemcardPath_B->GetPath().mb_str()))
|
if (!strcasecmp(m_MemcardPath[slot2]->GetPath().mb_str(), m_MemcardPath[slot]->GetPath().mb_str()))
|
||||||
{
|
{
|
||||||
PanicAlert(E_ALREADYOPENED);
|
PanicAlert(E_ALREADYOPENED);
|
||||||
}
|
}
|
||||||
else if (ReloadMemcard(event.GetPath().mb_str(), SLOT_B, pageB))
|
else if (ReloadMemcard(event.GetPath().mb_str(), slot))
|
||||||
{
|
{
|
||||||
m_MemcardList[SLOT_A]->twoCardsLoaded = true;
|
m_MemcardList[slot2]->twoCardsLoaded = true;
|
||||||
m_FixChecksum_B->Enable();
|
m_FixChecksum[slot]->Enable();
|
||||||
m_SaveImport_B->Enable();
|
m_SaveImport[slot]->Enable();
|
||||||
m_SaveExport_B->Enable();
|
m_SaveExport[slot]->Enable();
|
||||||
m_Delete_B->Enable();
|
m_Delete[slot]->Enable();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memoryCard[SLOT_B])
|
if (memoryCard[slot])
|
||||||
{
|
{
|
||||||
delete memoryCard[SLOT_B];
|
delete memoryCard[slot];
|
||||||
memoryCard[SLOT_B] = NULL;
|
memoryCard[slot] = NULL;
|
||||||
}
|
}
|
||||||
m_MemcardList[SLOT_A]->twoCardsLoaded = false;
|
m_MemcardList[slot2]->twoCardsLoaded = false;
|
||||||
m_MemcardPath_B->SetPath(wxEmptyString);
|
m_MemcardPath[slot]->SetPath(wxEmptyString);
|
||||||
m_MemcardList[SLOT_B]->ClearAll();
|
m_MemcardList[slot]->ClearAll();
|
||||||
t_Status_B->SetLabel(wxEmptyString);
|
t_Status[slot]->SetLabel(wxEmptyString);
|
||||||
m_FixChecksum_B->Disable();
|
m_FixChecksum[slot]->Disable();
|
||||||
m_SaveImport_B->Disable();
|
m_SaveImport[slot]->Disable();
|
||||||
m_SaveExport_B->Disable();
|
m_SaveExport[slot]->Disable();
|
||||||
m_Delete_B->Disable();
|
m_Delete[slot]->Disable();
|
||||||
if (m_MemcardList[SLOT_B]->usePages)
|
if (m_MemcardList[slot]->usePages)
|
||||||
{
|
{
|
||||||
m_PrevPage_B->Disable();
|
m_PrevPage[slot]->Disable();
|
||||||
m_NextPage_B->Disable();
|
m_NextPage[slot]->Disable();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (m_Delete_B->IsEnabled() && m_Delete_A->IsEnabled())
|
if (m_Delete[slot]->IsEnabled() && m_Delete[slot2]->IsEnabled())
|
||||||
{
|
{
|
||||||
m_CopyFrom_A->Enable();
|
m_CopyFrom[SLOT_A]->Enable();
|
||||||
m_CopyFrom_B->Enable();
|
m_CopyFrom[SLOT_B]->Enable();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_CopyFrom_A->Disable();
|
m_CopyFrom[SLOT_A]->Disable();
|
||||||
m_CopyFrom_B->Disable();
|
m_CopyFrom[SLOT_B]->Disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemcardManager::OnPageChange(wxCommandEvent& event)
|
void CMemcardManager::OnPageChange(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
|
int slot = SLOT_B;
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case ID_NEXTPAGE_A:
|
case ID_NEXTPAGE_A:
|
||||||
if (!m_PrevPage_A->IsEnabled())
|
slot = SLOT_A;
|
||||||
{
|
|
||||||
m_PrevPage_A->Enable();
|
|
||||||
m_MemcardList[SLOT_A]->prevPage = true;
|
|
||||||
}
|
|
||||||
pageA++;
|
|
||||||
if (pageA == maxPages)
|
|
||||||
{
|
|
||||||
m_NextPage_A->Disable();
|
|
||||||
m_MemcardList[SLOT_A]->nextPage = false;
|
|
||||||
}
|
|
||||||
ReloadMemcard(m_MemcardPath_A->GetPath().mb_str(), SLOT_A, pageA);
|
|
||||||
break;
|
|
||||||
case ID_NEXTPAGE_B:
|
case ID_NEXTPAGE_B:
|
||||||
if (!m_PrevPage_B->IsEnabled())
|
if (!m_PrevPage[slot]->IsEnabled())
|
||||||
{
|
{
|
||||||
m_PrevPage_B->Enable();
|
m_PrevPage[slot]->Enable();
|
||||||
m_MemcardList[SLOT_B]->prevPage = true;
|
m_MemcardList[slot]->prevPage = true;
|
||||||
}
|
}
|
||||||
pageB++;
|
page[slot]++;
|
||||||
if (pageB == maxPages)
|
if (page[slot] == maxPages)
|
||||||
{
|
{
|
||||||
m_NextPage_B->Disable();
|
m_NextPage[slot]->Disable();
|
||||||
m_MemcardList[SLOT_B]->nextPage = false;
|
m_MemcardList[slot]->nextPage = false;
|
||||||
}
|
}
|
||||||
ReloadMemcard(m_MemcardPath_B->GetPath().mb_str(), SLOT_B, pageB);
|
ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot);
|
||||||
break;
|
break;
|
||||||
case ID_PREVPAGE_A:
|
case ID_PREVPAGE_A:
|
||||||
if (!m_NextPage_A->IsEnabled())
|
slot = SLOT_A;
|
||||||
{
|
|
||||||
m_NextPage_A->Enable();
|
|
||||||
m_MemcardList[SLOT_A]->nextPage = true;
|
|
||||||
}
|
|
||||||
pageA--;
|
|
||||||
if (!pageA)
|
|
||||||
{
|
|
||||||
m_PrevPage_A->Disable();
|
|
||||||
m_MemcardList[SLOT_A]->prevPage = false;
|
|
||||||
}
|
|
||||||
ReloadMemcard(m_MemcardPath_A->GetPath().mb_str(), SLOT_A, pageA);
|
|
||||||
break;
|
|
||||||
case ID_PREVPAGE_B:
|
case ID_PREVPAGE_B:
|
||||||
if (!m_NextPage_B->IsEnabled())
|
if (!m_NextPage[slot]->IsEnabled())
|
||||||
{
|
{
|
||||||
m_NextPage_B->Enable();
|
m_NextPage[slot]->Enable();
|
||||||
m_MemcardList[SLOT_B]->nextPage = true;
|
m_MemcardList[slot]->nextPage = true;
|
||||||
}
|
}
|
||||||
pageB--;
|
page[slot]--;
|
||||||
if (!pageB)
|
if (!page[slot])
|
||||||
{
|
{
|
||||||
m_PrevPage_B->Disable();
|
m_PrevPage[slot]->Disable();
|
||||||
m_MemcardList[SLOT_B]->prevPage = false;
|
m_MemcardList[slot]->prevPage = false;
|
||||||
}
|
}
|
||||||
ReloadMemcard(m_MemcardPath_B->GetPath().mb_str(), SLOT_B, pageB);
|
ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,11 +399,11 @@ void CMemcardManager::OnMenuChange(wxCommandEvent& event)
|
||||||
m_MemcardList[SLOT_B]->usePages = !m_MemcardList[SLOT_B]->usePages;
|
m_MemcardList[SLOT_B]->usePages = !m_MemcardList[SLOT_B]->usePages;
|
||||||
if (!m_MemcardList[SLOT_A]->usePages)
|
if (!m_MemcardList[SLOT_A]->usePages)
|
||||||
{
|
{
|
||||||
m_PrevPage_A->Disable();
|
m_PrevPage[SLOT_A]->Disable();
|
||||||
m_PrevPage_B->Disable();
|
m_PrevPage[SLOT_B]->Disable();
|
||||||
m_NextPage_A->Disable();
|
m_NextPage[SLOT_A]->Disable();
|
||||||
m_NextPage_B->Disable();
|
m_NextPage[SLOT_B]->Disable();
|
||||||
pageA = pageB = FIRSTPAGE;
|
page[SLOT_A] = page[SLOT_B] = FIRSTPAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -467,13 +411,12 @@ void CMemcardManager::OnMenuChange(wxCommandEvent& event)
|
||||||
m_MemcardList[SLOT_A]->column[event.GetId()] = !m_MemcardList[SLOT_A]->column[event.GetId()];
|
m_MemcardList[SLOT_A]->column[event.GetId()] = !m_MemcardList[SLOT_A]->column[event.GetId()];
|
||||||
m_MemcardList[SLOT_B]->column[event.GetId()] = !m_MemcardList[SLOT_B]->column[event.GetId()];
|
m_MemcardList[SLOT_B]->column[event.GetId()] = !m_MemcardList[SLOT_B]->column[event.GetId()];
|
||||||
}
|
}
|
||||||
if (memoryCard[SLOT_A]) ReloadMemcard(m_MemcardPath_A->GetPath().mb_str(), SLOT_A, pageA);
|
if (memoryCard[SLOT_A]) ReloadMemcard(m_MemcardPath[SLOT_A]->GetPath().mb_str(), SLOT_A);
|
||||||
if (memoryCard[SLOT_B]) ReloadMemcard(m_MemcardPath_B->GetPath().mb_str(), SLOT_B, pageB);
|
if (memoryCard[SLOT_B]) ReloadMemcard(m_MemcardPath[SLOT_B]->GetPath().mb_str(), SLOT_B);
|
||||||
|
|
||||||
}
|
}
|
||||||
bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot)
|
bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot)
|
||||||
{
|
{
|
||||||
wxString blocksOpen;
|
|
||||||
switch (error)
|
switch (error)
|
||||||
{
|
{
|
||||||
case GCS:
|
case GCS:
|
||||||
|
@ -484,8 +427,8 @@ bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot)
|
||||||
{
|
{
|
||||||
memoryCard[slot]->FixChecksums();
|
memoryCard[slot]->FixChecksums();
|
||||||
if (!memoryCard[slot]->Save()) PanicAlert(E_SAVEFAILED);
|
if (!memoryCard[slot]->Save()) PanicAlert(E_SAVEFAILED);
|
||||||
slot == SLOT_B ? ReloadMemcard(m_MemcardPath_B->GetPath().mb_str(), slot, FIRSTPAGE)
|
page[slot] = FIRSTPAGE;
|
||||||
: ReloadMemcard(m_MemcardPath_A->GetPath().mb_str(), slot, FIRSTPAGE);
|
ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NOMEMCARD:
|
case NOMEMCARD:
|
||||||
|
@ -500,8 +443,7 @@ bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot)
|
||||||
PanicAlert(E_UNK);
|
PanicAlert(E_UNK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
blocksOpen.Printf(wxT(E_OUTOFBLOCKS), memoryCard[slot]->GetFreeBlocks());
|
PanicAlert(wxString::Format(wxT(E_OUTOFBLOCKS), memoryCard[slot]->GetFreeBlocks()));
|
||||||
PanicAlert(blocksOpen.ToAscii());
|
|
||||||
break;
|
break;
|
||||||
case OUTOFDIRENTRIES:
|
case OUTOFDIRENTRIES:
|
||||||
PanicAlert(E_OUTOFDIRENTRIES);
|
PanicAlert(E_OUTOFDIRENTRIES);
|
||||||
|
@ -545,8 +487,8 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
int index = index_B;
|
int index = index_B;
|
||||||
std::string fileName2("");
|
std::string fileName2("");
|
||||||
|
|
||||||
if (index_A != wxNOT_FOUND && pageA) index_A += itemsPerPage * pageA;
|
if (index_A != wxNOT_FOUND && page[SLOT_A]) index_A += itemsPerPage * page[SLOT_A];
|
||||||
if (index_B != wxNOT_FOUND && pageB) index_B += itemsPerPage * pageB;
|
if (index_B != wxNOT_FOUND && page[SLOT_B]) index_B += itemsPerPage * page[SLOT_B];
|
||||||
|
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
|
@ -640,7 +582,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
|
bool CMemcardManager::ReloadMemcard(const char *fileName, int card)
|
||||||
{
|
{
|
||||||
wxString wxBlock;
|
wxString wxBlock;
|
||||||
wxString wxFirstBlock;
|
wxString wxFirstBlock;
|
||||||
|
@ -652,7 +594,7 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
|
||||||
// TODO: add error checking and animate icons
|
// TODO: add error checking and animate icons
|
||||||
memoryCard[card] = new GCMemcard(fileName);
|
memoryCard[card] = new GCMemcard(fileName);
|
||||||
|
|
||||||
if (ReadError(memoryCard[card])) return false;
|
if (memoryCard[card]->fail) return false;
|
||||||
|
|
||||||
m_MemcardList[card]->Hide();
|
m_MemcardList[card]->Hide();
|
||||||
m_MemcardList[card]->ClearAll();
|
m_MemcardList[card]->ClearAll();
|
||||||
|
@ -719,8 +661,8 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int pagesMax = 128;
|
int pagesMax = 128;
|
||||||
if (m_MemcardList[card]->usePages) pagesMax = (page + 1) * itemsPerPage;
|
if (m_MemcardList[card]->usePages) pagesMax = (page[card] + 1) * itemsPerPage;
|
||||||
for (j = page * itemsPerPage;(j < nFiles) && (j < pagesMax);j++)
|
for (j = page[card] * itemsPerPage;(j < nFiles) && (j < pagesMax);j++)
|
||||||
{
|
{
|
||||||
char title[32];
|
char title[32];
|
||||||
char comment[32];
|
char comment[32];
|
||||||
|
@ -755,29 +697,13 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
|
||||||
{
|
{
|
||||||
if ((j == nFiles))
|
if ((j == nFiles))
|
||||||
{
|
{
|
||||||
if (card)
|
m_NextPage[card]->Disable();
|
||||||
{
|
m_MemcardList[card]->nextPage = false;
|
||||||
m_NextPage_B->Disable();
|
|
||||||
m_MemcardList[SLOT_B]->nextPage = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_NextPage_A->Disable();
|
|
||||||
m_MemcardList[SLOT_A]->nextPage = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (card)
|
m_NextPage[card]->Enable();
|
||||||
{
|
m_MemcardList[card]->nextPage = true;
|
||||||
m_NextPage_B->Enable();
|
|
||||||
m_MemcardList[SLOT_B]->nextPage = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_NextPage_A->Enable();
|
|
||||||
m_MemcardList[SLOT_A]->nextPage = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,29 +720,11 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
|
||||||
m_MemcardList[card]->Show();
|
m_MemcardList[card]->Show();
|
||||||
wxLabel.Printf(wxT("%d Free Blocks; %d Free Dir Entries"),
|
wxLabel.Printf(wxT("%d Free Blocks; %d Free Dir Entries"),
|
||||||
memoryCard[card]->GetFreeBlocks(), 127 - nFiles);
|
memoryCard[card]->GetFreeBlocks(), 127 - nFiles);
|
||||||
card ? t_Status_B->SetLabel(wxLabel) : t_Status_A->SetLabel(wxLabel);
|
t_Status[card]->SetLabel(wxLabel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMemcardManager::ReadError(GCMemcard *memcard)
|
|
||||||
{
|
|
||||||
if (!memcard->fail[0]) return false;
|
|
||||||
wxString wxBlock;
|
|
||||||
if (memcard->fail[HDR_READ_ERROR]) PanicAlert("Failed to read header correctly\n(0x0000-0x1FFF)");
|
|
||||||
if (memcard->fail[DIR_READ_ERROR]) PanicAlert("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
|
||||||
if (memcard->fail[DIR_BAK_READ_ERROR]) PanicAlert("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
|
||||||
if (memcard->fail[BAT_READ_ERROR]) PanicAlert("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
|
||||||
if (memcard->fail[BAT_BAK_READ_ERROR]) PanicAlert("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
|
||||||
if (memcard->fail[HDR_CSUM_FAIL]) PanicAlert("Header checksum failed");
|
|
||||||
if (memcard->fail[DIR_CSUM_FAIL]) PanicAlert("Directory checksum failed\n and Directory backup checksum failed");
|
|
||||||
if (memcard->fail[BAT_CSUM_FAIL]) PanicAlert("Block Allocation Table checksum failed");
|
|
||||||
if (memcard->fail[DATA_READ_FAIL]) PanicAlert("Failed to read save data\n(0xA000-)\nMemcard may be truncated");
|
|
||||||
if (memcard->fail[HDR_SIZE_FFFF]) PanicAlert("Memcard failed to load\n Card size is invalid");
|
|
||||||
if (memcard->fail[NOTRAWORGCP]) PanicAlert("File does not have a valid extension (.raw/.gcp)");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemcardManager::CMemcardListCtrl::OnRightClick(wxMouseEvent& event)
|
void CMemcardManager::CMemcardListCtrl::OnRightClick(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -61,37 +61,28 @@ class CMemcardManager
|
||||||
private:
|
private:
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
int pageA,
|
int page[2],
|
||||||
pageB,
|
|
||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
maxPages;
|
maxPages;
|
||||||
|
std::string DefaultMemcard[2];
|
||||||
wxBoxSizer *sMain;
|
|
||||||
wxBoxSizer *sPages_A;
|
|
||||||
wxBoxSizer *sPages_B;
|
|
||||||
wxStaticText *t_Status_A;
|
|
||||||
wxStaticText *t_Status_B;
|
|
||||||
wxButton *m_CopyFrom_A;
|
|
||||||
wxButton *m_CopyFrom_B;
|
|
||||||
wxButton *m_FixChecksum_A;
|
|
||||||
wxButton *m_FixChecksum_B;
|
|
||||||
wxButton *m_SaveImport_A;
|
|
||||||
wxButton *m_SaveImport_B;
|
|
||||||
wxButton *m_SaveExport_A;
|
|
||||||
wxButton *m_SaveExport_B;
|
|
||||||
wxButton *m_ConvertToGci;
|
|
||||||
wxButton *m_Delete_A;
|
|
||||||
wxButton *m_Delete_B;
|
|
||||||
wxButton *m_NextPage_A;
|
|
||||||
wxButton *m_NextPage_B;
|
|
||||||
wxButton *m_PrevPage_A;
|
|
||||||
wxButton *m_PrevPage_B;
|
|
||||||
wxStaticBoxSizer *sMemcard_A;
|
|
||||||
wxStaticBoxSizer *sMemcard_B;
|
|
||||||
wxFilePickerCtrl *m_MemcardPath_A;
|
|
||||||
wxFilePickerCtrl *m_MemcardPath_B;
|
|
||||||
IniFile MemcardManagerIni;
|
IniFile MemcardManagerIni;
|
||||||
|
|
||||||
|
wxBoxSizer *sMain,
|
||||||
|
*sPages_A,
|
||||||
|
*sPages_B;
|
||||||
|
wxButton *m_CopyFrom[2],
|
||||||
|
*m_FixChecksum[2],
|
||||||
|
*m_SaveImport[2],
|
||||||
|
*m_SaveExport[2],
|
||||||
|
*m_Delete[2],
|
||||||
|
*m_NextPage[2],
|
||||||
|
*m_PrevPage[2],
|
||||||
|
*m_ConvertToGci;
|
||||||
|
wxFilePickerCtrl *m_MemcardPath[2];
|
||||||
|
wxStaticBoxSizer *sMemcard_A,
|
||||||
|
*sMemcard_B;
|
||||||
|
wxStaticText *t_Status[2];
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ID_COPYFROM_A = 1000,
|
ID_COPYFROM_A = 1000,
|
||||||
|
@ -133,11 +124,10 @@ class CMemcardManager
|
||||||
void CreateGUIControls();
|
void CreateGUIControls();
|
||||||
void OnClose(wxCloseEvent& event);
|
void OnClose(wxCloseEvent& event);
|
||||||
void CopyDeleteClick(wxCommandEvent& event);
|
void CopyDeleteClick(wxCommandEvent& event);
|
||||||
bool ReloadMemcard(const char *fileName, int card, int page);
|
bool ReloadMemcard(const char *fileName, int card);
|
||||||
void OnMenuChange(wxCommandEvent& event);
|
void OnMenuChange(wxCommandEvent& event);
|
||||||
void OnPageChange(wxCommandEvent& event);
|
void OnPageChange(wxCommandEvent& event);
|
||||||
void OnPathChange(wxFileDirPickerEvent& event);
|
void OnPathChange(wxFileDirPickerEvent& event);
|
||||||
bool ReadError(GCMemcard *memcard);
|
|
||||||
bool CopyDeleteSwitch(u32 error, int slot);
|
bool CopyDeleteSwitch(u32 error, int slot);
|
||||||
|
|
||||||
class CMemcardListCtrl : public wxListCtrl
|
class CMemcardListCtrl : public wxListCtrl
|
||||||
|
|
|
@ -29,16 +29,6 @@ void ByteSwap(u8 *valueA, u8 *valueB)
|
||||||
*valueB = tmp;
|
*valueB = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 decode5A3(u16 val)
|
u32 decode5A3(u16 val)
|
||||||
{
|
{
|
||||||
const int lut5to8[] = { 0x00,0x08,0x10,0x18,0x20,0x29,0x31,0x39,
|
const int lut5to8[] = { 0x00,0x08,0x10,0x18,0x20,0x29,0x31,0x39,
|
||||||
|
@ -77,7 +67,7 @@ void decode5A3image(u32* dst, u16* src, int width, int height)
|
||||||
{
|
{
|
||||||
for (int ix = 0; ix < 4; ix++)
|
for (int ix = 0; ix < 4; ix++)
|
||||||
{
|
{
|
||||||
u32 RGBA = decode5A3(bswap16(src[ix]));
|
u32 RGBA = decode5A3(Common::swap16(src[ix]));
|
||||||
dst[(y + iy) * width + (x + ix)] = RGBA;
|
dst[(y + iy) * width + (x + ix)] = RGBA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +86,7 @@ void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height)
|
||||||
u32 *tdst = dst+(y+iy)*width+x;
|
u32 *tdst = dst+(y+iy)*width+x;
|
||||||
for (int ix = 0; ix < 8; ix++)
|
for (int ix = 0; ix < 8; ix++)
|
||||||
{
|
{
|
||||||
tdst[ix] = decode5A3(bswap16(pal[src[ix]]));
|
tdst[ix] = decode5A3(Common::swap16(pal[src[ix]]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,52 +95,69 @@ void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height)
|
||||||
|
|
||||||
GCMemcard::GCMemcard(const char *filename)
|
GCMemcard::GCMemcard(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *mcd = fopen(filename,"r+b");
|
FILE *mcd = fopen(filename, "r+b");
|
||||||
mcdFile = mcd;
|
mcdFile = mcd;
|
||||||
fail[0] = true;
|
fail = false;
|
||||||
if (!mcd) return;
|
if (!mcd)
|
||||||
|
|
||||||
for(int i=0;i<FAILLAST;i++)fail[i]=false;
|
|
||||||
|
|
||||||
//This function can be removed once more about hdr is known and we can check for a valid header
|
|
||||||
std::string fileType;
|
|
||||||
SplitPath(filename, NULL, NULL, &fileType);
|
|
||||||
if (strcasecmp(fileType.c_str(), ".raw") && strcasecmp(fileType.c_str(), ".gcp"))
|
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
if (!PanicYesNo("File does not exist.\n Create a new 16MB Memcard?"))
|
||||||
fail[NOTRAWORGCP] = true;
|
{
|
||||||
return;
|
fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mcd = fopen(filename, "wb");
|
||||||
|
if (!mcd)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mcdFile = mcd;
|
||||||
|
format(true);
|
||||||
|
fclose(mcd);
|
||||||
|
mcd = fopen(filename, "r+b");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//This function can be removed once more about hdr is known and we can check for a valid header
|
||||||
|
std::string fileType;
|
||||||
|
SplitPath(filename, NULL, NULL, &fileType);
|
||||||
|
if (strcasecmp(fileType.c_str(), ".raw") && strcasecmp(fileType.c_str(), ".gcp"))
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
PanicAlert("File does not have a valid extension (.raw/.gcp)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(mcd, 0x0000, SEEK_SET);
|
fseek(mcd, 0x0000, SEEK_SET);
|
||||||
if (fread(&hdr, 1, 0x2000, mcd) != 0x2000)
|
if (fread(&hdr, 1, 0x2000, mcd) != 0x2000)
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[HDR_READ_ERROR] = true;
|
PanicAlert("Failed to read header correctly\n(0x0000-0x1FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&dir, 1, 0x2000, mcd) != 0x2000)
|
if (fread(&dir, 1, 0x2000, mcd) != 0x2000)
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[DIR_READ_ERROR] = true;
|
PanicAlert("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&dir_backup, 1, 0x2000, mcd) != 0x2000)
|
if (fread(&dir_backup, 1, 0x2000, mcd) != 0x2000)
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[DIR_BAK_READ_ERROR] = true;
|
PanicAlert("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&bat, 1, 0x2000, mcd) != 0x2000)
|
if (fread(&bat, 1, 0x2000, mcd) != 0x2000)
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[BAT_READ_ERROR] = true;
|
PanicAlert("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fread(&bat_backup, 1, 0x2000, mcd) != 0x2000)
|
if (fread(&bat_backup, 1, 0x2000, mcd) != 0x2000)
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[BAT_BAK_READ_ERROR] = true;
|
PanicAlert("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,8 +167,8 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
{
|
{
|
||||||
// header checksum error!
|
// header checksum error!
|
||||||
// invalid files do not always get here
|
// invalid files do not always get here
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[HDR_CSUM_FAIL] = true;
|
PanicAlert("Header checksum failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +177,8 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
if (csums&4)
|
if (csums&4)
|
||||||
{
|
{
|
||||||
// backup is also wrong!
|
// backup is also wrong!
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[DIR_CSUM_FAIL] = true;
|
PanicAlert("Directory checksum failed\n and Directory backup checksum failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -190,8 +197,8 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
if (csums&16)
|
if (csums&16)
|
||||||
{
|
{
|
||||||
// backup is also wrong!
|
// backup is also wrong!
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[BAT_CSUM_FAIL] = true;
|
PanicAlert("Block Allocation Table checksum failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -227,14 +234,14 @@ GCMemcard::GCMemcard(const char *filename)
|
||||||
size_t read = fread(mc_data, 1, mc_data_size, mcd);
|
size_t read = fread(mc_data, 1, mc_data_size, mcd);
|
||||||
if (mc_data_size != read)
|
if (mc_data_size != read)
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[DATA_READ_FAIL] = true;
|
PanicAlert("Failed to read save data\n(0xA000-)\nMemcard may be truncated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fail[0] = true;
|
fail = true;
|
||||||
fail[HDR_SIZE_FFFF] = true;
|
PanicAlert("Memcard failed to load\n Card size is invalid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,8 +276,8 @@ void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
|
||||||
for (u32 i = 0; i < num; ++i)
|
for (u32 i = 0; i < num; ++i)
|
||||||
{
|
{
|
||||||
//weird warnings here
|
//weird warnings here
|
||||||
*c1 += bswap16(buf[i]);
|
*c1 += Common::swap16(buf[i]);
|
||||||
*c2 += bswap16((u16)(buf[i] ^ 0xffff));
|
*c2 += Common::swap16((u16)(buf[i] ^ 0xffff));
|
||||||
}
|
}
|
||||||
if (*c1 == 0xffff)
|
if (*c1 == 0xffff)
|
||||||
{
|
{
|
||||||
|
@ -496,7 +503,7 @@ u32 GCMemcard::GetFileData(u32 index, u8* dest, bool old) //index in the directo
|
||||||
memcpy(dest,mc_data + 0x2000 * (block - 5), 0x2000);
|
memcpy(dest,mc_data + 0x2000 * (block - 5), 0x2000);
|
||||||
dest+=0x2000;
|
dest+=0x2000;
|
||||||
|
|
||||||
u16 nextblock = bswap16(bat.Map[block - 5]);
|
u16 nextblock = Common::swap16(bat.Map[block - 5]);
|
||||||
if (block + saveLength != memcardSize && nextblock > 0)
|
if (block + saveLength != memcardSize && nextblock > 0)
|
||||||
{//Fixes for older memcards that were not initialized with FF
|
{//Fixes for older memcards that were not initialized with FF
|
||||||
block = nextblock;
|
block = nextblock;
|
||||||
|
@ -570,7 +577,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
|
||||||
int j = 2;
|
int j = 2;
|
||||||
while(j < BE16(direntry.BlockCount) + 1)
|
while(j < BE16(direntry.BlockCount) + 1)
|
||||||
{
|
{
|
||||||
bat_backup.Map[i] = bswap16(last + (u16)j);
|
bat_backup.Map[i] = Common::swap16(last + (u16)j);
|
||||||
i++;
|
i++;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -985,3 +992,84 @@ u32 GCMemcard::ReadAnimRGBA8(u32 index, u32* buffer, u8 *delays)
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GCMemcard::format(bool New)
|
||||||
|
{
|
||||||
|
u32 data_size = 0x2000 * (0x80 * 0x10 - 5);
|
||||||
|
if (New)
|
||||||
|
{
|
||||||
|
mc_data_size = data_size;
|
||||||
|
mc_data = new u8[mc_data_size];
|
||||||
|
}
|
||||||
|
// Only Format 16MB memcards for now
|
||||||
|
if (data_size != mc_data_size) return false;
|
||||||
|
// TODO:Once more is known about the header we can
|
||||||
|
// correct this function
|
||||||
|
memset(&hdr, 0xFF, 0x2000);
|
||||||
|
memset(&dir, 0xFF, 0x2000);
|
||||||
|
memset(&dir_backup, 0xFF, 0x2000);
|
||||||
|
memset(&bat, 0, 0x2000);
|
||||||
|
memset(&bat_backup, 0, 0x2000);
|
||||||
|
memset(mc_data, 0xFF, mc_data_size);
|
||||||
|
hdr.Unk1[0] = 0xE3;
|
||||||
|
hdr.Unk1[1] = 0x63;
|
||||||
|
hdr.Unk1[2] = 0x27;
|
||||||
|
hdr.Unk1[3] = 0xC1;
|
||||||
|
hdr.Unk1[4] = 0x6B;
|
||||||
|
hdr.Unk1[5] = 0x11;
|
||||||
|
hdr.Unk1[6] = 0xEC;
|
||||||
|
hdr.Unk1[7] = 0x47;
|
||||||
|
hdr.Unk1[8] = 0xF0;
|
||||||
|
hdr.Unk1[9] = 0x12;
|
||||||
|
hdr.Unk1[10] = 0x99;
|
||||||
|
hdr.Unk1[11] = 0x13;
|
||||||
|
hdr.fmtTime.low = 0x5CB62800;
|
||||||
|
hdr.fmtTime.high = 0xA665E7A3;
|
||||||
|
hdr.SramBias[3] = 0x40;
|
||||||
|
hdr.Unk2[0] = 0;
|
||||||
|
hdr.Unk2[1] = 0;
|
||||||
|
hdr.Unk2[2] = 0;
|
||||||
|
hdr.Unk2[3] = 0;
|
||||||
|
hdr.Unk2[4] = 0;
|
||||||
|
hdr.Unk2[5] = 0;
|
||||||
|
hdr.Unk2[6] = 0;
|
||||||
|
hdr.Unk2[7] = 0x01;
|
||||||
|
hdr.Pad1[0] = 0;
|
||||||
|
hdr.Pad1[1] = 0;
|
||||||
|
hdr.Size[0] = 0;
|
||||||
|
hdr.Size[1] = 0x80;
|
||||||
|
hdr.Encoding[0] = 0;
|
||||||
|
hdr.Encoding[1] = 0;
|
||||||
|
//hdr.CheckSum1[0] = 0xAA;
|
||||||
|
//hdr.CheckSum1[1] = 0x87;
|
||||||
|
//hdr.CheckSum2[0] = 0x54;
|
||||||
|
//hdr.CheckSum2[1] = 0x7B;
|
||||||
|
dir.UpdateCounter[0] = 0;
|
||||||
|
dir.UpdateCounter[1] = 0;
|
||||||
|
//dir.CheckSum1[0] = 0xF0;
|
||||||
|
//dir.CheckSum1[1] = 0x03;
|
||||||
|
//dir.CheckSum2[0] = 0;
|
||||||
|
//dir.CheckSum2[1] = 0;
|
||||||
|
dir_backup.UpdateCounter[0] = 0;
|
||||||
|
dir_backup.UpdateCounter[1] = 0x01;
|
||||||
|
//dir_backup.CheckSum1[0] = 0xF0;
|
||||||
|
//dir_backup.CheckSum1[1] = 0x04;
|
||||||
|
//dir_backup.CheckSum2[1] = 0xFE;
|
||||||
|
//bat.CheckSum1[0] = 0x07;
|
||||||
|
//bat.CheckSum1[1] = 0xFF;
|
||||||
|
//bat.CheckSum2[0] = 0xE8;
|
||||||
|
//bat.CheckSum2[1] = 0x03;
|
||||||
|
bat.FreeBlocks[0] = 0x07;
|
||||||
|
bat.FreeBlocks[1] = 0xFB;
|
||||||
|
bat.LastAllocated[1] = 0x04;
|
||||||
|
//bat_backup.CheckSum1[0] = 0x08;
|
||||||
|
//bat_backup.CheckSum2[0] = 0xE8;
|
||||||
|
//bat_backup.CheckSum2[1] = 0x02;
|
||||||
|
bat_backup.UpdateCounter[1] = 0x01;
|
||||||
|
bat_backup.FreeBlocks[0] = 0x07;
|
||||||
|
bat_backup.FreeBlocks[1] = 0xFB;
|
||||||
|
bat_backup.LastAllocated[1] = 0x04;
|
||||||
|
FixChecksums();
|
||||||
|
Save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -25,17 +25,6 @@ enum
|
||||||
GCI = 0,
|
GCI = 0,
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
NOMEMCARD,
|
NOMEMCARD,
|
||||||
HDR_READ_ERROR,
|
|
||||||
DIR_READ_ERROR,
|
|
||||||
DIR_BAK_READ_ERROR,
|
|
||||||
BAT_READ_ERROR,
|
|
||||||
BAT_BAK_READ_ERROR,
|
|
||||||
HDR_CSUM_FAIL,
|
|
||||||
DIR_CSUM_FAIL,
|
|
||||||
BAT_CSUM_FAIL,
|
|
||||||
DATA_READ_FAIL,
|
|
||||||
HDR_SIZE_FFFF,
|
|
||||||
NOTRAWORGCP,
|
|
||||||
OPENFAIL,
|
OPENFAIL,
|
||||||
OUTOFBLOCKS,
|
OUTOFBLOCKS,
|
||||||
OUTOFDIRENTRIES,
|
OUTOFDIRENTRIES,
|
||||||
|
@ -48,7 +37,6 @@ enum
|
||||||
GCSFAIL,
|
GCSFAIL,
|
||||||
FAIL,
|
FAIL,
|
||||||
WRITEFAIL,
|
WRITEFAIL,
|
||||||
FAILLAST,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GCMemcard
|
class GCMemcard
|
||||||
|
@ -145,7 +133,7 @@ private:
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool fail[FAILLAST];
|
bool fail;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
GCMemcard(const char* fileName);
|
GCMemcard(const char* fileName);
|
||||||
|
@ -155,6 +143,7 @@ public:
|
||||||
|
|
||||||
bool IsOpen();
|
bool IsOpen();
|
||||||
bool Save();
|
bool Save();
|
||||||
|
bool format(bool New);
|
||||||
|
|
||||||
void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2);
|
void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2);
|
||||||
u32 TestChecksums();
|
u32 TestChecksums();
|
||||||
|
@ -164,7 +153,7 @@ public:
|
||||||
u32 GetNumFiles();
|
u32 GetNumFiles();
|
||||||
|
|
||||||
// get the free blocks from bat
|
// get the free blocks from bat
|
||||||
u16 GetFreeBlocks(void);
|
u16 GetFreeBlocks();
|
||||||
|
|
||||||
// Returns true if title already on memcard
|
// Returns true if title already on memcard
|
||||||
bool TitlePresent(DEntry d);
|
bool TitlePresent(DEntry d);
|
||||||
|
|
|
@ -240,7 +240,7 @@ void ConfigBox::CreateGUIControls()
|
||||||
// GUI center button
|
// GUI center button
|
||||||
m_JoyButtonStart[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONSTART, wxT("0"), wxPoint(278, 403), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
|
m_JoyButtonStart[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONSTART, wxT("0"), wxPoint(278, 403), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
|
||||||
m_JoyButtonStart[i]->Enable(false);
|
m_JoyButtonStart[i]->Enable(false);
|
||||||
m_bJoyButtonCalibrate[i] = new wxButton(m_Controller[i], ID_BUTTONCALIBRATE, wxT("Calibrate"), wxPoint(297, 440), wxSize(21, 14), 0, wxDefaultValidator, wxT("Calibrate"));
|
m_bJoyButtonCalibrate[i] = new wxButton(m_Controller[i], ID_BUTTONCALIBRATE, wxT("Calibrate"), wxPoint(283, 430), wxSize(50, 20), 0, wxDefaultValidator, wxT("Calibrate"));
|
||||||
m_JoyButtonHalfpress[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONHALFPRESS, wxT("0"), wxPoint(167, 424), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
|
m_JoyButtonHalfpress[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONHALFPRESS, wxT("0"), wxPoint(167, 424), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0"));
|
||||||
m_JoyButtonHalfpress[i]->Enable(false);
|
m_JoyButtonHalfpress[i]->Enable(false);
|
||||||
m_bJoyButtonStart[i] = new wxButton(m_Controller[i], IDB_BUTTONSTART, wxEmptyString, wxPoint(297, 385), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString);
|
m_bJoyButtonStart[i] = new wxButton(m_Controller[i], IDB_BUTTONSTART, wxEmptyString, wxPoint(297, 385), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString);
|
||||||
|
|
Loading…
Reference in New Issue