Added SRAM save game functionality
This commit is contained in:
@@ -23,6 +23,7 @@ namespace Core.Memory
|
|||||||
|
|
||||||
// A flag to handle cartridges that don't use paging (like early 32KB games)
|
// A flag to handle cartridges that don't use paging (like early 32KB games)
|
||||||
private bool _isCartridgeLoaded = false;
|
private bool _isCartridgeLoaded = false;
|
||||||
|
public bool SramUsed { get; private set; } = false;
|
||||||
|
|
||||||
public void LoadCartridge(byte[] romData)
|
public void LoadCartridge(byte[] romData)
|
||||||
{
|
{
|
||||||
@@ -57,7 +58,7 @@ namespace Core.Memory
|
|||||||
if ((_mapperControl & 0x08) != 0)
|
if ((_mapperControl & 0x08) != 0)
|
||||||
{
|
{
|
||||||
int ramBank = (_mapperControl & 0x04) != 0 ? 1 : 0;
|
int ramBank = (_mapperControl & 0x04) != 0 ? 1 : 0;
|
||||||
int ramOffset = (ramBank * 0x4000) + (address & 0x3FFF);
|
int ramOffset = (ramBank * 0x4000) + (address & 0x1FFF);
|
||||||
return _cartridgeRam[ramOffset];
|
return _cartridgeRam[ramOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,8 +140,9 @@ namespace Core.Memory
|
|||||||
// Bypass the lock if they are trying to save their game!
|
// Bypass the lock if they are trying to save their game!
|
||||||
if (address >= 0x8000 && (_mapperControl & 0x08) != 0)
|
if (address >= 0x8000 && (_mapperControl & 0x08) != 0)
|
||||||
{
|
{
|
||||||
|
SramUsed = true;
|
||||||
int ramBank = (_mapperControl & 0x04) != 0 ? 1 : 0;
|
int ramBank = (_mapperControl & 0x04) != 0 ? 1 : 0;
|
||||||
int ramOffset = (ramBank * 0x4000) + (address & 0x3FFF);
|
int ramOffset = (ramBank * 0x4000) + (address & 0x1FFF);
|
||||||
_cartridgeRam[ramOffset] = value;
|
_cartridgeRam[ramOffset] = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -196,11 +198,37 @@ namespace Core.Memory
|
|||||||
|
|
||||||
return _cartridgeRom[absoluteAddress];
|
return _cartridgeRom[absoluteAddress];
|
||||||
}
|
}
|
||||||
|
public void LoadSaveData(string filePath)
|
||||||
|
{
|
||||||
|
if (System.IO.File.Exists(filePath))
|
||||||
|
{
|
||||||
|
byte[] saveData = System.IO.File.ReadAllBytes(filePath);
|
||||||
|
Array.Copy(saveData, _cartridgeRam, Math.Min(saveData.Length, _cartridgeRam.Length));
|
||||||
|
SramUsed = true; // We loaded a save, so it's active!
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _cartridgeRam.Length; i++)
|
||||||
|
{
|
||||||
|
_cartridgeRam[i] = 0xFF;
|
||||||
|
}
|
||||||
|
SramUsed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveSaveData(string filePath)
|
||||||
|
{
|
||||||
|
// Only write a file to the hard drive if the game actually used the Save RAM!
|
||||||
|
if (SramUsed)
|
||||||
|
{
|
||||||
|
System.IO.File.WriteAllBytes(filePath, _cartridgeRam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void CleanRAMData()
|
public void CleanRAMData()
|
||||||
{
|
{
|
||||||
Array.Clear(_workRam, 0, _workRam.Length);
|
Array.Clear(_workRam, 0, _workRam.Length);
|
||||||
Array.Clear(_cartridgeRam, 0, _cartridgeRam.Length);
|
_mapperControl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,7 @@ namespace Desktop
|
|||||||
public double FrameTime { get; private set; } = 0;
|
public double FrameTime { get; private set; } = 0;
|
||||||
public double FramesPerSecond { get; private set; } = 0;
|
public double FramesPerSecond { get; private set; } = 0;
|
||||||
private string _currentRomName = "No ROM";
|
private string _currentRomName = "No ROM";
|
||||||
|
private string _currentRomPath = "";
|
||||||
private Stopwatch _stopwatch = new System.Diagnostics.Stopwatch();
|
private Stopwatch _stopwatch = new System.Diagnostics.Stopwatch();
|
||||||
public bool IsRunning { get; private set; } = false;
|
public bool IsRunning { get; private set; } = false;
|
||||||
|
|
||||||
@@ -181,7 +182,6 @@ namespace Desktop
|
|||||||
{
|
{
|
||||||
IsRunning = false;
|
IsRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LoadRomAndStart(string filePath)
|
private async void LoadRomAndStart(string filePath)
|
||||||
{
|
{
|
||||||
StopEmulator();
|
StopEmulator();
|
||||||
@@ -190,20 +190,59 @@ namespace Desktop
|
|||||||
await _emulatorTask;
|
await _emulatorTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1. SAVE THE PREVIOUS GAME!
|
||||||
|
SaveCurrentSram();
|
||||||
|
|
||||||
// 2. Load the file
|
// 2. Load the file
|
||||||
byte[] rom = File.ReadAllBytes(filePath);
|
byte[] rom = File.ReadAllBytes(filePath);
|
||||||
|
|
||||||
// 3. Jam it into the Sega Mapper
|
// 3. Jam it into the Sega Mapper
|
||||||
_machine.LoadCartridge(rom);
|
_machine.LoadCartridge(rom);
|
||||||
|
|
||||||
|
// 4. Update the path tracking
|
||||||
|
_currentRomPath = filePath;
|
||||||
_currentRomName = Path.GetFileNameWithoutExtension(filePath);
|
_currentRomName = Path.GetFileNameWithoutExtension(filePath);
|
||||||
this.Text = $"Parsons Master System - {_currentRomName}";
|
this.Text = $"Parsons Master System - {_currentRomName}";
|
||||||
|
|
||||||
// 5. Turn the power on!
|
// 5. LOAD THE NEW SAVE DATA!
|
||||||
|
string savPath = Path.ChangeExtension(_currentRomPath, ".sav");
|
||||||
|
_machine.MemoryBus.LoadSaveData(savPath);
|
||||||
|
|
||||||
|
// 6. Turn the power on!
|
||||||
StartEmulator();
|
StartEmulator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//private async void LoadRomAndStart(string filePath)
|
||||||
|
//{
|
||||||
|
// StopEmulator();
|
||||||
|
// if (_emulatorTask != null)
|
||||||
|
// {
|
||||||
|
// await _emulatorTask;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 2. Load the file
|
||||||
|
// byte[] rom = File.ReadAllBytes(filePath);
|
||||||
|
|
||||||
|
// // 3. Jam it into the Sega Mapper
|
||||||
|
// _machine.LoadCartridge(rom);
|
||||||
|
|
||||||
|
// _currentRomName = Path.GetFileNameWithoutExtension(filePath);
|
||||||
|
// this.Text = $"Parsons Master System - {_currentRomName}";
|
||||||
|
|
||||||
|
// // 5. Turn the power on!
|
||||||
|
|
||||||
|
// StartEmulator();
|
||||||
|
//}
|
||||||
|
private void SaveCurrentSram()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_currentRomPath) && _machine != null)
|
||||||
|
{
|
||||||
|
// Swaps ".sms" for ".sav"
|
||||||
|
string savPath = Path.ChangeExtension(_currentRomPath, ".sav");
|
||||||
|
_machine.MemoryBus.SaveSaveData(savPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void PopulateIncludedRomsMenu()
|
private void PopulateIncludedRomsMenu()
|
||||||
{
|
{
|
||||||
// The folder you used for Golden Axe Warrior
|
// The folder you used for Golden Axe Warrior
|
||||||
@@ -264,7 +303,7 @@ namespace Desktop
|
|||||||
|
|
||||||
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Environment.Exit(0);
|
this.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Form1_KeyDown(object sender, KeyEventArgs e)
|
private void Form1_KeyDown(object sender, KeyEventArgs e)
|
||||||
@@ -308,6 +347,7 @@ namespace Desktop
|
|||||||
private void ParsonsForm1_FormClosing(object sender, FormClosingEventArgs e)
|
private void ParsonsForm1_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
{
|
{
|
||||||
IsRunning = false;
|
IsRunning = false;
|
||||||
|
SaveCurrentSram();
|
||||||
_audioPlayer?.Stop();
|
_audioPlayer?.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
Desktop/ROMS/zexdoc.sav
Normal file
10
Desktop/ROMS/zexdoc.sav
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user