N64: Setup saveram, but it doesn't always work right yet. Sometimes switching games loses the save ram. Sometimes bizhawk crashes when saving saveram.
This commit is contained in:
parent
4001ade4e1
commit
fffc9d676e
|
@ -117,10 +117,24 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64
|
||||||
|
|
||||||
public bool DeterministicEmulation { get; set; }
|
public bool DeterministicEmulation { get; set; }
|
||||||
|
|
||||||
public byte[] ReadSaveRam() { return null; }
|
public byte[] ReadSaveRam()
|
||||||
public void StoreSaveRam(byte[] data) { }
|
{
|
||||||
public void ClearSaveRam() { }
|
byte[] ret = new byte[0x800 + 4 * 0x8000];
|
||||||
public bool SaveRamModified { get; set; }
|
api.SaveSaveram(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreSaveRam(byte[] data)
|
||||||
|
{
|
||||||
|
api.LoadSaveram(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearSaveRam()
|
||||||
|
{
|
||||||
|
api.InitSaveram();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SaveRamModified { get { return true; } set { } }
|
||||||
|
|
||||||
void SyncState(Serializer ser)
|
void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
|
|
|
@ -204,6 +204,29 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64
|
||||||
delegate IntPtr DebugMemGetPointer(m64p_dbg_memptr_type mem_ptr_type);
|
delegate IntPtr DebugMemGetPointer(m64p_dbg_memptr_type mem_ptr_type);
|
||||||
DebugMemGetPointer m64pDebugMemGetPointer;
|
DebugMemGetPointer m64pDebugMemGetPointer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the saveram (eeprom and 4 mempacks)
|
||||||
|
/// </summary>
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate IntPtr init_saveram();
|
||||||
|
init_saveram m64pinit_saveram;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pulls out the saveram for bizhawk to save
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest">A byte array to save the saveram into</param>
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate IntPtr save_saveram(byte[] dest);
|
||||||
|
save_saveram m64psave_saveram;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restores the saveram from bizhawk
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="src">A byte array containing the saveram to restore</param>
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate IntPtr load_saveram(byte[] src);
|
||||||
|
load_saveram m64pload_saveram;
|
||||||
|
|
||||||
// The last parameter of CoreDoCommand is actually a void pointer, so instead we'll make a few delegates for the versions we want to use
|
// The last parameter of CoreDoCommand is actually a void pointer, so instead we'll make a few delegates for the versions we want to use
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
delegate m64p_error CoreDoCommandByteArray(m64p_command Command, int ParamInt, byte[] ParamPtr);
|
delegate m64p_error CoreDoCommandByteArray(m64p_command Command, int ParamInt, byte[] ParamPtr);
|
||||||
|
@ -458,6 +481,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64
|
||||||
// Get the pointer for RDRAM
|
// Get the pointer for RDRAM
|
||||||
rdram = m64pDebugMemGetPointer(m64p_dbg_memptr_type.M64P_DBG_PTR_RDRAM);
|
rdram = m64pDebugMemGetPointer(m64p_dbg_memptr_type.M64P_DBG_PTR_RDRAM);
|
||||||
|
|
||||||
|
InitSaveram();
|
||||||
|
|
||||||
// Start the emulator in another thread
|
// Start the emulator in another thread
|
||||||
m64pEmulator = new Thread(ExecuteEmulator);
|
m64pEmulator = new Thread(ExecuteEmulator);
|
||||||
m64pEmulator.Start();
|
m64pEmulator.Start();
|
||||||
|
@ -502,6 +527,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64
|
||||||
m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm));
|
m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm));
|
||||||
m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm));
|
m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm));
|
||||||
m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer));
|
m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer));
|
||||||
|
m64pinit_saveram = (init_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "init_saveram"), typeof(init_saveram));
|
||||||
|
m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "save_saveram"), typeof(save_saveram));
|
||||||
|
m64pload_saveram = (load_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "load_saveram"), typeof(load_saveram));
|
||||||
|
|
||||||
GfxPluginStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginStartup"), typeof(PluginStartup));
|
GfxPluginStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginStartup"), typeof(PluginStartup));
|
||||||
GfxPluginShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginShutdown"), typeof(PluginShutdown));
|
GfxPluginShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginShutdown"), typeof(PluginShutdown));
|
||||||
|
@ -645,6 +673,21 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64
|
||||||
m64pCoreLoadState(buffer);
|
m64pCoreLoadState(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InitSaveram()
|
||||||
|
{
|
||||||
|
m64pinit_saveram();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveSaveram(byte[] dest)
|
||||||
|
{
|
||||||
|
m64psave_saveram(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadSaveram(byte[] src)
|
||||||
|
{
|
||||||
|
m64pload_saveram(src);
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (!disposed)
|
if (!disposed)
|
||||||
|
|
Binary file not shown.
|
@ -41,18 +41,19 @@
|
||||||
|
|
||||||
static unsigned char eeprom[0x800];
|
static unsigned char eeprom[0x800];
|
||||||
static unsigned char mempack[4][0x8000];
|
static unsigned char mempack[4][0x8000];
|
||||||
|
int saveramModified = 0;
|
||||||
|
|
||||||
static char *get_eeprom_path(void)
|
/*static char *get_eeprom_path(void)
|
||||||
{
|
{
|
||||||
return formatstr("%s%s.eep", get_savesrampath(), ROM_SETTINGS.goodname);
|
return formatstr("%s%s.eep", get_savesrampath(), ROM_SETTINGS.goodname);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void eeprom_format(void)
|
static void eeprom_format(void)
|
||||||
{
|
{
|
||||||
memset(eeprom, 0, sizeof(eeprom));
|
memset(eeprom, 0, sizeof(eeprom));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eeprom_read_file(void)
|
/*static void eeprom_read_file(void)
|
||||||
{
|
{
|
||||||
char *filename = get_eeprom_path();
|
char *filename = get_eeprom_path();
|
||||||
|
|
||||||
|
@ -69,11 +70,11 @@ static void eeprom_read_file(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filename);
|
free(filename);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void eeprom_write_file(void)
|
static void eeprom_write_file(void)
|
||||||
{
|
{
|
||||||
char *filename = get_eeprom_path();
|
/*char *filename = get_eeprom_path();
|
||||||
|
|
||||||
switch (write_to_file(filename, eeprom, sizeof(eeprom)))
|
switch (write_to_file(filename, eeprom, sizeof(eeprom)))
|
||||||
{
|
{
|
||||||
|
@ -86,13 +87,15 @@ static void eeprom_write_file(void)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filename);
|
free(filename);*/
|
||||||
|
|
||||||
|
saveramModified = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_mempack_path(void)
|
/*static char *get_mempack_path(void)
|
||||||
{
|
{
|
||||||
return formatstr("%s%s.mpk", get_savesrampath(), ROM_SETTINGS.goodname);
|
return formatstr("%s%s.mpk", get_savesrampath(), ROM_SETTINGS.goodname);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void mempack_format(void)
|
static void mempack_format(void)
|
||||||
{
|
{
|
||||||
|
@ -128,7 +131,7 @@ static void mempack_format(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mempack_read_file(void)
|
/*static void mempack_read_file(void)
|
||||||
{
|
{
|
||||||
char *filename = get_mempack_path();
|
char *filename = get_mempack_path();
|
||||||
|
|
||||||
|
@ -145,11 +148,11 @@ static void mempack_read_file(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filename);
|
free(filename);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void mempack_write_file(void)
|
static void mempack_write_file(void)
|
||||||
{
|
{
|
||||||
char *filename = get_mempack_path();
|
/*char *filename = get_mempack_path();
|
||||||
|
|
||||||
switch (write_to_file(filename, mempack, sizeof(mempack)))
|
switch (write_to_file(filename, mempack, sizeof(mempack)))
|
||||||
{
|
{
|
||||||
|
@ -162,7 +165,9 @@ static void mempack_write_file(void)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filename);
|
free(filename);*/
|
||||||
|
|
||||||
|
saveramModified = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define DEBUG_PIF
|
//#define DEBUG_PIF
|
||||||
|
@ -216,7 +221,7 @@ static void EepromCommand(unsigned char *Command)
|
||||||
#ifdef DEBUG_PIF
|
#ifdef DEBUG_PIF
|
||||||
DebugMessage(M64MSG_INFO, "EepromCommand() read 8-byte block %i", Command[3]);
|
DebugMessage(M64MSG_INFO, "EepromCommand() read 8-byte block %i", Command[3]);
|
||||||
#endif
|
#endif
|
||||||
eeprom_read_file();
|
//eeprom_read_file();
|
||||||
memcpy(&Command[4], eeprom + Command[3]*8, 8);
|
memcpy(&Command[4], eeprom + Command[3]*8, 8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -225,7 +230,7 @@ static void EepromCommand(unsigned char *Command)
|
||||||
#ifdef DEBUG_PIF
|
#ifdef DEBUG_PIF
|
||||||
DebugMessage(M64MSG_INFO, "EepromCommand() write 8-byte block %i", Command[3]);
|
DebugMessage(M64MSG_INFO, "EepromCommand() write 8-byte block %i", Command[3]);
|
||||||
#endif
|
#endif
|
||||||
eeprom_read_file();
|
//eeprom_read_file();
|
||||||
memcpy(eeprom + Command[3]*8, &Command[4], 8);
|
memcpy(eeprom + Command[3]*8, &Command[4], 8);
|
||||||
eeprom_write_file();
|
eeprom_write_file();
|
||||||
}
|
}
|
||||||
|
@ -397,7 +402,7 @@ static void internal_ControllerCommand(int Control, unsigned char *Command)
|
||||||
address &= 0xFFE0;
|
address &= 0xFFE0;
|
||||||
if (address <= 0x7FE0)
|
if (address <= 0x7FE0)
|
||||||
{
|
{
|
||||||
mempack_read_file();
|
//mempack_read_file();
|
||||||
memcpy(&Command[5], &mempack[Control][address], 0x20);
|
memcpy(&Command[5], &mempack[Control][address], 0x20);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -444,7 +449,7 @@ static void internal_ControllerCommand(int Control, unsigned char *Command)
|
||||||
address &= 0xFFE0;
|
address &= 0xFFE0;
|
||||||
if (address <= 0x7FE0)
|
if (address <= 0x7FE0)
|
||||||
{
|
{
|
||||||
mempack_read_file();
|
//mempack_read_file();
|
||||||
memcpy(&mempack[Control][address], &Command[5], 0x20);
|
memcpy(&mempack[Control][address], &Command[5], 0x20);
|
||||||
mempack_write_file();
|
mempack_write_file();
|
||||||
}
|
}
|
||||||
|
@ -590,3 +595,21 @@ void update_pif_read(void)
|
||||||
input.readController(-1, NULL);
|
input.readController(-1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT void CALL init_saveram(void)
|
||||||
|
{
|
||||||
|
eeprom_format();
|
||||||
|
mempack_format();
|
||||||
|
saveramModified = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT void CALL save_saveram(unsigned char * dest)
|
||||||
|
{
|
||||||
|
memcpy(dest, eeprom, 0x800);
|
||||||
|
memcpy(dest + 0x800, mempack, 4 * 0x8000);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT void CALL load_saveram(unsigned char * src)
|
||||||
|
{
|
||||||
|
memcpy(eeprom, src, 0x800);
|
||||||
|
memcpy(mempack, src + 0x800, 4 * 0x8000);
|
||||||
|
}
|
Loading…
Reference in New Issue