Save Game Metadata Questions

slinga

Member
@EmeraldNova has been testing my Save Game Copier re-write. He noticed that the Panzer Dragoon Zwei save didn't work when copied. One theory I had is that the comment on the save (which appears to change based on your in-game rank) was invalid. Also highly possible I still have bugs in my code but it appeared the hashes matched.

So some questions:

1) What does the Netlink do regarding metadata? I was under the impression that the Netlink does not transmit the save metadata. What happens when you download a save with the Netlink to your Saturn? I'm assuming the comment field says something like "Netlink"?
2) Do you know if Panzer Dragoon Zwei or any other game actually validate the comment field?
3) @cafe-alpha, Rockin' B, and hitomi2500 have save game utilities. If they save the metadata in some way I should probably do it the same way for compatibility across tools. I haven't looked at their source code yet.

Thanks.
 
Last edited:

nando

New Member
I have a Netlink, but I don't have a way yet to run code on my Saturn - hopefully my place in the Satiator queue is reached soon. :)
 

rorirub

New Member
I've dumped my save game of PD Zwei before, not with your app but by dumping a backup memory cart and writing a parser, and then using a custom version of Madroms/Rockin-B Save Game Manager to upload it back on the Saturn side. It worked fine.

Do you save all metadata properly in your saves? My memory is foggy but there's the comment, the file date, the file name, there was also a field that listed the # of the file created on the memory cart (not sure what that was, but it gets generated anew when you copy a file, so not important), and a bunch of other stuff I don't remember.
Might also be that you just don't upload data correctly, due to cart fragmentation and stuff like that, but if you use the BIOS function then that shouldn't be an issue.
 

slinga

Member
I've dumped my save game of PD Zwei before, not with your app but by dumping a backup memory cart and writing a parser, and then using a custom version of Madroms/Rockin-B Save Game Manager to upload it back on the Saturn side. It worked fine.
Do you recall if you copied over the comment string as well?
 

rorirub

New Member
I don't remember the exact format but looking at the files it seems I saved the original filename and comment *inside* the file too, so the filename on my PC would be irrelevant.

This may be of interest to you:
It has a sector map viewer, and under options -> Insert you can view the anatomy of a save file. The format I used was the "Druid II like" mode, which is basically everything from the save file, except the sector headers and allocation map (which you only need for traversing the raw data through fixed sector size), plus 2 byte padding so the actual file data always starts at byte 20h instead of 1Eh.
 

cafe-alpha

Member
So some questions:


1) What does the Netlink do regarding metadata? I was under the impression that the Netlink does not transmit the save metadata. What happens when you download a save with the Netlink to your Saturn? I'm assuming the comment field says something like "Netlink"?

2) Do you know if Panzer Dragoon Zwei or any other game actually validate the comment field?

3) @cafe-alpha, Rockin' B, and hitomi2500 have save game utilities. If they save the metadata in some way I should probably do it the same way for compatibility across tools. I haven't looked at their source code yet.


Thanks.

I don't think that there is a game requiring correct metadata to work, but there's maybe a weird case of game using language field to store save data (Bug IIRC, but I may be wrong) and generally speaking it's better to keep metadata as for example comment of a save may give some information about its contents.
Existing save data formats (I insist on the 's' because there are plenty) are so-so : planetweb format doesn't provides any metadata, SSF format have custom (and not documented) format to store date etc. So on my side I simply created an new save data header which is just a full copy of BupDir structure contents, plus some optional informations such as the number of times the save was read or written etc.


Here is what my save header looks like. it looks complicated, but except magic string and of course BupDir structure, it is OK to set everything else to zero.

Code:
#if defined( __GNUC__ )
#pragma pack(1)
#else
#pragma pack(push,1)
#endif


/**
 * Vmem usage statistics structure.
 * Statistics are reset on each vmem session, ie when Saturn is reset,
 * or when game calls BUP_Init function.
**/
typedef struct _vmem_bup_stats_t
{
    /* Number of times BUP_Dir function is called. */
    unsigned char dir_cnt;

    /* Number of times BUP_Read function is called. */
    unsigned char read_cnt;

    /* Number of times BUP_Write function is called. */
    unsigned char write_cnt;

    /* Number of times BUP_Verify function is called. */
    unsigned char verify_cnt;
} vmem_bup_stats_t;


/**
 * Backup data header.
**/
typedef struct _vmem_bup_header_t
{
    /* Magic string.
     * Used in order to verify that file is in vmem format.
     */
#define VMEM_MAGIC_STRING_LEN 4
#define VMEM_MAGIC_STRING "Vmem"
    char magic[VMEM_MAGIC_STRING_LEN];

    /* Save ID.
     * "Unique" ID for each save data file, the higher, the most recent.
     */
    unsigned long save_id;

    /* Vmem usage statistics. */
    vmem_bup_stats_t stats;

    /* Unused, kept for future use. */
    char unused1[8 - sizeof(vmem_bup_stats_t)];

    /* Backup Data Informations Record (34 bytes + 2 padding bytes). */
    BupDir dir;

    /* Date stamp, in Saturn's BUP library format.
     * Used in order to verify which save data is the most
     * recent one when rebuilding index data.
     * Note #1 : this information is already present in BupDir structure, 
     * but games are setting it, so it may be incorrect (typically, set 
     * to zero).
     * Note #2 : this date information is the date when Pseudo Saturn Kai
     * last started, not the time the save was saved, so if information in
     * dir structure is available, it is more accurate.
     */
    unsigned long date;

    /* Unused, kept for future use. */
    char unused2[8];
} vmem_bup_header_t;


#if defined( __GNUC__ )
#pragma pack()
#else
#pragma pack(pop)
#endif
Note #1 : The #pragma pack thing is required because BupDir structure size is not a multiple of 4 bytes.
Note #2 : File extension have to be set to .BUP to make my Save Data Manager recognizing the saves correctly.
 

slinga

Member
Thank you for the response, that was the info I was looking for. While not hard to implement I need to think through how to name the files and how to display them to the user. I suppose I need to incoroporate the save_id as output to the user as well.
 

cafe-alpha

Member
save_id is an extra feature of Gamer's Cartridge to revision history of saves (for example, to recover a save that was deleted or overwritten), so in normal usage setting it always to zero should be fine.
 
Top