/**************************************************************************** * * * Project64 - A Nintendo 64 emulator. * * http://www.pj64-emu.com/ * * Copyright (C) 2012 Project64. All rights reserved. * * * * License: * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ #include "stdafx.h" #include #include CSram::CSram(bool ReadOnly) : m_ReadOnly(ReadOnly) { } CSram::~CSram() { } bool CSram::LoadSram() { CPath FileName(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.sra", g_Settings->LoadStringVal(Game_GameName).c_str()).c_str()); if (g_Settings->LoadBool(Setting_UniqueSaveDir)) { FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); } #ifdef _WIN32 FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY)); #endif if (!FileName.DirectoryExists()) { FileName.DirectoryCreate(); } if (!m_File.Open(FileName, (m_ReadOnly ? CFileBase::modeRead : CFileBase::modeReadWrite) | CFileBase::modeNoTruncate | CFileBase::modeCreate)) { WriteTrace(TraceN64System, TraceError, "Failed to open (%s), ReadOnly = %d", (const char *)FileName, m_ReadOnly); return false; } m_File.SeekToBegin(); return true; } void CSram::DmaFromSram(uint8_t * dest, int32_t StartOffset, int32_t len) { uint32_t i; if (!m_File.IsOpen()) { if (!LoadSram()) { return; } } // Fix Dezaemon 3D saves StartOffset = ((StartOffset >> 3) & 0xFFFF8000) | (StartOffset & 0x7FFF); if (((StartOffset & 3) == 0) && ((((uint32_t)dest) & 3) == 0)) { m_File.Seek(StartOffset, CFile::begin); m_File.Read(dest, len); } else { for (i = 0; i < len; i++) { m_File.Seek((StartOffset + i) ^ 3, CFile::begin); m_File.Read((uint8_t*)(((uint32_t)dest + i) ^ 3), 1); } } } void CSram::DmaToSram(uint8_t * Source, int32_t StartOffset, int32_t len) { uint32_t i; if (m_ReadOnly) { return; } if (!m_File.IsOpen()) { if (!LoadSram()) { return; } } // Fix Dezaemon 3D saves StartOffset = ((StartOffset >> 3) & 0xFFFF8000) | (StartOffset & 0x7FFF); if (((StartOffset & 3) == 0) && ((((uint32_t)Source) & 3) == 0) && NULL != NULL) { m_File.Seek(StartOffset, CFile::begin); m_File.Write(Source, len); } else { for (i = 0; i < len; i++) { m_File.Seek((StartOffset + i) ^ 3, CFile::begin); m_File.Write((uint8_t*)(((uint32_t)Source + i) ^ 3), 1); } } }