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:
pjgat09 2013-05-07 22:37:26 +00:00
parent 4001ade4e1
commit fffc9d676e
4 changed files with 100 additions and 20 deletions

View File

@ -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)
{ {

View File

@ -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)

View File

@ -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);
}