From a054383c7fc7893b676fd94b3bcfb0ce7b1efc47 Mon Sep 17 00:00:00 2001
From: squall-leonhart <squall-leonhart@a31d4220-a93d-0410-bf67-fe4944624d44>
Date: Sun, 24 Oct 2010 15:53:08 +0000
Subject: [PATCH] another patch, this time for GSV snapshots.

git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@962 a31d4220-a93d-0410-bf67-fe4944624d44
---
 src/gba/Flash.cpp         |  2 +-
 src/gba/Flash.h           |  4 ++-
 src/gba/GBA.cpp           | 56 +++++++++++++++++++++++++++++++++++++++
 src/gba/GBA.h             |  1 +
 src/win32/Commands.cpp    |  2 +-
 src/win32/FileDlg.cpp     |  2 ++
 src/win32/MainWndFile.cpp | 10 ++++---
 src/win32/VBA.rc          |  3 ++-
 src/win32/resource.h      |  1 +
 9 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/src/gba/Flash.cpp b/src/gba/Flash.cpp
index 50c443e3..b689bb48 100644
--- a/src/gba/Flash.cpp
+++ b/src/gba/Flash.cpp
@@ -17,7 +17,7 @@
 #define FLASH_PROGRAM            8
 #define FLASH_SETBANK            9
 
-u8 flashSaveMemory[0x20000];
+u8 flashSaveMemory[FLASH_128K_SZ];
 int flashState = FLASH_READ_ARRAY;
 int flashReadState = FLASH_READ_ARRAY;
 int flashSize = 0x10000;
diff --git a/src/gba/Flash.h b/src/gba/Flash.h
index 51f801aa..cd23a5c6 100644
--- a/src/gba/Flash.h
+++ b/src/gba/Flash.h
@@ -1,13 +1,15 @@
 #ifndef FLASH_H
 #define FLASH_H
 
+#define FLASH_128K_SZ 0x20000
+
 extern void flashSaveGame(gzFile _gzFile);
 extern void flashReadGame(gzFile _gzFile, int version);
 extern void flashReadGameSkip(gzFile _gzFile, int version);
 extern u8 flashRead(u32 address);
 extern void flashWrite(u32 address, u8 byte);
 extern void flashDelayedWrite(u32 address, u8 byte);
-extern u8 flashSaveMemory[0x20000];
+extern u8 flashSaveMemory[FLASH_128K_SZ];
 extern void flashSaveDecide(u32 address, u8 byte);
 extern void flashReset();
 extern void flashSetSize(int size);
diff --git a/src/gba/GBA.cpp b/src/gba/GBA.cpp
index 9b13d628..b4512b23 100644
--- a/src/gba/GBA.cpp
+++ b/src/gba/GBA.cpp
@@ -983,6 +983,62 @@ bool CPUReadGSASnapshot(const char *fileName)
   return true;
 }
 
+bool CPUReadGSASPSnapshot(const char *fileName)
+{
+  const char gsvfooter[] = "xV4\x12";
+  const size_t namepos=0x0c, namesz=12;
+  const size_t footerpos=0x42c, footersz=4;
+
+  char footer[footersz+1], romname[namesz+1], savename[namesz+1];;
+  FILE *file = fopen(fileName, "rb");
+
+  if(!file) {
+    systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
+    return false;
+  }
+
+  // read save name
+  fseek(file, namepos, SEEK_SET);
+  fread(savename, 1, namesz, file);
+  savename[namesz] = 0;
+
+  memcpy(romname, &rom[0xa0], namesz);
+  romname[namesz] = 0;
+
+  if(memcmp(romname, savename, namesz)) {
+    systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
+                  N_("Cannot import snapshot for %s. Current game is %s"),
+                  savename,
+                  romname);
+    fclose(file);
+    return false;
+  }
+
+  // read footer tag
+  fseek(file, footerpos, SEEK_SET);
+  fread(footer, 1, footersz, file);
+  footer[footersz] = 0;
+
+  if(memcmp(footer, gsvfooter, footersz)) {
+    systemMessage(0,
+                  N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"),
+                  fileName,
+				  footer,
+                  footerpos,
+				  gsvfooter);
+    fclose(file);
+    return false;
+  }
+
+  // Read up to 128k save
+  fread(flashSaveMemory, 1, FLASH_128K_SZ, file);
+
+  fclose(file);
+  CPUReset();
+  return true;
+}
+
+
 bool CPUWriteGSASnapshot(const char *fileName,
                          const char *title,
                          const char *desc,
diff --git a/src/gba/GBA.h b/src/gba/GBA.h
index f66adb6c..ec104ad3 100644
--- a/src/gba/GBA.h
+++ b/src/gba/GBA.h
@@ -78,6 +78,7 @@ extern char oldbuffer[10];
 #endif
 
 extern bool CPUReadGSASnapshot(const char *);
+extern bool CPUReadGSASPSnapshot(const char *);
 extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
 extern bool CPUWriteBatteryFile(const char *);
 extern bool CPUReadBatteryFile(const char *);
diff --git a/src/win32/Commands.cpp b/src/win32/Commands.cpp
index 362dfcd4..454d5b1a 100644
--- a/src/win32/Commands.cpp
+++ b/src/win32/Commands.cpp
@@ -59,7 +59,7 @@ struct {
   { "FileReset", ID_FILE_RESET },
   { "FileImportBatteryFile", ID_FILE_IMPORT_BATTERYFILE },
   { "FileImportGamesharkCodeFile", ID_FILE_IMPORT_GAMESHARKCODEFILE },
-  { "FileImportGamesharkSnapshot", ID_FILE_IMPORT_GAMESHARKSNAPSHOT },
+  { "FileImportGamesharkActionReplaySnapshot", ID_FILE_IMPORT_GAMESHARKSNAPSHOT },
   { "FileExportBatteryFile", ID_FILE_EXPORT_BATTERYFILE },
   { "FileExportGamesharkSnapshot", ID_FILE_EXPORT_GAMESHARKSNAPSHOT },
   { "FileScreenCapture", ID_FILE_SCREENCAPTURE },
diff --git a/src/win32/FileDlg.cpp b/src/win32/FileDlg.cpp
index a6e1f039..bde34659 100644
--- a/src/win32/FileDlg.cpp
+++ b/src/win32/FileDlg.cpp
@@ -92,6 +92,8 @@ FileDlg::FileDlg(CWnd *parent, LPCTSTR file, LPCTSTR filter,
   m_ofn.lpfnHook = HookFunc;
   m_ofn.Flags = OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_ENABLEHOOK;
   m_ofn.Flags |= OFN_EXPLORER;
+  if (!save)
+	m_ofn.Flags |= OFN_READONLY;
   m_filter = filter;
 
   char *p = m_filter.GetBuffer(0);
diff --git a/src/win32/MainWndFile.cpp b/src/win32/MainWndFile.cpp
index dccc4fef..7ff97e5f 100644
--- a/src/win32/MainWndFile.cpp
+++ b/src/win32/MainWndFile.cpp
@@ -448,8 +448,8 @@ void MainWnd::OnUpdateFileImportGamesharkcodefile(CCmdUI* pCmdUI)
 
 void MainWnd::OnFileImportGamesharksnapshot()
 {
-  LPCTSTR exts[] = { ".gbs" };
-  CString filter = theApp.cartridgeType == 1 ? winLoadFilter(IDS_FILTER_GBS) : winLoadFilter(IDS_FILTER_SPS);
+  LPCTSTR exts[] = { ".?ps", ".gsv" };
+  CString filter = theApp.cartridgeType == 1 ? winLoadFilter(IDS_FILTER_GBS) : winLoadFilter(IDS_FILTER_GSVSPS);
   CString title = winResLoadString(IDS_SELECT_SNAPSHOT_FILE);
 
   FileDlg dlg(this, "", filter, 0, "", exts, "", title, false);
@@ -465,8 +465,12 @@ void MainWnd::OnFileImportGamesharksnapshot()
                 MB_OKCANCEL) == IDCANCEL)
     return;
 
-  if(theApp.cartridgeType == 1)
+  if(theApp.cartridgeType == IMAGE_GB && dlg.getFilterIndex() == 1)
     gbReadGSASnapshot(dlg.GetPathName());
+  else if(theApp.cartridgeType == IMAGE_GB && dlg.getFilterIndex() == 2) {
+	/* gameboy .gsv saves? */ }
+  else if(theApp.cartridgeType == IMAGE_GBA && dlg.getFilterIndex() == 2)
+	CPUReadGSASPSnapshot(dlg.GetPathName());
   else
     CPUReadGSASnapshot(dlg.GetPathName());
 }
diff --git a/src/win32/VBA.rc b/src/win32/VBA.rc
index 835ac5f7..e6738f57 100644
--- a/src/win32/VBA.rc
+++ b/src/win32/VBA.rc
@@ -2225,7 +2225,8 @@ BEGIN
     IDS_LOADED_CHEATS       "Loaded cheats"
     IDS_ERROR_DISP_COLOR    "Unsupported display setting for color depth: %d bits. \nWindows desktop must be in either 16-bit, 24-bit or 32-bit mode for this program to work in window mode."
     IDS_ADD_GSA_CODE        "Add GameSharkAdvance code"
-    IDS_FILTER_SPS          "GS & PAC Snapshots (*.SPS;*.XPS)_*.SPS;*.XPS__"
+    IDS_FILTER_GSVSPS       "GS & PAC Snapshots (*.SPS;*.XPS)_*.SPS;*.XPS_GameShark SP Snapshots (*.GSV)_*.gsv__"
+    IDS_FILTER_SPS          "Gameshark Snapshot_*.SPS__"
     IDS_SELECT_SNAPSHOT_FILE "Select snapshot file"
     IDS_FILTER_SAV          "Battery file_*.SAV_Flash save_*.DAT__"
     IDS_SELECT_BATTERY_FILE "Select battery file"
diff --git a/src/win32/resource.h b/src/win32/resource.h
index a28b83dd..627ca9e4 100644
--- a/src/win32/resource.h
+++ b/src/win32/resource.h
@@ -392,6 +392,7 @@
 #define IDC_SAVE_OBJ                    1138
 #define IDC_MAP_VIEW_ZOOM               1138
 #define IDS_MOVIE_PLAY                  1138
+#define IDS_FILTER_GSVSPS               1139
 #define IDC_VIEWER                      1140
 #define IDC_CHANGE_BACKDROP             1140
 #define IDC_ADDRESSES                   1141