git @ Cat's Eye Technologies linapple / master src / SaveState.cpp
master

Tree @master (Download .tar.gz)

SaveState.cpp @masterraw · history · blame

/*
AppleWin : An Apple //e emulator for Windows

Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski

AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* Description: Save-state (snapshot) module
 *
 * Author: Copyright (c) 2004-2006 Tom Charlesworth
 */

/* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007 */

#include "stdafx.h"
#include "wwrapper.h"

#define DEFAULT_SNAPSHOT_NAME "SaveState.aws"

bool g_bSaveStateOnExit = false;

static char g_szSaveStateFilename[MAX_PATH] = {0};

//-----------------------------------------------------------------------------

char* Snapshot_GetFilename()
{
  return g_szSaveStateFilename;
}

void Snapshot_SetFilename(char* pszFilename)
{
  if(*pszFilename)
    strcpy(g_szSaveStateFilename, (const char *) pszFilename);
  else
    strcpy(g_szSaveStateFilename, DEFAULT_SNAPSHOT_NAME);
}

//-----------------------------------------------------------------------------

void Snapshot_LoadState()
{
  char szMessage[32 + MAX_PATH];

  APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)];

  try
  {
    if(pSS == NULL)
      throw(0);

    memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT));

    //

/*    HANDLE hFile = CreateFile(  g_szSaveStateFilename,
                  GENERIC_READ,
                  0,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);*/
    HANDLE hFile = (FILE*)fopen(g_szSaveStateFilename, "rb");

    if(hFile == INVALID_HANDLE_VALUE)
    {
      strcpy(szMessage, "File not found: ");
      strcpy(szMessage + strlen(szMessage), g_szSaveStateFilename);
      throw(0);
    }

    DWORD dwBytesRead;
    BOOL bRes = ReadFile(  hFile,
                pSS,
                sizeof(APPLEWIN_SNAPSHOT),
                &dwBytesRead,
                NULL);

    CloseHandle(hFile);

    if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT)))
    {
      // File size wrong: probably because of version mismatch or corrupt file
      strcpy(szMessage, "File size mismatch");
      throw(0);
    }

    if(pSS->Hdr.dwTag != (DWORD) AW_SS_TAG)
    {
      strcpy(szMessage, "File corrupt");
      throw(0);
    }

/* Let it be any version, never mind it! ^_^ */
     if(pSS->Hdr.dwVersion != MAKE_VERSION(1,0,0,1))
     {
       strcpy(szMessage, "Version mismatch");
       throw(0);
     }

    // TO DO: Verify checksum

    //
    // Reset all sub-systems
    MemReset();

    if (!IS_APPLE2)
      MemResetPaging();

    DiskReset();
    KeybReset();
    VideoResetState();
    MB_Reset();

    //
    // Apple2 uint
    //

    CpuSetSnapshot(&pSS->Apple2Unit.CPU6502);
    sg_SSC.CommSetSnapshot(&pSS->Apple2Unit.Comms);
    JoySetSnapshot(&pSS->Apple2Unit.Joystick);
    KeybSetSnapshot(&pSS->Apple2Unit.Keyboard);
    SpkrSetSnapshot(&pSS->Apple2Unit.Speaker);
    VideoSetSnapshot(&pSS->Apple2Unit.Video);
    MemSetSnapshot(&pSS->Apple2Unit.Memory);

    //

    //
    // Slot4: Mockingboard
    MB_SetSnapshot(&pSS->Mockingboard1, 4);

    //
    // Slot5: Mockingboard
    MB_SetSnapshot(&pSS->Mockingboard2, 5);

    //
    // Slot6: Disk][
    DiskSetSnapshot(&pSS->Disk2, 6);

    // Hmmm. And SLOT 7 (HDD1 and HDD2)? Where are they??? -- beom beotiger ^_^
  }
  catch(int)
  {
/*    MessageBox(  g_hFrameWindow,
          szMessage,
          TEXT("Load State"),
          MB_ICONEXCLAMATION | MB_SETFOREGROUND);*/
    fprintf(stderr, "%s\n", szMessage); // instead of wndzoooe messagebox let's use powerful stderr
  }

  delete [] pSS;
}

//-----------------------------------------------------------------------------

void Snapshot_SaveState()
{
  APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)];
  if(pSS == NULL)
  {
    // To do
    return;
  }

  memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT));

  pSS->Hdr.dwTag = AW_SS_TAG;
  pSS->Hdr.dwVersion = MAKE_VERSION(1,0,0,1);
//  pSS->Hdr.dwVersion = LINAPPLE_VERSION; //defined in AppleWin.h
  pSS->Hdr.dwChecksum = 0;  // TO DO

  //
  // Apple2 uint
  //

  pSS->Apple2Unit.UnitHdr.dwLength = sizeof(SS_APPLE2_Unit);
  pSS->Apple2Unit.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
//  pSS->Apple2Unit.UnitHdr.dwVersion = LINAPPLE_VERSION;

  CpuGetSnapshot(&pSS->Apple2Unit.CPU6502);
  sg_SSC.CommGetSnapshot(&pSS->Apple2Unit.Comms);
  JoyGetSnapshot(&pSS->Apple2Unit.Joystick);
  KeybGetSnapshot(&pSS->Apple2Unit.Keyboard);
  SpkrGetSnapshot(&pSS->Apple2Unit.Speaker);
  VideoGetSnapshot(&pSS->Apple2Unit.Video);
  MemGetSnapshot(&pSS->Apple2Unit.Memory);

  //
  // Slot1: Empty
  pSS->Empty1.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
  pSS->Empty1.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
  pSS->Empty1.Hdr.dwSlot = 1;
  pSS->Empty1.Hdr.dwType = CT_Empty;

  //
  // Slot2: Empty
  pSS->Empty2.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
  pSS->Empty2.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
  pSS->Empty2.Hdr.dwSlot = 2;
  pSS->Empty2.Hdr.dwType = CT_Empty;

  //
  // Slot3: Empty
  pSS->Empty3.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
  pSS->Empty3.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
  pSS->Empty3.Hdr.dwSlot = 3;
  pSS->Empty3.Hdr.dwType = CT_Empty;

  //
  // Slot4: Mockingboard
  MB_GetSnapshot(&pSS->Mockingboard1, 4);

  //
  // Slot5: Mockingboard
  MB_GetSnapshot(&pSS->Mockingboard2, 5);

  //
  // Slot6: Disk][
  DiskGetSnapshot(&pSS->Disk2, 6);

  //

//   HANDLE hFile = CreateFile(  g_szSaveStateFilename,
//                 GENERIC_WRITE,
//                 0,
//                 NULL,
//                 CREATE_ALWAYS,
//                 FILE_ATTRIBUTE_NORMAL,
//                 NULL);
  HANDLE hFile = fopen(g_szSaveStateFilename, "wb");

//  DWORD dwError = GetLastError();
//  _ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));

  if(hFile != INVALID_HANDLE_VALUE)
  {
    DWORD dwBytesWritten;
    /*BOOL bRes =*/ WriteFile(  hFile,
                pSS,
                sizeof(APPLEWIN_SNAPSHOT),
                &dwBytesWritten,
                NULL);

//    if(!bRes || (dwBytesWritten != sizeof(APPLEWIN_SNAPSHOT)))
//      dwError = GetLastError();

    CloseHandle(hFile);
  }
  else
  {
//    dwError = GetLastError();
    ; //just do nothing
  }

//  _ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));

  delete [] pSS;
}

//-----------------------------------------------------------------------------

void Snapshot_Startup()
{
  static bool bDone = false;

  if(!g_bSaveStateOnExit || bDone)
    return;

  Snapshot_LoadState();

  bDone = true;
}

void Snapshot_Shutdown()
{
  static bool bDone = false;

  if(!g_bSaveStateOnExit || bDone)
    return;

  Snapshot_SaveState();

  bDone = true;
}