mirror of
https://github.com/coderkei/akmenu-next.git
synced 2025-06-19 01:15:32 -04:00
195 lines
6.5 KiB
C++
195 lines
6.5 KiB
C++
/*
|
|
sram.cpp
|
|
Copyright (C) 2007-2009 somebody
|
|
Copyright (C) 2009 yellow wood goblin
|
|
|
|
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, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
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 for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "sram.h"
|
|
#include <fat.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include "exptools.h"
|
|
#include "language.h"
|
|
#include "progresswnd.h"
|
|
|
|
bool cSram::SaveFileName(const char* romName, char* saveName) {
|
|
saveName[0] = 0;
|
|
if (strlen(romName) > 251) return false;
|
|
strcpy(saveName, romName);
|
|
strcat(saveName, ".sav");
|
|
return true;
|
|
}
|
|
|
|
void cSram::BlankSram(u16 aStartPage) {
|
|
u8* buf = (u8*)malloc(SRAM_PAGE_SIZE);
|
|
if (buf) {
|
|
cExpansion::OpenNorWrite();
|
|
memset(buf, 0, SRAM_PAGE_SIZE);
|
|
for (u32 i = 0; i < SRAM_SAVE_PAGES; i++) {
|
|
expansion().SetRampage(i + aStartPage);
|
|
cExpansion::WriteSram(0x0A000000, buf, SRAM_PAGE_SIZE);
|
|
}
|
|
free(buf);
|
|
}
|
|
cExpansion::CloseNorWrite();
|
|
}
|
|
|
|
void cSram::LoadSramFromFile(const char* romName, u16 aStartPage) {
|
|
char saveName[256];
|
|
if (!SaveFileName(romName, saveName)) return;
|
|
|
|
FILE* saveFile = fopen(saveName, "rb");
|
|
if (saveFile) {
|
|
sSaveInfo saveInfo;
|
|
ProcessRAW(saveFile, saveInfo);
|
|
u8* buf = (u8*)malloc(saveInfo.size);
|
|
if (buf) {
|
|
BlankSram(aStartPage);
|
|
progressWnd().setTipText(LANG("progress window", "gba save load"));
|
|
progressWnd().show();
|
|
progressWnd().setPercent(0);
|
|
memset(buf, 0, saveInfo.size);
|
|
size_t ret = fread(buf, saveInfo.size, 1, saveFile);
|
|
progressWnd().setPercent(10);
|
|
if (ret == 1 && !ferror(saveFile)) {
|
|
int page = saveInfo.offset / SRAM_PAGE_SIZE,
|
|
offset = saveInfo.offset % SRAM_PAGE_SIZE, size = saveInfo.size, bufOffset = 0,
|
|
ii = 0;
|
|
while (page < SRAM_SAVE_PAGES && size > 0) {
|
|
expansion().SetRampage(page + aStartPage);
|
|
int maxSize = SRAM_PAGE_SIZE - offset,
|
|
bufSize = (size > maxSize) ? maxSize : size;
|
|
cExpansion::WriteSram(0x0A000000, buf + bufOffset, bufSize);
|
|
bufOffset += bufSize;
|
|
size -= bufSize;
|
|
offset = 0;
|
|
page++;
|
|
if (ii++ % 4 == 0)
|
|
progressWnd().setPercent(10 + bufOffset * 90 / saveInfo.size);
|
|
}
|
|
}
|
|
progressWnd().setPercent(100);
|
|
progressWnd().hide();
|
|
free(buf);
|
|
}
|
|
fclose(saveFile);
|
|
expansion().SetRampage(0);
|
|
} else {
|
|
BlankSram(aStartPage);
|
|
}
|
|
}
|
|
|
|
void cSram::SaveSramToFile(const char* romName, u16 aStartPage) {
|
|
char saveName[256];
|
|
if (!SaveFileName(romName, saveName)) return;
|
|
sSaveInfo saveInfo;
|
|
FILE* saveFile = fopen(saveName, "rb");
|
|
if (saveFile) {
|
|
fread(&saveInfo, sizeof(saveInfo), 1, saveFile);
|
|
if (saveInfo.marker != SAVE_GBA_HEADER_MAGIC) // raw save
|
|
{
|
|
saveInfo.marker = SAVE_GBA_HEADER_MAGIC;
|
|
saveInfo.offset = 0;
|
|
fseek(saveFile, 0, SEEK_END);
|
|
saveInfo.size = ftell(saveFile);
|
|
saveInfo.header = 0;
|
|
}
|
|
fclose(saveFile);
|
|
saveFile = NULL;
|
|
}
|
|
NormalizeSize(saveInfo);
|
|
saveFile = fopen(saveName, "wb");
|
|
if (saveFile) {
|
|
fwrite(&saveInfo, sizeof(saveInfo), 1, saveFile);
|
|
progressWnd().setTipText(LANG("progress window", "gba save store"));
|
|
progressWnd().show();
|
|
progressWnd().setPercent(0);
|
|
u8* buf = SaveSramToMemory(aStartPage, saveInfo, true);
|
|
if (buf) {
|
|
fwrite(buf, saveInfo.size, 1, saveFile);
|
|
free(buf);
|
|
}
|
|
progressWnd().setPercent(100);
|
|
progressWnd().hide();
|
|
fclose(saveFile);
|
|
}
|
|
}
|
|
|
|
u8* cSram::SaveSramToMemory(u16 aStartPage, sSaveInfo& aSaveInfo, bool aShowProgress) {
|
|
u8* buf = (u8*)malloc(aSaveInfo.size);
|
|
if (buf) {
|
|
cExpansion::OpenNorWrite();
|
|
memset(buf, 0, aSaveInfo.size);
|
|
|
|
int page = aSaveInfo.offset / SRAM_PAGE_SIZE, offset = aSaveInfo.offset % SRAM_PAGE_SIZE,
|
|
size = aSaveInfo.size, bufOffset = 0, ii = 0;
|
|
while (page < SRAM_SAVE_PAGES && size > 0) {
|
|
expansion().SetRampage(page + aStartPage);
|
|
int maxSize = SRAM_PAGE_SIZE - offset, bufSize = (size > maxSize) ? maxSize : size;
|
|
cExpansion::ReadSram(0x0A000000, buf + bufOffset, bufSize);
|
|
bufOffset += bufSize;
|
|
size -= bufSize;
|
|
offset = 0;
|
|
page++;
|
|
if (aShowProgress && ii++ % 4 == 0)
|
|
progressWnd().setPercent(bufOffset * 90 / aSaveInfo.size);
|
|
}
|
|
cExpansion::CloseNorWrite();
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
void cSram::CreateDefaultFile(const char* romName, u32 size) {
|
|
char saveName[256];
|
|
if (!SaveFileName(romName, saveName)) return;
|
|
sSaveInfo saveInfo(size);
|
|
NormalizeSize(saveInfo);
|
|
FILE* saveFile = fopen(saveName, "rb");
|
|
if (saveFile) {
|
|
fclose(saveFile);
|
|
} else {
|
|
FILE* saveFile = fopen(saveName, "wb");
|
|
if (saveFile) {
|
|
fwrite(&saveInfo, sizeof(saveInfo), 1, saveFile);
|
|
fclose(saveFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
void cSram::NormalizeSize(sSaveInfo& anInfo) {
|
|
if ((anInfo.offset + anInfo.size) > SRAM_SAVE_SIZE) {
|
|
if (anInfo.offset <= SRAM_SAVE_SIZE) {
|
|
anInfo.size = SRAM_SAVE_SIZE - anInfo.offset;
|
|
} else {
|
|
anInfo.size = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void cSram::ProcessRAW(FILE* aFile, sSaveInfo& anInfo) {
|
|
fread(&anInfo, sizeof(anInfo), 1, aFile);
|
|
if (anInfo.marker != SAVE_GBA_HEADER_MAGIC) // raw save
|
|
{
|
|
anInfo.marker = SAVE_GBA_HEADER_MAGIC;
|
|
anInfo.offset = 0;
|
|
fseek(aFile, 0, SEEK_END);
|
|
anInfo.size = ftell(aFile);
|
|
fseek(aFile, 0, SEEK_SET);
|
|
anInfo.header = 0;
|
|
}
|
|
NormalizeSize(anInfo);
|
|
}
|