mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
Added gci importing/exporting to the memcardmanager (thanks to lpfaint99, see issue 229). Also improved GCMemcard a bit.
I have loaded a raw dump from a real gamecube in dolphin successfully, then used FixChecksums on it (which actually changes some data...), and it continued to act correctly in dolphin. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@841 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -1,5 +1,20 @@
|
||||
// gcmc.cpp: define el punto de entrada de la aplicaci<63>n de consola.
|
||||
//
|
||||
// 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/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "stdafx.h"
|
||||
#endif
|
||||
@ -249,16 +264,20 @@ bool GCMemcard::GetFileData(u32 index, u8*dest) //index in the directory array
|
||||
if(!mcdFile) return false;
|
||||
|
||||
int block = BE16(dir.Dir[index].FirstBlock);
|
||||
int saveLength = BE16(dir.Dir[index].BlockCount);
|
||||
int memcardSize = BE16(hdr.Size) * 0x0010;
|
||||
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;
|
||||
if(block + saveLength != memcardSize)
|
||||
{
|
||||
int nextblock=bswap16(bat.Map[block-5]);
|
||||
assert(nextblock>0);
|
||||
block=nextblock;
|
||||
}else block=0xffff;
|
||||
}
|
||||
while(block!=0xffff);
|
||||
|
||||
@ -540,46 +559,38 @@ u32 GCMemcard::TestChecksums()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ==========================================================================================
|
||||
// Fix checksums - I'll begin with fixing Directory and Directory backup. Feel free to add the
|
||||
// other blocks.
|
||||
// ------------------------------------------------------------------------------------------
|
||||
u32 GCMemcard::FixChecksums()
|
||||
bool GCMemcard::FixChecksums()
|
||||
{
|
||||
if(!mcdFile) return 0xFFFFFFFF;
|
||||
if(!mcdFile) return false;
|
||||
|
||||
u16 csum1=0,csum2=0;
|
||||
|
||||
u32 results = 0;
|
||||
|
||||
calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2);
|
||||
if(BE16(dir.CheckSum1) != csum1) results |= 2;
|
||||
if(BE16(dir.CheckSum2) != csum2) results |= 2;
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Save the values we just read
|
||||
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*)&dir_backup,0xFFE,&csum1,&csum2);
|
||||
if(BE16(dir_backup.CheckSum1) != csum1) results |= 4;
|
||||
if(BE16(dir_backup.CheckSum2) != csum2) results |= 4;
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Save the values we just read
|
||||
dir_backup.CheckSum1[0]=u8(csum1>>8);
|
||||
dir_backup.CheckSum1[1]=u8(csum1);
|
||||
dir_backup.CheckSum2[0]=u8(csum2>>8);
|
||||
dir_backup.CheckSum2[1]=u8(csum2);
|
||||
// ------------------------------------------------------------------------------------------
|
||||
return 0;
|
||||
}
|
||||
// ==========================================================================================
|
||||
|
||||
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);
|
||||
|
||||
calc_checksumsBE((u16*)(((u8*)&bat_backup)+4),0xFFE,&csum1,&csum2);
|
||||
bat_backup.CheckSum1[0]=u8(csum1>>8);
|
||||
bat_backup.CheckSum1[1]=u8(csum1);
|
||||
bat_backup.CheckSum2[0]=u8(csum2>>8);
|
||||
bat_backup.CheckSum2[1]=u8(csum2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
|
||||
{
|
||||
@ -598,6 +609,53 @@ u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 GCMemcard::AddGci(const char *fileName)
|
||||
{
|
||||
if(!mcdFile) return 0;
|
||||
|
||||
FILE *gci=fopen(fileName,"rb");
|
||||
|
||||
if(!gci) return 0;
|
||||
|
||||
DEntry *d = new DEntry;
|
||||
fread(d,1,0x40,gci);
|
||||
|
||||
u32 size=BE16((d->BlockCount))*0x2000;
|
||||
u8 *t = new u8[size];
|
||||
fread(t,1,size,gci);
|
||||
u32 ret = ImportFile(*d,t);
|
||||
delete[] t;
|
||||
delete d;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool GCMemcard::SaveGci(u32 index, const char *fileName)
|
||||
{
|
||||
FILE *gci=fopen(fileName,"wb");
|
||||
|
||||
if(!gci) return false;
|
||||
|
||||
fseek(gci,0,SEEK_SET);
|
||||
|
||||
DEntry d;
|
||||
if(!this->GetFileInfo(index,d)) return false;
|
||||
fwrite(&d,1,0x40,gci);
|
||||
|
||||
u8 *t = new u8[this->GetFileSize(index)*0x2000];
|
||||
|
||||
if(!this->GetFileData(index,t)) return false;
|
||||
|
||||
int fileBlocks=BE16(d.BlockCount);
|
||||
|
||||
fseek(gci,0x40,SEEK_SET);
|
||||
fwrite(t,1,0x2000*fileBlocks,gci);
|
||||
|
||||
fclose(gci);
|
||||
delete[] t;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GCMemcard::Save()
|
||||
{
|
||||
if(!mcdFile) return false;
|
||||
@ -683,6 +741,7 @@ GCMemcard::GCMemcard(const char *filename)
|
||||
|
||||
fseek(mcd,0xa000,SEEK_SET);
|
||||
|
||||
assert(BE16(hdr.Size)!=0xFFFF);
|
||||
mc_data_size=(((u32)BE16(hdr.Size)*16)-5)*0x2000;
|
||||
mc_data = new u8[mc_data_size];
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
// 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/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char u8;
|
||||
@ -128,8 +145,8 @@ public:
|
||||
bool IsOpen();
|
||||
|
||||
u32 TestChecksums();
|
||||
u32 FixChecksums();
|
||||
|
||||
bool FixChecksums();
|
||||
|
||||
// get number of file entries in the directory
|
||||
u32 GetNumFiles();
|
||||
|
||||
@ -160,6 +177,12 @@ public:
|
||||
// reads a save from another memcard, and imports the data into this memcard
|
||||
u32 CopyFrom(GCMemcard& source, u32 index);
|
||||
|
||||
// writes a .gci file to disk containing index
|
||||
bool SaveGci(u32 index, const char* fileName);
|
||||
|
||||
// reads a .gci file and calls ImportFile
|
||||
u32 AddGci(const char* fileName);
|
||||
|
||||
// reads the banner image
|
||||
bool ReadBannerRGBA8(u32 index, u32* buffer);
|
||||
|
||||
|
Reference in New Issue
Block a user