| | slinga said: |  |
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. |