Apollo Save Tool Save Format Conversions: Supported PSV, PSU, MCS, and PSX Formats

Apollo Save Tool supports bidirectional conversion between classic PlayStation save formats, allowing users to import PS1 saves as MCS, PSV, PSX, MCB, PDA, or PS1 files and export them as MCS, PSV, or PSX, while PS2 saves can be imported as PSU, PSV, XPS, CBS, MAX, or SPS and exported as PSU or PSV.

According to the bucanero/apollo-ps4 source code, the application functions as a unified front-end for managing saves across three PlayStation generations. The conversion logic resides primarily in source/saves.c and source/exec_cmd.c, utilizing an intermediate virtual memory card (VMC) representation to translate between legacy PS1/PS2 formats and modern PSV containers.

Supported Save Format Conversion Matrix

Apollo implements distinct import and export capabilities for each console family. The extension filtering logic in source/saves.c uses endsWith() checks to validate supported formats at lines 766 and surrounding blocks.

Console Importable Formats Exportable Formats
PS1 .MCS, .PSV, .PSX, .PS1, .MCB, .PDA .MCS, .PSV, .PSX
PS2 .PSU, .PSV, .XPS, .CBS, .MAX, .SPS .PSU, .PSV
PS3-virtual — (Generated from imports) .PSV (Generated)

Extension Detection Implementation

In source/saves.c, the file browser filters valid save files using explicit string comparisons:

if (!endsWith(dir->d_name, ".PSV") && !endsWith(dir->d_name, ".MCS") && 
    !endsWith(dir->d_name, ".PSX") && !endsWith(dir->d_name, ".PSU") && ...)

This ensures only compatible files appear in the import dialog, preventing users from selecting unsupported container types.

The Conversion Pipeline: From Import to Export

Apollo handles save format conversions through a three-stage pipeline that abstracts format-specific details into a unified VMC interface.

Stage 1: Import and VMC Loading

When a user imports a legacy save—such as a .MCS file for PS1 or a .PSU file for PS2—the application loads the data into an in-memory virtual memory card representation. This decouples the storage format from the data structure, allowing cross-format manipulation.

Stage 2: Format Translation

For PS2 conversions involving third-party formats like XPS, CBS, or MAX, Apollo utilizes specific converter functions defined in source/exec_cmd.c. These functions translate proprietary containers into standard PSV format before VMC import:

/* source/exec_cmd.c – PS2 XPS to PSV conversion chain */
ret = ps2_xps2psv(src, APOLLO_LOCAL_CACHE "TEMP.PSV") &&
      vmc_import_psv(APOLLO_LOCAL_CACHE "TEMP.PSV");
unlink_secure(APOLLO_LOCAL_CACHE "TEMP.PSV");

Similar functions exist for ps2_cbs2psv() and ps2_max2psv(), each parsing the respective container format, building a valid PSV header, and injecting the raw PS2 save data.

Stage 3: Export to Target Format

The export process reverses the pipeline. When a user selects Export to .PSV or Export to .MCS, the saveSingleSave() function writes the VMC data back to disk using the target format's specifications. The PSV resigning subsystem in source/psv_resign.c handles cryptographic validation and container sealing during this phase, ensuring generated PSV files maintain proper magic headers and type discrimination.

Core Implementation Files and Functions

Understanding the Apollo Save Tool architecture requires examining these specific source files:

File Function in Conversion Pipeline
source/saves.c Central dispatcher for import/export operations; creates UI command codes like CMD_EXP_VMC1SAVE and CMD_EXP_VMC2SAVE; validates file extensions.
source/exec_cmd.c Execution layer housing conversion helpers (ps2_xps2psv, ps2_cbs2psv, ps2_max2psv) and the VMC import logic.
source/psv_resign.c Container validation and resigning; checks PSV_MAGIC bytes and discriminates between PS1-derived and PS2-derived PSV files via PSV_TYPE_OFFSET.
source/psv_ps2.c PS2-specific PSV generation utilities for constructing valid containers from raw save data.
source/ps1card.c PS1-specific handling for MCS/PSX generation and PSV encapsulation of PS1 saves.
include/saves.h Type definitions including FILE_TYPE_PSV, FILE_TYPE_PSU, and CHAR_TAG_PSV constants.

UI Command Construction

Export menu entries are dynamically generated in source/saves.c using the _createCmdCode() function. For PS1 PSV exports:

/* source/saves.c – PS1 PSV export command creation (line 838) */
cmd = _createCmdCode(PATCH_COMMAND,
                     CHAR_ICON_COPY " ",
                     _("Export save game to .PSV format"),
                     CMD_CODE_NULL);
_createOptions(cmd, _("Export .PSV save to USB"), CMD_EXP_VMC1SAVE);
asprintf(&optval->name, "%s", _("Export .PSV save to HDD"));
cmd->options[0].id = PS1SAVE_PSV;

PS2 PSU exports follow a similar pattern at line 984, utilizing CMD_EXP_VMC2SAVE and FILE_TYPE_PSU identifiers to route the operation to the appropriate handler.

Practical Code Examples

The following snippets demonstrate how Apollo Save Tool implements specific conversion workflows in the bucanero/apollo-ps4 codebase.

Exporting PS1 Saves to MCS Format

The MCS export path targets original PlayStation memory card raw dumps:

/* source/saves.c – MCS export command (line 829) */
cmd = _createCmdCode(PATCH_COMMAND,
                     CHAR_ICON_COPY " ",
                     _("Export save game to .MCS format"),
                     CMD_CODE_NULL);
_createOptions(cmd, _("Export .MCS save to USB"), CMD_EXP_VMC1SAVE);

When triggered, this invokes saveSingleSave() with the PS1SAVE_MCS type identifier, writing the VMC contents as a raw 128KB memory card image compatible with emulators.

PS2 XPS Import and Conversion

Third-party PS2 save formats require normalization to PSV before VMC integration:

/* source/exec_cmd.c – XPS conversion workflow (line 1046) */
int ret = ps2_xps2psv(src, APOLLO_LOCAL_CACHE "TEMP.PSV");
if (ret) {
    ret = vmc_import_psv(APOLLO_LOCAL_CACHE "TEMP.PSV");
}
unlink_secure(APOLLO_LOCAL_CACHE "TEMP.PSV");

The ps2_xps2psv() function parses the XPS container's proprietary headers, extracts the raw save data, constructs a compliant PSV header, and writes the temporary file. vmc_import_psv() then imports this standardized container into the virtual memory card, after which the temporary file is securely deleted.

PSV Type Validation

Before processing any PSV file, Apollo validates the container type in source/psv_resign.c:

/* source/psv_resign.c – Magic and type validation (line 351) */
if (memcmp(PSV_MAGIC, p, 4) != 0 || p[PSV_TYPE_OFFSET] != PSV_TYPE_PS2) {
    LOG("Not a PS2 .PSV file");
    return -1;
}

This ensures the application correctly discriminates between PS1-derived and PS2-derived PSV files, applying the appropriate cryptographic and structural handling for each generation.

Summary

  • Apollo Save Tool supports import of PS1 saves via .MCS, .PSV, .PSX, .PS1, .MCB, and .PDA extensions, and export to .MCS, .PSV, and .PSX.
  • PS2 saves can be imported as .PSU, .PSV, .XPS, .CBS, .MAX, or .SPS, with export capabilities limited to .PSU and .PSV formats.
  • The conversion architecture utilizes a virtual memory card (VMC) intermediate representation implemented in source/saves.c, enabling bidirectional translation between legacy formats and modern PSV containers.
  • Third-party PS2 formats (XPS, CBS, MAX) are normalized through specific converter functions in source/exec_cmd.c before VMC import.
  • All PSV operations undergo validation in source/psv_resign.c to ensure proper magic headers and console-type discrimination.

Frequently Asked Questions

Can Apollo Save Tool convert PS2 MAX or CBS saves directly to PSU format?

Yes, but indirectly. According to source/exec_cmd.c, the tool first converts MAX or CBS files to a temporary PSV format using ps2_max2psv() or ps2_cbs2psv(), imports the PSV into the virtual memory card, then exports as PSU via saveSingleSave() with the FILE_TYPE_PSU identifier. The user interface abstracts this two-step process into a single export action.

What is the difference between PSV files for PS1 and PS2 saves in Apollo?

While both use the .PSV extension, the internal structure differs. As implemented in source/psv_resign.c, Apollo checks the byte at PSV_TYPE_OFFSET to discriminate between PS1-derived and PS2-derived PSV files. PS1 PSV files contain 128KB memory card images, while PS2 PSV files encapsulate larger save data structures with different cryptographic signatures.

Does Apollo support converting PS3 saves to PS1 or PS2 formats?

No. The PSV format referenced in Apollo refers to "PlayStation Virtual" saves exported from PS1/PS2 data for use on PS3/PS4 systems, not native PS3 save data. The tool generates PSV files from legacy imports but cannot decrypt or convert modern PS3/PS4 proprietary save formats back to classic PS1/PS2 formats.

Where does Apollo validate file extensions before showing the import dialog?

Extension filtering occurs in source/saves.c around line 766, where the directory listing logic uses endsWith() comparisons against supported extensions including .PSV, .MCS, .PSX, and .PSU. Only files matching these patterns appear in the browser, preventing users from attempting to import incompatible container formats.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →