Save file format (to help add RetroAchievements?)


We saw that RetroAchievements have been implemented for version 1, a very fun way to compete! A big thanks to RetroAchievement user Sines who appears to be responsible for this!

Version 2 of the game has built-in achievements. In the hope that it could help implementing RetroAchievements for Version 2, we are providing this technical post.

Achievements are stored in a bitfield within SRAM. When it needs to access SRAM, the game code uses the mapper to map the content of SRAM at address 0x8000 in Z80 memory. To do this, the game writes to mapper register $FFFC with bit set 3, updates the data, then disables SRAM by writing to $FFFC again, but with bit 3 cleared. This last $FFFC write could be the trigger to synchronize RetroAchievements with in-game achievements. At that precise moment, achievement bits in SRAM may just have changed!

The structure of the saved data is shown below:

#define SV_SCORE_SLOTS        8
#define SV_SCORE_NAME_LEN    10
#define SV_SCORE_DIGITS        7
// Note: Structure stored packed (no padding) - Use prama pack or
// read fields one by one!
struct scoreEntry {
    // Only terminated by zero if the zero fits
    uint8_t name[SV_SCORE_NAME_LEN];
    // Unpacked BCD
    uint8_t score[SV_SCORE_DIGITS];
};
// Origin of save structure at offset 0 in SRAM (0x8000 in Z80 memory when SRAM is enabled)
struct savestruct {
    uint8_t magic[4]; // 'E','V','L','2'
    uint8_t flags;
    uint8_t achbits[3];
    struct scoreEntry scores[SV_SCORE_SLOTS];
};

The structure member achbits is where achievements are stored. Each bit that is set corresponds to an unlocked(achieved) achievement. Here is a macro to check if achievement id achid is set:

#define GET_ACH_COMPLETED(achbits, achid) ((achbits)[(achid)>>3] & (0x80 >> ((achid) & 7)))

Now what are the achievement IDs? Here is the enumeration:

ACH_BILLY_DONE = 0, // Victory over Billy - Win against billy in a tournament
ACH_JIMMY_DONE, // Victory over Jimmy - Defeat Jimmy in a tournament
ACH_YUI_DONE, // Victory over Yui - Defeat Yui in a tournament
ACH_FASTNIC_DONE, // Victory over Fast Nic - Defeat and unlock Fast Nic in a tournament
ACH_KAREN_DONE, // Karen's demise - Overcome Karen in a tournament
ACH_MUSTACHIO_DONE, // Mustachio's dethroning - Prevail over Mustachio's in a tournament
ACH_8BITBOI_DONE, // 8BitBoi Master - Have the 8BitBoi byte the dust in a tournament
ACH_DEMON_DONE, // Banisher of evil - Send the demon back where it belongs!
ACH_PERFECT_MATCH, // Skillfull Volleyball - Play a perfect match
ACH_PURIST, // Purist - Win a tournament without using items
ACH_BONUS_10BOUNCE, // Juggler - In bonus round, keep the ball in the air until the end.
ACH_BONUS_CELLS, // Master Juggler - In bonus round, make the ball pass over all cells.
ACH_NODEATH_TOURNAMENT, // Masterfull Volleyball - Finish the tournament without loosing a life.
ACH_PERFECT_TOURNAMENT, // Out-of-this-world Volleyball - Play a tournament with only perfect matches.</p>
ACH_UNLOCK_FASTNIC, // Fast and perfect - Play a perfect match against Fastnic

Get Extreme Volleyball Infernal League

Buy Now$4.99 USD or more

Leave a comment

Log in with itch.io to leave a comment.