]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Full relative/absolute path statefile support.
authorToni Wilen <twilen@winuae.net>
Sat, 14 Jul 2018 18:24:19 +0000 (21:24 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 14 Jul 2018 18:24:19 +0000 (21:24 +0300)
blkdev.cpp
disk.cpp
filesys.cpp
include/savestate.h
include/uae.h
od-win32/win32.cpp
savestate.cpp

index d76c7a0f975d32d56f281698232e2a484e8fbb5d..8c50999bb47dd7decb5a5c37244d10515d6b6ff1 100644 (file)
@@ -2329,8 +2329,8 @@ uae_u8 *save_cd (int num, int *len)
                return NULL;
        if (!currprefs.cs_cd32cd && !currprefs.cs_cdtvcd && !currprefs.scsi)
                return NULL;
-       dstbak = dst = xmalloc (uae_u8, 4 + 256 + 4 + 4);
-       save_u32 (4 | 8);
+       dstbak = dst = xmalloc (uae_u8, 4 + MAX_DPATH + 4 + 4 + 4 + 2 * MAX_DPATH);
+       save_u32 (4 | 8 | 16);
        save_path (currprefs.cdslots[num].name, SAVESTATE_PATH_CD);
        save_u32 (currprefs.cdslots[num].type);
        save_u32 (0);
@@ -2339,6 +2339,7 @@ uae_u8 *save_cd (int num, int *len)
        for (int i = 0; i < SUBQ_SIZE; i++)
                save_u8 (st->play_qcode[i]);
        save_u32 (st->play_end_pos);
+       save_path_full(currprefs.cdslots[num].name, SAVESTATE_PATH_CD);
        *len = dst - dstbak;
        return dstbak;
 }
@@ -2355,20 +2356,25 @@ uae_u8 *restore_cd (int num, uae_u8 *src)
        s = restore_path (SAVESTATE_PATH_CD);
        int type = restore_u32 ();
        restore_u32 ();
-       if (flags & 4) {
-               if (currprefs.cdslots[num].name[0] == 0 || zfile_exists (s)) {
-                       _tcscpy (changed_prefs.cdslots[num].name, s);
-                       _tcscpy (currprefs.cdslots[num].name, s);
-               }
-               changed_prefs.cdslots[num].type = currprefs.cdslots[num].type = type;
-               changed_prefs.cdslots[num].temporary = currprefs.cdslots[num].temporary = true;
-       }
        if (flags & 8) {
                restore_u32 ();
                for (int i = 0; i < SUBQ_SIZE; i++)
                        st->play_qcode[i] = restore_u8 ();
                st->play_end_pos = restore_u32 ();
        }
+       if (flags & 16) {
+               xfree(s);
+               s = restore_path_full();
+       }
+       if (flags & 4) {
+               if (currprefs.cdslots[num].name[0] == 0 || zfile_exists(s)) {
+                       _tcscpy(changed_prefs.cdslots[num].name, s);
+                       _tcscpy(currprefs.cdslots[num].name, s);
+               }
+               changed_prefs.cdslots[num].type = currprefs.cdslots[num].type = type;
+               changed_prefs.cdslots[num].temporary = currprefs.cdslots[num].temporary = true;
+       }
+       xfree(s);
        return src;
 }
 
index 8a2373f03c7c6796dbd7fb340a6916d9b6797030..9b7c942bcf0fbc6c29939c4affe8320df9e3ac87 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -4498,13 +4498,18 @@ uae_u8 *restore_disk (int num,uae_u8 *src)
        drv->dskchange_time = 0;
        restore_u32 ();
        s = restore_path (SAVESTATE_PATH_FLOPPY);
-       if (s && s[0])
-               write_log (_T("-> '%s'\n"), s);
-       _tcscpy (old, currprefs.floppyslots[num].df);
-       _tcsncpy (changed_prefs.floppyslots[num].df, s, 255);
-       xfree(s);
        int dskready_up_time = restore_u16 ();
        int dskready_down_time = restore_u16 ();
+       if (restore_u32() & 1) {
+               xfree(s);
+               s = restore_path_full();
+       }
+       if (s && s[0])
+               write_log(_T("-> '%s'\n"), s);
+       _tcscpy(old, currprefs.floppyslots[num].df);
+       _tcsncpy(changed_prefs.floppyslots[num].df, s, 255);
+       xfree(s);
+
        newis = changed_prefs.floppyslots[num].df[0] ? 1 : 0;
        if (!(disabled & (1 << num))) {
                if (!newis && old[0]) {
@@ -4521,6 +4526,7 @@ uae_u8 *restore_disk (int num,uae_u8 *src)
                                } else {
                                        drv->dskchange_time = -1;
                                        _tcscpy(drv->newname, changed_prefs.floppyslots[num].df);
+                                       _tcscpy(currprefs.floppyslots[num].df, drv->newname);
                                        write_log(_T("Disk image not found, faking inserted disk.\n"));
                                }
                        }
@@ -4564,7 +4570,7 @@ uae_u8 *save_disk (int num, int *len, uae_u8 *dstptr, bool usepath)
        if (dstptr)
                dstbak = dst = dstptr;
        else
-               dstbak = dst = xmalloc (uae_u8, 2 + 1 + 1 + 1 + 1 + 4 + 4 + 256);
+               dstbak = dst = xmalloc (uae_u8, 2 + 1 + 1 + 1 + 1 + 4 + 4 + MAX_DPATH + 2 + 2 + 4 + 2 * MAX_DPATH);
        save_u32 (drv->drive_id);           /* drive type ID */
        save_u8 ((drv->motoroff ? 0 : 1) | ((disabled & (1 << num)) ? 2 : 0) | (drv->idbit ? 4 : 0) | (drv->dskchange ? 8 : 0) | (side ? 16 : 0) | (drv->wrprot ? 32 : 0));
        save_u8 (drv->cyl);                             /* cylinder */
@@ -4575,6 +4581,11 @@ uae_u8 *save_disk (int num, int *len, uae_u8 *dstptr, bool usepath)
        save_path (usepath ? currprefs.floppyslots[num].df : _T(""), SAVESTATE_PATH_FLOPPY);/* image name */
        save_u16 (drv->dskready_up_time);
        save_u16 (drv->dskready_down_time);
+       if (usepath) {
+               save_u32(1);
+               save_path_full(currprefs.floppyslots[num].df, SAVESTATE_PATH_FLOPPY);
+       }
+
        *len = dst - dstbak;
        return dstbak;
 }
index 3edd22a2788ed1649efb7a7ddd734458a627ffd0..dd23cd05ffd9037f28f3987cfe9cfe86f6cfb7a8 100644 (file)
@@ -9798,6 +9798,9 @@ static uae_u8 *save_filesys_virtual (UnitInfo *ui, uae_u8 *dst)
        return dst;
 }
 
+
+static TCHAR *new_filesys_root_path, *new_filesys_fs_path;
+
 uae_u8 *save_filesys_common (int *len)
 {
        uae_u8 *dstbak, *dst;
@@ -9821,14 +9824,51 @@ uae_u8 *restore_filesys_common (uae_u8 *src)
        filesys_reset2 ();
        a_uniq = restore_u64 ();
        key_uniq = restore_u64 ();
+
+       xfree(new_filesys_root_path);
+       xfree(new_filesys_fs_path);
+       new_filesys_root_path = NULL;
+       new_filesys_fs_path = NULL;
        return src;
 }
 
+uae_u8 *save_filesys_paths(int num, int *len)
+{
+       uae_u8 *dstbak, *dst;
+       UnitInfo *ui;
+       int type = is_hardfile(num);
+       int ptype;
+
+       ui = &mountinfo.ui[num];
+       if (ui->open <= 0)
+               return NULL;
+       dstbak = dst = xmalloc(uae_u8, 4 + 4 + 2 + 2 * 2 * MAX_DPATH);
+
+       if (type == FILESYS_VIRTUAL || type == FILESYS_CD)
+               ptype = SAVESTATE_PATH_VDIR;
+       else if (type == FILESYS_HARDFILE || type == FILESYS_HARDFILE_RDB)
+               ptype = SAVESTATE_PATH_HDF;
+       else if (type == FILESYS_HARDDRIVE)
+               ptype = SAVESTATE_PATH_HD;
+       else
+               ptype = SAVESTATE_PATH;
+
+       save_u32(0);
+       save_u32(ui->devno);
+       save_u16(type);
+       save_path_full(ui->rootdir, ptype);
+       save_path_full(ui->filesysdir, SAVESTATE_PATH);
+
+       *len = dst - dstbak;
+       return dstbak;
+}
+
 uae_u8 *save_filesys (int num, int *len)
 {
        uae_u8 *dstbak, *dst;
        UnitInfo *ui;
        int type = is_hardfile (num);
+       int ptype;
 
        ui = &mountinfo.ui[num];
        if (ui->open <= 0)
@@ -9842,13 +9882,14 @@ uae_u8 *save_filesys (int num, int *len)
        save_u32 (ui->devno);
        save_u16 (type);
        if (type == FILESYS_VIRTUAL || type == FILESYS_CD)
-               save_path (ui->rootdir, SAVESTATE_PATH_VDIR);
+               ptype = SAVESTATE_PATH_VDIR;
        else if (type == FILESYS_HARDFILE || type == FILESYS_HARDFILE_RDB)
-               save_path (ui->rootdir, SAVESTATE_PATH_HDF);
+               ptype = SAVESTATE_PATH_HDF;
        else if (type == FILESYS_HARDDRIVE)
-               save_path (ui->rootdir, SAVESTATE_PATH_HD);
+               ptype = SAVESTATE_PATH_HD;
        else
-               save_path (ui->rootdir, SAVESTATE_PATH);
+               ptype = SAVESTATE_PATH;
+       save_path(ui->rootdir, ptype);
        save_string (ui->devname);
        save_string (ui->volname);
        save_path (ui->filesysdir, SAVESTATE_PATH);
@@ -9864,6 +9905,16 @@ uae_u8 *save_filesys (int num, int *len)
        return dstbak;
 }
 
+uae_u8 *restore_filesys_paths(uae_u8 *src)
+{
+       restore_u32();
+       restore_u32();
+       restore_u16();
+       new_filesys_root_path = restore_path_full();
+       new_filesys_fs_path = restore_path_full();
+       return src;
+}
+
 uae_u8 *restore_filesys (uae_u8 *src)
 {
        int type, devno;
@@ -9872,8 +9923,8 @@ uae_u8 *restore_filesys (uae_u8 *src)
        uae_u32 startup;
        struct uaedev_config_info *ci;
 
-       if (restore_u32 () != 2)
-               return src;
+       if (restore_u32() != 2)
+               goto end2;
        devno = restore_u32 ();
        ui = &mountinfo.ui[devno];
        ci = &ui->hf.ci;
@@ -9900,6 +9951,18 @@ uae_u8 *restore_filesys (uae_u8 *src)
        ci->readonly = restore_u8 () != 0;
        startup = restore_u32 ();
        filesys_configdev = restore_u32 ();
+
+       if (new_filesys_root_path) {
+               xfree(rootdir);
+               rootdir = new_filesys_root_path;
+               new_filesys_root_path = NULL;
+       }
+       if (new_filesys_fs_path) {
+               xfree(filesysdir);
+               filesysdir = new_filesys_fs_path;
+               new_filesys_fs_path = NULL;
+       }
+
        if (type == FILESYS_HARDFILE || type == FILESYS_HARDFILE_RDB) {
                src = restore_filesys_hardfile (ui, src);
                xfree (volname);
@@ -9911,19 +9974,25 @@ uae_u8 *restore_filesys (uae_u8 *src)
        _tcscpy (ci->filesys, filesysdir);
 
        if (set_filesys_unit (devno, ci, false) < 0) {
-                       write_log (_T("filesys '%s' failed to restore\n"), rootdir);
-                       goto end;
+               write_log (_T("filesys '%s' failed to restore\n"), rootdir);
+               goto end;
        }
        ui->devno = devno;
        ui->startup = startup;
        if (type == FILESYS_VIRTUAL || type == FILESYS_CD)
                src = restore_filesys_virtual (ui, src, devno);
+
        write_log (_T("'%s' restored\n"), rootdir);
 end:
        xfree (rootdir);
        xfree (devname);
        xfree (volname);
        xfree (filesysdir);
+end2:
+       xfree(new_filesys_root_path);
+       xfree(new_filesys_fs_path);
+       new_filesys_root_path = NULL;
+       new_filesys_fs_path = NULL;
        return src;
 }
 
index d06085fb34c9163cc849b7d72fcee89abacd5089..12081ad7edb5a36a886536d7f79ee4ed13372b1c 100644 (file)
@@ -45,7 +45,9 @@ extern TCHAR *restore_string_func (uae_u8 **);
 #define SAVESTATE_PATH_CD 5
 
 extern void save_path_func (uae_u8 **, const TCHAR*, int type);
-extern TCHAR *restore_path_func (uae_u8 **, int type);
+extern void save_path_full_func(uae_u8 **, const TCHAR*, int type);
+extern TCHAR *restore_path_func(uae_u8 **, int type);
+extern TCHAR *restore_path_full_func(uae_u8 **);
 
 #define save_u64(x) save_u64_func (&dst, (x))
 #define save_u32(x) save_u32_func (&dst, (x))
@@ -61,7 +63,9 @@ extern TCHAR *restore_path_func (uae_u8 **, int type);
 #define restore_string() restore_string_func (&src)
 
 #define save_path(x, p) save_path_func (&dst, (x), p)
+#define save_path_full(x, p) save_path_full_func (&dst, (x), p)
 #define restore_path(p) restore_path_func (&src, p)
+#define restore_path_full() restore_path_full_func (&src)
 
 
 /* save, restore and initialize routines for Amiga's subsystems */
@@ -152,6 +156,8 @@ extern uae_u8 *restore_filesys (uae_u8 *src);
 extern uae_u8 *save_filesys (int num, int *len);
 extern uae_u8 *restore_filesys_common (uae_u8 *src);
 extern uae_u8 *save_filesys_common (int *len);
+extern uae_u8 *restore_filesys_paths(uae_u8 *src);
+extern uae_u8 *save_filesys_paths(int num, int *len);
 extern int save_filesys_cando(void);
 
 extern uae_u8 *restore_gayle(uae_u8 *src);
index 6ea146c41ec0c5e707fe130832b95ed697e951d7..9fa23022d6521ffe791facc2003d069335dad7c8 100644 (file)
@@ -41,9 +41,11 @@ extern int target_sleep_nanos(int);
 extern bool get_plugin_path (TCHAR *out, int size, const TCHAR *path);
 extern void stripslashes (TCHAR *p);
 extern void fixtrailing (TCHAR *p);
-extern void fullpath (TCHAR *path, int size);
+extern void fullpath(TCHAR *path, int size);
+extern void fullpath(TCHAR *path, int size, bool userelative);
 extern void getpathpart (TCHAR *outpath, int size, const TCHAR *inpath);
 extern void getfilepart (TCHAR *out, int size, const TCHAR *path);
+extern bool target_isrelativemode(void);
 extern uae_u32 getlocaltime (void);
 extern bool isguiactive(void);
 extern bool is_mainthread(void);
index 7e943b6b773da01f0f474e2e20a017de9580ec80..79b302a5da326d4327e1abeedb0dab807d8decac 100644 (file)
@@ -3496,7 +3496,7 @@ void fixtrailing (TCHAR *p)
        _tcscat(p, _T("\\"));
 }
 // convert path to absolute or relative
-void fullpath (TCHAR *path, int size)
+void fullpath(TCHAR *path, int size, bool userelative)
 {
        if (path[0] == 0 || (path[0] == '\\' && path[1] == '\\') || path[0] == ':')
                return;
@@ -3508,7 +3508,7 @@ void fullpath (TCHAR *path, int size)
        /* <drive letter>: is supposed to mean same as <drive letter>:\ */
        if (_istalpha (path[0]) && path[1] == ':' && path[2] == 0)
                _tcscat (path, _T("\\"));
-       if (relativepaths) {
+       if (userelative) {
                TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
                tmp1[0] = 0;
                GetCurrentDirectory (sizeof tmp1 / sizeof (TCHAR), tmp1);
@@ -3551,6 +3551,16 @@ done:;
                DWORD err = GetFullPathName (tmp, size, path, NULL);
        }
 }
+void fullpath(TCHAR *path, int size)
+{
+       fullpath(path, size, relativepaths);
+}
+
+bool target_isrelativemode(void)
+{
+       return relativepaths != 0;
+}
+
 void getpathpart (TCHAR *outpath, int size, const TCHAR *inpath)
 {
        _tcscpy (outpath, inpath);
index b43b38cfb46ac1ba9c8cbe47795e81b4fc65a13d..1d36cedb17bfb3c8cf15e7ac80ecb1b3613f1c38 100644 (file)
@@ -201,6 +201,17 @@ void save_path_func (uae_u8 **dstp, const TCHAR *from, int type)
 {
        save_string_func (dstp, from);
 }
+void save_path_full_func(uae_u8 **dstp, const TCHAR *spath, int type)
+{
+       TCHAR path[MAX_DPATH];
+       save_u32_func(dstp, type);
+       _tcscpy(path, spath ? spath : _T(""));
+       fullpath(path, MAX_DPATH, false);
+       save_string_func(dstp, path);
+       _tcscpy(path, spath ? spath : _T(""));
+       fullpath(path, MAX_DPATH, true);
+       save_string_func(dstp, path);
+}
 
 uae_u32 restore_u32_func (uae_u8 **dstp)
 {
@@ -262,31 +273,30 @@ static bool state_path_exists(const TCHAR *path, int type)
        return my_existsfile(path);
 }
 
-TCHAR *restore_path_func (uae_u8 **dstp, int type)
+static TCHAR *state_resolve_path(TCHAR *s, int type, bool newmode)
 {
        TCHAR *newpath;
-       TCHAR *s;
        TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH];
 
-       s = restore_string_func (dstp);
        if (s[0] == 0)
                return s;
-       if (zfile_exists (s))
+       if (!newmode && state_path_exists(s, type))
                return s;
        if (type == SAVESTATE_PATH_HD)
                return s;
-#if 0
-       _tcscpy(tmp, s);
-       fullpath(tmp, sizeof(tmp) / sizeof(TCHAR));
-       if (state_path_exists(tmp, type)) {
-               xfree(s);
-               return my_strdup(tmp);
-       }
-#endif
-       getfilepart (tmp, sizeof tmp / sizeof (TCHAR), s);
-       if (state_path_exists(tmp, type)) {
-               xfree (s);
-               return my_strdup (tmp);
+       if (newmode) {
+               _tcscpy(tmp, s);
+               fullpath(tmp, sizeof(tmp) / sizeof(TCHAR));
+               if (state_path_exists(tmp, type)) {
+                       xfree(s);
+                       return my_strdup(tmp);
+               }
+       } else {
+               getfilepart(tmp, sizeof tmp / sizeof(TCHAR), s);
+               if (state_path_exists(tmp, type)) {
+                       xfree(s);
+                       return my_strdup(tmp);
+               }
        }
        for (int i = 0; i < MAX_PATHS; i++) {
                newpath = NULL;
@@ -316,6 +326,43 @@ TCHAR *restore_path_func (uae_u8 **dstp, int type)
        return s;
 }
 
+TCHAR *restore_path_func(uae_u8 **dstp, int type)
+{
+       TCHAR *s = restore_string_func(dstp);
+       return state_resolve_path(s, type, false);
+}
+
+TCHAR *restore_path_full_func(uae_u8 **dstp)
+{
+       int type = restore_u32_func(dstp);
+       TCHAR *a = restore_string_func(dstp);
+       TCHAR *r = restore_string_func(dstp);
+       if (target_isrelativemode()) {
+               xfree(a);
+               return state_resolve_path(r, type, true);
+       } else {
+               TCHAR tmp[MAX_DPATH];
+               _tcscpy(tmp, a);
+               fullpath(tmp, sizeof(tmp) / sizeof(TCHAR));
+               if (state_path_exists(tmp, type)) {
+                       xfree(r);
+                       xfree(a);
+                       return my_strdup(tmp);
+               }
+               _tcscpy(tmp, r);
+               fullpath(tmp, sizeof(tmp) / sizeof(TCHAR));
+               if (state_path_exists(tmp, type)) {
+                       xfree(r);
+                       xfree(a);
+                       return my_strdup(tmp);
+               }
+               xfree(r);
+               return state_resolve_path(a, type, true);
+       }
+       return NULL;
+}
+
+
 /* read and write IFF-style hunks */
 
 static void save_chunk (struct zfile *f, uae_u8 *chunk, unsigned int len, const TCHAR *name, int compress)
@@ -691,10 +738,12 @@ void restore_state (const TCHAR *filename)
                        end = restore_hrtmon (chunk);
 #endif
 #ifdef FILESYS
-               else if (!_tcscmp (name, _T("FSYS")))
-                       end = restore_filesys (chunk);
-               else if (!_tcscmp (name, _T("FSYC")))
-                       end = restore_filesys_common (chunk);
+               else if (!_tcscmp(name, _T("FSYP")))
+                       end = restore_filesys_paths(chunk);
+               else if (!_tcscmp(name, _T("FSYS")))
+                       end = restore_filesys(chunk);
+               else if (!_tcscmp(name, _T("FSYC")))
+                       end = restore_filesys_common(chunk);
 #endif
 #ifdef CD32
                else if (!_tcscmp (name, _T("CD32")))
@@ -1053,10 +1102,15 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
        if (dst) {
                save_chunk (f, dst, len, _T("FSYC"), 0);
                for (i = 0; i < nr_units (); i++) {
-                       dst = save_filesys (i, &len);
+                       dst = save_filesys_paths(i, &len);
+                       if (dst) {
+                               save_chunk(f, dst, len, _T("FSYP"), 0);
+                               xfree(dst);
+                       }
+                       dst = save_filesys(i, &len);
                        if (dst) {
-                               save_chunk (f, dst, len, _T("FSYS"), 0);
-                               xfree (dst);
+                               save_chunk(f, dst, len, _T("FSYS"), 0);
+                               xfree(dst);
                        }
                }
        }