|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: ! 4: Memory Snapshot ! 5: ! 6: This handles the saving/restoring of the emulator's state so any game/application can be saved ! 7: and restored at any time. This is quite complicated as we need to store all STRam, all chip states, ! 8: all emulation variables and then things get really complicated as we need to restore file handles ! 9: and such like. ! 10: To help keep things simple each file has one function which is used to save/restore all variables ! 11: that are local to it. We use one function to reduce redundancy and the function 'MemorySnapShot_Store' ! 12: decides if it should save or restore the data. ! 13: */ ! 14: ! 15: #include "main.h" ! 16: /*#include "compress.h"*/ ! 17: #include "debug.h" ! 18: #include "dialog.h" ! 19: #include "fdc.h" ! 20: #include "file.h" ! 21: #include "floppy.h" ! 22: #include "gemdos.h" ! 23: #include "ikbd.h" ! 24: #include "int.h" ! 25: #include "m68000.h" ! 26: #include "memorySnapShot.h" ! 27: #include "mfp.h" ! 28: #include "psg.h" ! 29: #include "reset.h" ! 30: #include "sound.h" ! 31: #include "tos.h" ! 32: #include "video.h" ! 33: #include "view.h" ! 34: ! 35: //#define COMPRESS_MEMORYSNAPSHOT // Compress snapshots to reduce disc space used ! 36: ! 37: //HFILE CaptureFile; ! 38: //OFSTRUCT CaptureFileInfo; ! 39: BOOL bCaptureSave, bCaptureError; ! 40: BOOL bSaveMemoryState=FALSE, bRestoreMemoryState=FALSE; ! 41: char szSnapShotFileName[MAX_FILENAME_LENGTH]; ! 42: ! 43: //----------------------------------------------------------------------- ! 44: /* ! 45: Check if need to save/restore emulation memory state, via flag 'bSaveMemoryState', and 'bRestoreMemoryState' ! 46: */ ! 47: void MemorySnapShot_CheckSaveRestore(void) ! 48: { ! 49: // Is chose to save memory state, one of these two flags will be set ! 50: /*FIXME*/ ! 51: /* ! 52: if (bSaveMemoryState || bRestoreMemoryState) { ! 53: Main_PauseEmulation(); // Hold things... ! 54: View_ToggleWindowsMouse(MOUSE_WINDOWS); // Put mouse into ST mode ! 55: View_LimitCursorToScreen(); // Free mouse from Window constraints ! 56: ! 57: // Do we need user to enter a filename? ! 58: if (strlen(ConfigureParams.Memory.szMemoryCaptureFileName)<=0) { ! 59: if (!File_OpenSelectDlg(hWnd,ConfigureParams.Memory.szMemoryCaptureFileName,FILEFILTER_MEMORYFILE,FALSE,bSaveMemoryState)) ! 60: bSaveMemoryState = bRestoreMemoryState = FALSE; ! 61: } ! 62: ! 63: // Do save/load ! 64: if (bSaveMemoryState) ! 65: MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName); ! 66: else if (bRestoreMemoryState) ! 67: MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName); ! 68: bSaveMemoryState = bRestoreMemoryState = FALSE; ! 69: ! 70: View_LimitCursorToClient(); // And limit mouse in Window ! 71: View_ToggleWindowsMouse(MOUSE_ST); // Put mouse into ST mode ! 72: Main_UnPauseEmulation(); // And off we go... ! 73: } ! 74: */ ! 75: } ! 76: ! 77: //----------------------------------------------------------------------- ! 78: /* ! 79: Get filename to save/restore to, so can compress ! 80: */ ! 81: char *MemorySnapShot_CompressBegin(char *pszFileName) ! 82: { ! 83: #ifdef COMPRESS_MEMORYSNAPSHOT ! 84: // Create temporary filename ! 85: sprintf(szSnapShotFileName,"%s/%s",szWorkingDir,"snapshot.mem"); ! 86: return(szSnapShotFileName); ! 87: #else //COMPRESS_MEMORYSNAPSHOT ! 88: return(pszFileName); ! 89: #endif //COMPRESS_MEMORYSNAPSHOT ! 90: } ! 91: ! 92: //----------------------------------------------------------------------- ! 93: /* ! 94: Compress memory snap shot ! 95: */ ! 96: void MemorySnapShot_CompressEnd(char *pszFileName) ! 97: { ! 98: #ifdef COMPRESS_MEMORYSNAPSHOT ! 99: // Compress file from temporary to final destination ! 100: Compress_Pack_File(szSnapShotFileName,pszFileName); ! 101: // And delete temporary ! 102: File_Delete(szSnapShotFileName); ! 103: #endif //COMPRESS_MEMORYSNAPSHOT ! 104: } ! 105: ! 106: //----------------------------------------------------------------------- ! 107: /* ! 108: Uncompress memory snap shot to temporary file ! 109: */ ! 110: char *MemorySnapShot_UnCompressBegin(char *pszFileName) ! 111: { ! 112: #ifdef COMPRESS_MEMORYSNAPSHOT ! 113: // Uncompress to temporary file ! 114: sprintf(szSnapShotFileName,"%s/%s",szWorkingDir,"snapshot.mem"); ! 115: Compress_UnPack_File(pszFileName,szSnapShotFileName); ! 116: return(szSnapShotFileName); ! 117: #else //COMPRESS_MEMORYSNAPSHOT ! 118: return(pszFileName); ! 119: #endif //COMPRESS_MEMORYSNAPSHOT ! 120: } ! 121: ! 122: //----------------------------------------------------------------------- ! 123: /* ! 124: Clean up after uncompression ! 125: */ ! 126: void MemorySnapShot_UnCompressEnd(void) ! 127: { ! 128: // And delete temporary ! 129: File_Delete(szSnapShotFileName); ! 130: } ! 131: ! 132: //----------------------------------------------------------------------- ! 133: /* ! 134: Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows how to handle data ! 135: */ ! 136: BOOL MemorySnapShot_OpenFile(char *pszFileName,BOOL bSave) ! 137: { ! 138: char szString[256]; ! 139: char VersionString[VERSION_STRING_SIZE]; ! 140: /* FIXME */ ! 141: /* ! 142: // Set error ! 143: bCaptureError = FALSE; ! 144: ! 145: // Open file, set flag so 'MemorySnapShot_Store' can load to/save from file ! 146: if (bSave) { ! 147: // Save ! 148: CaptureFile = OpenFile(pszFileName,&CaptureFileInfo,OF_CREATE | OF_WRITE); ! 149: if (CaptureFile==HFILE_ERROR) { ! 150: bCaptureError = TRUE; ! 151: return(FALSE); ! 152: } ! 153: bCaptureSave = TRUE; ! 154: // Store version string ! 155: MemorySnapShot_Store(VERSION_STRING,VERSION_STRING_SIZE); ! 156: } ! 157: else { ! 158: // Restore ! 159: CaptureFile = OpenFile(pszFileName,&CaptureFileInfo,OF_READ); ! 160: if (CaptureFile==HFILE_ERROR) { ! 161: bCaptureError = TRUE; ! 162: return(FALSE); ! 163: } ! 164: bCaptureSave = FALSE; ! 165: // Restore version string ! 166: MemorySnapShot_Store(VersionString,VERSION_STRING_SIZE); ! 167: // Does match current version? ! 168: if (stricmp(VersionString,VERSION_STRING)) { ! 169: // No, inform user and error ! 170: sprintf(szString,"Unable to Restore Memory State.\nFile is only compatible with Hatari v%s",VersionString); ! 171: Main_Message(szString,PROG_NAME,MB_OK | MB_ICONSTOP); ! 172: bCaptureError = TRUE; ! 173: return(FALSE); ! 174: } ! 175: } ! 176: ! 177: // All OK ! 178: return(TRUE); ! 179: */ ! 180: return FALSE; ! 181: } ! 182: ! 183: //----------------------------------------------------------------------- ! 184: /* ! 185: Close snapshot file ! 186: */ ! 187: void MemorySnapShot_CloseFile(void) ! 188: { ! 189: //FIXME _lclose(CaptureFile); ! 190: } ! 191: ! 192: //----------------------------------------------------------------------- ! 193: /* ! 194: Save/Restore data to/from file ! 195: */ ! 196: void MemorySnapShot_Store(void *pData, int Size) ! 197: { ! 198: long nBytes; ! 199: /*FIXME*/ ! 200: /* ! 201: // Check no file errors ! 202: if (CaptureFile!=HFILE_ERROR) { ! 203: // Saving or Restoring? ! 204: if (bCaptureSave) ! 205: nBytes = _hwrite(CaptureFile,(char *)pData,Size); ! 206: else ! 207: nBytes = _hread(CaptureFile,(char *)pData,Size); ! 208: ! 209: // Did save OK? ! 210: if (nBytes==HFILE_ERROR) ! 211: bCaptureError = TRUE; ! 212: else if (nBytes!=Size) ! 213: bCaptureError = TRUE; ! 214: } ! 215: */ ! 216: } ! 217: ! 218: //----------------------------------------------------------------------- ! 219: /* ! 220: Save 'snapshot' of memory/chips/emulation variables ! 221: */ ! 222: void MemorySnapShot_Capture(char *pszFileName) ! 223: { ! 224: char *pszSnapShotFileName; ! 225: /*FIXME*/ ! 226: /* ! 227: // Wait... ! 228: SetCursor(Cursors[CURSOR_HOURGLASS]); ! 229: ! 230: // If to be compressed, return temporary filename ! 231: pszSnapShotFileName = MemorySnapShot_CompressBegin(pszFileName); ! 232: ! 233: // Set to 'saving' ! 234: if (MemorySnapShot_OpenFile(pszSnapShotFileName,TRUE)) { ! 235: // Capture each files details ! 236: Main_MemorySnapShot_Capture(TRUE); ! 237: FDC_MemorySnapShot_Capture(TRUE); ! 238: Floppy_MemorySnapShot_Capture(TRUE); ! 239: GemDOS_MemorySnapShot_Capture(TRUE); ! 240: IKBD_MemorySnapShot_Capture(TRUE); ! 241: Int_MemorySnapShot_Capture(TRUE); ! 242: M68000_MemorySnapShot_Capture(TRUE); ! 243: M68000_Decode_MemorySnapShot_Capture(TRUE); ! 244: MFP_MemorySnapShot_Capture(TRUE); ! 245: PSG_MemorySnapShot_Capture(TRUE); ! 246: Sound_MemorySnapShot_Capture(TRUE); ! 247: TOS_MemorySnapShot_Capture(TRUE); ! 248: Video_MemorySnapShot_Capture(TRUE); ! 249: ! 250: // And close ! 251: MemorySnapShot_CloseFile(); ! 252: } ! 253: ! 254: // And compress, if need to ! 255: MemorySnapShot_CompressEnd(pszFileName); ! 256: ! 257: // We're back ! 258: SetCursor(Cursors[CURSOR_ARROW]); ! 259: ! 260: // Did error ! 261: if (bCaptureError) ! 262: Main_Message("Unable to Save Memory State to file.",PROG_NAME,MB_OK | MB_ICONSTOP); ! 263: else ! 264: Main_Message("Memory State file saved.",PROG_NAME,MB_OK | MB_ICONINFORMATION); ! 265: */ ! 266: } ! 267: ! 268: //----------------------------------------------------------------------- ! 269: /* ! 270: Restore 'snapshot' of memory/chips/emulation variables ! 271: */ ! 272: void MemorySnapShot_Restore(char *pszFileName) ! 273: { ! 274: char *pszSnapShotFileName; ! 275: /*FIXME*/ ! 276: /* ! 277: // Wait... ! 278: SetCursor(Cursors[CURSOR_HOURGLASS]); ! 279: ! 280: // If to be uncompressed, return temporary filename ! 281: pszSnapShotFileName = MemorySnapShot_UnCompressBegin(pszFileName); ! 282: ! 283: // Set to 'restore' ! 284: if (MemorySnapShot_OpenFile(pszSnapShotFileName,FALSE)) { ! 285: // Reset emulator to get things running ! 286: Reset_Cold(); ! 287: ! 288: // Capture each files details ! 289: Main_MemorySnapShot_Capture(FALSE); ! 290: FDC_MemorySnapShot_Capture(FALSE); ! 291: Floppy_MemorySnapShot_Capture(FALSE); ! 292: GemDOS_MemorySnapShot_Capture(FALSE); ! 293: IKBD_MemorySnapShot_Capture(FALSE); ! 294: Int_MemorySnapShot_Capture(FALSE); ! 295: M68000_MemorySnapShot_Capture(FALSE); ! 296: M68000_Decode_MemorySnapShot_Capture(FALSE); ! 297: MFP_MemorySnapShot_Capture(FALSE); ! 298: PSG_MemorySnapShot_Capture(FALSE); ! 299: Sound_MemorySnapShot_Capture(FALSE); ! 300: TOS_MemorySnapShot_Capture(FALSE); ! 301: Video_MemorySnapShot_Capture(FALSE); ! 302: ! 303: // And close ! 304: MemorySnapShot_CloseFile(); ! 305: } ! 306: ! 307: // And clean up ! 308: MemorySnapShot_UnCompressEnd(); ! 309: ! 310: // We're back ! 311: SetCursor(Cursors[CURSOR_ARROW]); ! 312: ! 313: // Did error ! 314: if (bCaptureError) ! 315: Main_Message("Unable to Restore Memory State from file.",PROG_NAME,MB_OK | MB_ICONSTOP); ! 316: else ! 317: Main_Message("Memory State file restored.",PROG_NAME,MB_OK | MB_ICONINFORMATION); ! 318: */ ! 319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.