From 73866d3b4a1e0805cd33e0757f2b0db8775fbef8 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 14 Jul 2018 21:24:19 +0300 Subject: [PATCH] Full relative/absolute path statefile support. --- blkdev.cpp | 26 +++++++----- disk.cpp | 23 +++++++--- filesys.cpp | 85 +++++++++++++++++++++++++++++++++---- include/savestate.h | 8 +++- include/uae.h | 4 +- od-win32/win32.cpp | 14 ++++++- savestate.cpp | 100 ++++++++++++++++++++++++++++++++++---------- 7 files changed, 209 insertions(+), 51 deletions(-) diff --git a/blkdev.cpp b/blkdev.cpp index d76c7a0f..8c50999b 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -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; } diff --git a/disk.cpp b/disk.cpp index 8a2373f0..9b7c942b 100644 --- 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; } diff --git a/filesys.cpp b/filesys.cpp index 3edd22a2..dd23cd05 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -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; } diff --git a/include/savestate.h b/include/savestate.h index d06085fb..12081ad7 100644 --- a/include/savestate.h +++ b/include/savestate.h @@ -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); diff --git a/include/uae.h b/include/uae.h index 6ea146c4..9fa23022 100644 --- a/include/uae.h +++ b/include/uae.h @@ -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); diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 7e943b6b..79b302a5 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -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) /* : is supposed to mean same as :\ */ 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); diff --git a/savestate.cpp b/savestate.cpp index b43b38cf..1d36cedb 100644 --- a/savestate.cpp +++ b/savestate.cpp @@ -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); } } } -- 2.47.3