My first commit, renames AddGci and SaveGci to ImportGci and ExportGci

adds Madcatz gameshark .gcs, and Datel Maxdrive/pro .sav file support to function importgci
adds conversion from .gcs and .sav to .gci, added to speed up testing for .gcs and .sav until ImportFile is fixed

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@856 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99 2008-10-14 03:16:09 +00:00
parent 1cdddbcca9
commit 0629cc6690
4 changed files with 190 additions and 31 deletions

View File

@ -81,6 +81,7 @@ BEGIN_EVENT_TABLE(CMemcardManager, wxDialog)
EVT_BUTTON(ID_GCISAVERIGHT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_GCIOPENLEFT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_GCISAVELEFT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_CONVERTTOGCI,CMemcardManager::CopyDeleteClick)
EVT_FILEPICKER_CHANGED(ID_MEMCARD1PATH,CMemcardManager::OnPathChange)
EVT_FILEPICKER_CHANGED(ID_MEMCARD2PATH,CMemcardManager::OnPathChange)
END_EVENT_TABLE()
@ -119,6 +120,9 @@ void CMemcardManager::CreateGUIControls()
m_GciSaveLeft = new wxButton(this, ID_GCISAVELEFT, wxT("<-Export GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_GciOpenRight = new wxButton(this, ID_GCIOPENRIGHT, wxT("Import GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_GciSaveRight = new wxButton(this, ID_GCISAVERIGHT, wxT("Export GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
//Added to test GCS and SAV import, until ImportFile is fixed
//rather than needing to import and then export
m_ConvertToGci = new wxButton(this, ID_CONVERTTOGCI, wxT("Convert to GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_DeleteLeft = new wxButton(this, ID_DELETELEFT, wxT("<-Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_DeleteRight = new wxButton(this, ID_DELETERIGHT, wxT("Delete->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
@ -154,6 +158,8 @@ void CMemcardManager::CreateGUIControls()
sButtons->Add(m_GciOpenLeft, 0, wxEXPAND, 5);
sButtons->Add(m_GciSaveLeft, 0, wxEXPAND, 5);
sButtons->AddStretchSpacer(1);
sButtons->Add(m_ConvertToGci, 0, wxEXPAND, 5);
sButtons->AddStretchSpacer(1);
sButtons->Add(m_GciOpenRight, 0, wxEXPAND, 5);
sButtons->Add(m_GciSaveRight, 0, wxEXPAND, 5);
sButtons->AddStretchSpacer(1);
@ -227,22 +233,56 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
memoryCard[0]->Save();
}
break;
case ID_CONVERTTOGCI:
{//Wont compile without brackets?? VC++ Express
wxString temp = wxFileSelector(_T("Select the save file to convert"),
wxEmptyString, wxEmptyString, wxEmptyString,wxString::Format
(
_T("Gamecube save files(*.gcs,*.sav)|*.gcs;*.sav|"
"MadCatz Gameshark files(*.gcs)|*.gcs|"
"Datel MaxDrive/Pro files(*.sav)|*.sav"),
wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
const char * fileName = temp.ToAscii();
wxString temp2 = wxFileSelector(_T("Save GCI as.."),
wxEmptyString, wxEmptyString, _T(".gci"), wxString::Format
(
_T("GCI File(*.gci)|*.gci"),
wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),
wxFD_OVERWRITE_PROMPT|wxFD_SAVE);
const char * fileName2 = temp2.ToAscii();
int len = temp.length();
if(len>0)
{
memoryCard[0]->ImportGci(fileName,len,fileName2);
}
}
break;
case ID_GCIOPENLEFT:
if (memoryCard[0] != NULL)
{
wxString temp = wxFileSelector(_T("Select the GCI file to import"),
wxEmptyString, wxEmptyString, wxEmptyString,wxString::Format
(
_T("GCI File(*.gci)|*.gci|All files (%s)|%s"),
_T("Gamecube save files(*.gci,*.gcs,*.sav)|*.gci;*.gcs;*.sav|"
"Native GCI files (*.gci)|*.gci|"
"MadCatz Gameshark files(*.gcs)|*.gcs|"
"Datel MaxDrive/Pro files(*.sav)|*.sav"),
wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
const char * fileName = temp.ToAscii();
if (temp.length()>0)
int len = temp.length();
if(len>0)
{
memoryCard[0]->AddGci(fileName);
memoryCard[0]->ImportGci(fileName,len,0);
memoryCard[0]->Save();
ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
}
@ -254,16 +294,19 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
wxString temp = wxFileSelector(_T("Select the GCI file to import"),
wxEmptyString, wxEmptyString, wxEmptyString,wxString::Format
(
_T("GCI File(*.gci)|*.gci|All files (%s)|%s"),
_T("Gamecube save files(*.gci,*.gcs,*.sav)|*.gci;*.gcs;*.sav|"
"Native GCI files (*.gci)|*.gci|"
"MadCatz Gameshark files(*.gcs)|*.gcs|"
"Datel MaxDrive/Pro files(*.sav)|*.sav"),
wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
const char * fileName = temp.ToAscii();
if (temp.length()>0)
int len = temp.length();
if(len>0)
{
memoryCard[1]->AddGci(fileName);
memoryCard[1]->ImportGci(fileName,len,0);
memoryCard[1]->Save();
ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
}
@ -283,7 +326,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
const char * fileName = temp.ToAscii();
if (temp.length()>0)
memoryCard[0]->SaveGci(index0, fileName);
memoryCard[0]->ExportGci(index0, fileName);
}
break;
case ID_GCISAVERIGHT:
@ -300,7 +343,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
const char * fileName = temp.ToAscii();
if (temp.length()>0)
memoryCard[1]->SaveGci(index1, fileName);
memoryCard[1]->ExportGci(index1, fileName);
}
break;
case ID_DELETELEFT:

View File

@ -14,7 +14,7 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//updated to 677
#ifndef __MEMCARD_MANAGER_h__
#define __MEMCARD_MANAGER_h__
@ -50,6 +50,7 @@ class CMemcardManager
wxButton *m_GciSaveLeft;
wxButton *m_GciOpenRight;
wxButton *m_GciSaveRight;
wxButton *m_ConvertToGci;
wxButton *m_DeleteLeft;
wxButton *m_DeleteRight;
wxStaticBoxSizer *sMemcard1;
@ -72,6 +73,7 @@ class CMemcardManager
ID_GCISAVELEFT,
ID_GCIOPENRIGHT,
ID_GCIOPENLEFT,
ID_CONVERTTOGCI,
ID_MEMCARD1LIST,
ID_MEMCARD2LIST,
ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values

View File

@ -19,8 +19,8 @@
#include "stdafx.h"
#endif
#include <assert.h>
#include <memory.h>
#include <stdio.h>
#include "wx/ffile.h"
#include "GCMemcard.h"
@ -609,37 +609,139 @@ u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
return ret;
}
u32 GCMemcard::AddGci(const char *fileName)
u32 GCMemcard::ImportGci(const char *fileName, int endFile, const char *fileName2)
{
if(!mcdFile) return 0;
if(!mcdFile && !fileName2) return 0;
FILE *gci=fopen(fileName,"rb");
wxFFile gci(fileName,"rb");
if(!gci.IsOpened())return 0;
if(!gci) return 0;
enum
{
GCI = 0,
SAV = 0x80,
GCS = 0x110
};
int offset;
char * tmp = new char[0xD];
u16 tmpU16;
const char * fileType= (char*)fileName+ endFile-3;
if(!_stricmp(fileType,"gci") && !fileName2)//Extension can be either case
offset = GCI;
else
{
gci.Read(tmp,0xD);
if(!_stricmp(fileType,"gcs"))//Extension can be either case
{
if(!memcmp(tmp,"GCSAVE",6)) //Header must be uppercase
offset = GCS;
else
{
//TODO error message, file has gsc extension but does not have a correct header
return 0;
}
}
else{
if(!_stricmp(fileType,"sav"))//Extension can be either case
{
if(!memcmp(tmp,"DATELGC_SAVE",0xC))//Header must be uppercase
offset = SAV;
else
{
//TODO error message, file has sav extension but does not have a correct header
return 0;
}
}
else
{
//TODO error message, file has invalid extension
return 0;
}
}
}
gci.Seek(offset,wxFromStart);
DEntry *d = new DEntry;
fread(d,1,0x40,gci);
gci.Read(d,0x40);
switch(offset){
case GCS:
//field containing the Block count as displayed within the GameSaves software
//is not stored in the GCS file.
//It is stored only within the corresponding GSV file.
//If the GCS file is added without using the GameSaves software,
//the value stored is always "1"
tmpU16 =(((int)gci.Length()-offset-0x40)/0x2000);
if(tmpU16<0x100){
d->BlockCount[1] = (u8)tmpU16;
}
else{
d->BlockCount[0] = (u8)(tmpU16-0xFF);
d->BlockCount[1] = 0xFF;
}
break;
case SAV:
//swap byte pairs
//0x2C and 0x2D,0x2E and 0x2F,0x30 and 0x31,0x32 and 0x33,0x34 and 0x35,
//0x36 and 0x37,0x38 and 0x39,0x3A and 0x3B,0x3C and 0x3D,0x3E and 0x3F.
SWAP((d->ImageOffset));
SWAP(&(d->ImageOffset[2]));
SWAP((d->IconFmt));
SWAP((d->AnimSpeed));
varSwap(&d->Permissions,&d->CopyCounter);
SWAP((d->FirstBlock));
SWAP((d->BlockCount));
SWAP((d->Unused2));
SWAP((d->CommentsAddr));
SWAP(&(d->CommentsAddr[2]));
break;
default:
break;
}
//TODO verify file length
assert(((int)gci.Length()-offset)== ((BE16(d->BlockCount)* 0x2000) + 0x40));
u32 size=BE16((d->BlockCount))*0x2000;
u8 *t = new u8[size];
fread(t,1,size,gci);
u32 ret = ImportFile(*d,t);
gci.Read(t,size);
gci.Close();
u32 ret = 0;
if(!fileName2)
{
wxFFile gci2(fileName2,"wb");
if(!gci2.IsOpened())return 0;
gci2.Seek(0,wxFromStart);
gci2.Write(d,0x40);
int fileBlocks=BE16(d->BlockCount);
gci2.Seek(0x40,wxFromStart);
gci2.Write(t,0x2000*fileBlocks);
gci2.Close();
}
else ret = ImportFile(*d,t);
delete[] t;
delete[] tmp;
delete d;
return ret;
}
bool GCMemcard::SaveGci(u32 index, const char *fileName)
bool GCMemcard::ExportGci(u32 index, const char *fileName)
{
FILE *gci=fopen(fileName,"wb");
wxFFile gci(fileName,"wb");
if(!gci) return false;
if(!gci.IsOpened())return false;
fseek(gci,0,SEEK_SET);
gci.Seek(0,wxFromStart);
DEntry d;
if(!this->GetFileInfo(index,d)) return false;
fwrite(&d,1,0x40,gci);
gci.Write(&d,0x40);
u8 *t = new u8[this->GetFileSize(index)*0x2000];
@ -647,10 +749,10 @@ bool GCMemcard::SaveGci(u32 index, const char *fileName)
int fileBlocks=BE16(d.BlockCount);
fseek(gci,0x40,SEEK_SET);
fwrite(t,1,0x2000*fileBlocks,gci);
gci.Seek(0x40,wxFromStart);
gci.Write(t,0x2000*fileBlocks);
fclose(gci);
gci.Close();
delete[] t;
return true;
@ -753,3 +855,9 @@ GCMemcard::~GCMemcard()
{
fclose((FILE*)mcdFile);
}
void varSwap(u8 *valueA,u8 *valueB){
u8 temp = *valueA;
*valueA = *valueB;
*valueB = temp;
}

View File

@ -15,12 +15,18 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#pragma once
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#define SWAP(a) (varSwap(a,a+sizeof(u8)));
void varSwap(u8 *valueA,u8 *valueB);
u16 __inline bswap16(u16 s)
{
return (s>>8) | (s<<8);
@ -178,10 +184,10 @@ public:
u32 CopyFrom(GCMemcard& source, u32 index);
// writes a .gci file to disk containing index
bool SaveGci(u32 index, const char* fileName);
bool ExportGci(u32 index, const char* fileName);
// reads a .gci file and calls ImportFile
u32 AddGci(const char* fileName);
// reads a .gci/.gcs/.sav file and calls ImportFile or saves out a gci file
u32 ImportGci(const char* fileName, int endFile,const char* fileName2);
// reads the banner image
bool ReadBannerRGBA8(u32 index, u32* buffer);