[PC] Save editor - Memoria (0.6.3.1)

  • Thread starter Thread starter gjoerulv
  • Start date Start date
Status
Not open for further replies.
G

gjoerulv

Guest
v0.6.3.1 is available. Download below.

Features:

  • Editing character stat, equipment and abilities.
  • Change party members, Gil, Items and other party related stuff
  • Card editing.
  • Import and export features.
  • PSX memcard handling. Change region. Copy/paste/delete blocks.
  • When editing *.dat and/or *.sav keep in mind that this must be considered experimental. BACKUP YOUR FILES!

New in 0.6.3.1:

  • !ONLY TESTED ON STEAM VERSION!
  • Fixed a bug on item-editing.
  • Known bugs/issues: Setting abilities (magic stones) only works like it would in-game (if I'm not mistaken). Meaning setting all abilities won't work, most likely. Also setting Cardattack/def values to max will cause the card to reset when they lvl (255->0). Try setting these values a bit lower to avoid this.
    Explanation

Known bugs/issues in newest release:

  • Exporting/importing blocks makes an undo-redo push even if you did not export/import anything. This does not mean it's unsafe to export/import.
  • Try to avoid switching to full screen or restore down when editing cards (card tab active). It may cause lag for a while. It's better to do this while another tab is active.
  • As mentioned in version history, Card and ability (magic stones) editing isn't 100%. Setting passive abilities doesn't seem to register (2016 release only).
  • Preview of *.dat and *.sav files will not be updated in-game.
  • Successful thefts editing on 2016 release doesn't seem to work.
  • Probably more :P


For non-steam/android/ios users:
I want feedback on design etc. But more importantly you can help me figure out the savemap. I included an unknown-values-report form. Open a .mcr file with FF9 data and push F10 (Properties) (PSX files only).
As you can see it will find offsets which values are unknown and compare 'em, and report 'em IF they are different. This way it can be quite easy to figure out the unknown data by loading a game, do minor changes, then save to another slot/block.
The radio buttons which makes sense to use are:
Characters Only (Checks unknown data in characters only).
Block, no character data (Checks all unknown data not related to any characters).

DOWNLOAD


0.5.1b
0.5b
0.4b
0.3b

For Windows. .Net framework 2.0 required.

If your characters heals enemies when attacking, it's because they have the healer ability on. This cannot be undone in game as the healer ability is not visible on all characters. In Memoria goto character tab -> magic stones -> Uncheck healer.

Credits:
Zande (CRC, Savemap)
sithlord48 (memory card file info)
Armorvil (for naming the app)
MaKiPL (for help on the 2016 rerelease.)
 
Last edited:
Wow, great work ! I love the layout ; simple and efficient.

Looking at the available options, aside from the story and world positions, it seems to me that you already figured out the whole savemap. Though I'm surprised that you can put 255 in the Strength, Speed, Magic and Spirit boxes - aren't the maximum 100 for Str/Mag and 50 for Spd/Spr ?

EDIT:

Wow, this isn't gonna be simple. I saved my game near the chocobo forest (King Ed Plains), and went to save on another block in Eunorus Plains, near the Dragon Gate. Then, I compared the two blocks with the "block, no character data" function. Here are the results :

Code: [Select]
Code:
Offset   BlockA  BlockB  A - B0x0017   51      52      -10x0021   4f      50      -10x0023   58      50      80x0110   1a      14      60x0111   38      44      -120x0113   36      3e      -80x0114    f      41      -500x0115   14      44      -480x0116   33      42      -150x012c   87       b      1240x012d   bb      cd      -180x0178    2       3      -10x017c    1       2      -10x0200   9c      81      270x0201   44      90      -760x0202    4       3      10x0203   8a       1      1370x0204   f8      fd      -50x0205   4d       d      640x0206   3b       9      500x0208   5b      d9      -1260x0213   3c      77      -590x0214   48      8f      -710x0215    4       3      10x0216   d9       7      2100x0217   f8      fd      -50x0218   54      97      -670x0219   3a       9      490x021b   5d      11      760x0f0d   f0       0      2400x0f18   23      36      -190x0f19    8       1      70x13fe   a0       4      1560x13ff   79      a1      -40Comparisson complete!Offset   BlockA  BlockB  A - B0x0178    2       3      -10x017c    1       2      -10x0200   9c      81      270x0201   44      90      -760x0202    4       3      10x0203   8a       1      1370x0204   f8      fd      -50x0205   4d       d      640x0206   3b       9      500x0208   5b      d9      -1260x0213   3c      77      -590x0214   48      8f      -710x0215    4       3      10x0216   d9       7      2100x0217   f8      fd      -50x0218   54      97      -670x0219   3a       9      490x021b   5d      11      760x0f0d   f0       0      2400x0f18   23      36      -190x0f19    8       1      70x13fe   a0       4      1560x13ff   79      a1      -40Comparisson complete!Offset   BlockA  BlockB  A - B0x0017   51      52      -10x0021   4f      50      -10x0023   58      50      80x0110   1a      14      60x0111   38      44      -120x0113   36      3e      -80x0114    f      41      -500x0115   14      44      -480x0116   33      42      -150x012c   87       b      1240x012d   bb      cd      -180x0178    2       3      -10x017c    1       2      -10x0200   9c      81      270x0201   44      90      -760x0202    4       3      10x0203   8a       1      1370x0204   f8      fd      -50x0205   4d       d      640x0206   3b       9      500x0208   5b      d9      -1260x0213   3c      77      -590x0214   48      8f      -710x0215    4       3      10x0216   d9       7      2100x0217   f8      fd      -50x0218   54      97      -670x0219   3a       9      490x021b   5d      11      760x0f0d   f0       0      2400x0f18   23      36      -190x0f19    8       1      70x13fe   a0       4      1560x13ff   79      a1      -40Comparisson complete!Offset   BlockA  BlockB  A - B0x0178    2       3      -10x017c    1       2      -10x0200   9c      81      270x0201   44      90      -760x0202    4       3      10x0203   8a       1      1370x0204   f8      fd      -50x0205   4d       d      640x0206   3b       9      500x0208   5b      d9      -1260x0213   3c      77      -590x0214   48      8f      -710x0215    4       3      10x0216   d9       7      2100x0217   f8      fd      -50x0218   54      97      -670x0219   3a       9      490x021b   5d      11      760x0f0d   f0       0      2400x0f18   23      36      -190x0f19    8       1      70x13fe   a0       4      1560x13ff   79      a1      -40Comparisson complete!
I bet the coordinates for the party are in there somewhere, along with the game clock, but wow. I didn't expect so many bytes to change.
 
Last edited:
I wish I could tag threads now. This is already beautiful :cry:.

Anyway, I need to look into that crc check from FFIX for you, don't I? I don't get much chance to sit down with the FFIX discs, but I'll see if I can smuggle some time in tomorrow.
 
...I'm surprised that you can put 255 in the Strength, Speed, Magic and Spirit boxes - aren't the maximum 100 for Str/Mag and 50 for Spd/Spr ?
You can, but but anything above 100 won't display correctly. And I'm not sure if the game calculates beyond the max value. I know that if you level up or change equipment your stats will pretty much reset.

Figuring out the savemap shouldn't be too hard. It just requires patience. I'm lacking it for the moment. :P

@NFITC1 smuggle away if you can. I was hoping this release would spawn some crc related work. I'll get to it eventually. If you're looking for a emulator with good debugging pSX 1.13 works fine. I've heard PCSXTrace is pretty good too. I'll check it out.
 
2 gjoerulv: Do you have description to all save data that you found? I working on script dumper now. It can help me a bit.
 
@Akari
Yup.
Code: [Select]
Code:
0x0105: BYTE    Level;          // Party leader level0x0106: CHAR[8]   Name;        // Party leader name0x010E: BYTE    Unknown;        // ???0x010F: BYTE    Unknown;        // ???0x0110: CHAR[28]    Location;   // Name of current location0x012C: BYTE    Gametime;       // Gametime0x0130: BYTE    Gil;            // Total amount of Gil???0x01C5 BYTE    DISCNR???0x0EE0 - 0x0EE3 = party members (1 byte each).0x0EE4 - 0x0EE7 =               //UNKNOWN0x0EE8: DWORD                   // Total amount of Gil0x0EEC: WORD        // Frogs captured bt Quina0x0EEE: BYTE                    //UNKNOWN0x0EEF: BYTE                    //UNKNOWN0x0EF0: WORD                    // Dragons slayed0x13FE: WORD   CRC/CHECKSUMZidane   9D0 - A5F      items F20 - 111FVivi     A60 - AEE      cards 1178 - 13F3Dagger   AF0 - B7FSteiner  B80 - C0FFreya    C10 - C9FQuina    CA0 - D2FEiko     D30 - DBFAmarant  DC0 - E4FBeatrix  E50 - EDF// ============================================================================// Final Fantasy IX | Savegame | Character Stats// Start Pointer: 0x09d0// End Pointer: 0x0EDF// Block Count: 9// Block Size: 144 bytes// Total Size: 1296 bytes// ============================================================================0x0000: CHAR[8]     Name;        // Character name0x0008: BYTE    Unknown;        // ???0x0009: BYTE    Unknown;        // ???0x000A: BYTE    Unknown;        // ???0x000B: BYTE    Level;          // Character level0x000C: DWORD   Experience;     // Total amount of experience ?0x0010: WORD    CurrentHP;      // Current amount of HP0x0012: WORD    CurrentMP;      // Current amount of MP0x0014: BYTE    Unknown;        // ???0x0015: BYTE    Unknown;        // ???0x0016: BYTE    Unknown;        // ???0x0017: BYTE    CurrentMS;      // Current amount of magical stones0x0018: WORD    MaxHP;          // Max amount of HP0x001A: WORD    MaxMP;          // Max amount of MP0x001C: BYTE    Unknown;        // ???0x001D: BYTE    Unknown;        // ???0x001E: BYTE    Unknown;        // ???0x001F: BYTE    MaxMS;          // Max amount of magical stones0x0020: BYTE    TranceLevel;    // Trance Level0x0021: BYTE    Unknown;        // ???0x0022: BYTE    Unknown;        // ???0x0023: BYTE    Unknown;        // ???0x0024: BYTE    Speed;          // Speed (total value incl. gear bonuses)0x0025: BYTE    Strength;       // Strength (total value incl. gear bonuses)0x0026: BYTE    Magic;          // Magic (total value incl. gear bonuses)0x0027: BYTE    Spirit;         // Spirit (total value incl. gear bonuses)0x0028: BYTE    Defence;        // Defence0x0029: BYTE    Evade;          // Evade0x002A: BYTE    MagicDefence;   // Magic defence0x002B: BYTE    MagicEvade;     // Magic evade0x002C: WORD    2nd HP max;     // Max HP with Bonus?0x002E: WORD    2nd MP max;     // Max MP with Bonus?0x0030: BYTE    BaseSpeed;      // Base speed (excl. gear bonuses)0x0031: BYTE    BaseStrength;   // Base strength (excl. gear bonuses)0x0032: BYTE    BaseMagic;      // Base magic (excl. gear bonuses)0x0033: BYTE    BaseSpirit;     // Base spirit (excl. gear bonuses)0x0034: BYTE    Unknown;        // ???0x0035: BYTE    Unknown;        // ???0x0036: BYTE    Unknown;        // ???0x0037: BYTE    Unknown;        // ???0x0038: BYTE    Status;         // Status bits.0x0039: BYTE    Weapon;         // Equiped weapon0x003A: BYTE    Headgear;       // Equiped head gear0x003B: BYTE    Armgear;        // Equiped arm gear0x003C: BYTE    Armor;          // Equiped armor0x003D: BYTE    Addon;          // Equiped add-on0x003E: BYTE    Unknown;        // ???0x003F: BYTE    Unknown;        // ???0x0040: BYTE    Unknown;        // ???0x0041: BYTE    Unknown;        // ???0x0042: BYTE    Unknown;        // ???0x0043: BYTE    Unknown;        // ???0x0044: BYTE    Unknown;        // ???0x0045: BYTE    Unknown;        // ???0x0046: BYTE    Unknown;        // ???0x0047: BYTE    Unknown;        // ???0x0048: BYTE    Unknown;        // ???0x0049: BYTE    Unknown;        // ???0x004A: BYTE    Unknown;        // ???0x004B: BYTE    Unknown;        // ???0x004C: BYTE    Unknown;        // ???0x004D: BYTE    Unknown;        // ???0x004E: BYTE    Unknown;        // ???0x004F: BYTE    Unknown;        // ???0x0050: BYTE    Unknown;        // ???0x0051: BYTE    Unknown;        // ???0x0052: BYTE    Unknown;        // ???0x0053: BYTE    Unknown;        // ???0x0054: BYTE    Unknown;        // ???0x0055: BYTE    Unknown;        // ???0x0056: BYTE    Unknown;        // ???0x0057: BYTE    Unknown;        // ???0x0058: BYTE    Unknown;        // ???0x0058: BYTE    AbilityAP[48];  // AP for action/support abilities0x0088: BYTE    Support[8];     // (Bitmap) Support abilities equiped// ============================================================================// Final Fantasy IX | Savegame | Item List// Start Pointer: 0x0F20// End Pointer: 0x111F// Block Count: 256// Block Size: 2 bytes// Total Size: 512 bytes// ============================================================================0x0000: BYTE    ID;              // Item ID0x0001: BYTE    Count;           // Item Count CARDS:0x1178: WORD    WINS0x117A: WORD    LOSSES0x117C: WORD    DRAWS// ============================================================================// Final Fantasy IX | Savegame | Cards// Start Pointer: 0x117E// End Pointer: 0x13F3// Block Count: 105// Block Size: 6 bytes// Total Size: 630 bytes// ============================================================================ 0x0000: BYTE    Type;            // Type  (FFh = No Card/Type)0x0001: BYTE    Arrow bits;      // Bitmap representing arrows.0x0002: BYTE    Attack;          // Attack Power.    0x0003: BYTE    Attack type;     // Type of attack (physical, magical etch.)0x0004: BYTE    P.Def;           // Physical defence power.0x0005: BYTE    M.Def;           // Magical defence power.
 
In case you were wondering, it looks like the texts for saving/loading exist in Dir00: File 39 in the FFIX.img file on disc 1. It contains texts like "Data from another game.", "Data corrupted", "Select MEMORY CARD slot.", "Do not remove MEMORY CARDsor Controllers, or open thedisc cover."[sic], and "Honolulu Harbor Court" (I kid you not). My knowledge of such things seems to end there. :( This is lacking the usual executable header info so there's no real entry point for me to start disassembling at. It's likely this file contains the methods for calculating the CRC because of the "Data corrupted." text that's in there. Without an entry point I don't know what's really going on.
 
@NFITC1
Yes, I knew that. Thanks for the effort!

I'm trying something new now. Hopefully it'll work.
 
I figured you would, but I thought I'd mention in case you hadn't looked yet. It seems in that file after all the texts are some images. What kind of images are these and how do I view them?
 
In case you were wondering, it looks like the texts for saving/loading exist in Dir00: File 39 in the FFIX.img file on disc 1. It contains texts like "Data from another game.", "Data corrupted", "Select MEMORY CARD slot.", "Do not remove MEMORY CARDsor Controllers, or open thedisc cover."[sic], and "Honolulu Harbor Court" (I kid you not). My knowledge of such things seems to end there. :( This is lacking the usual executable header info so there's no real entry point for me to start disassembling at. It's likely this file contains the methods for calculating the CRC because of the "Data corrupted." text that's in there. Without an entry point I don't know what's really going on.
In DIR 0 there are only 20 files. File 13 is SAVE & LOAD menu.

  0x0000 - 0x0003: DWORD = 20
  // ???
  0x0004 - 0x0017: 5 blocks of unknown data
  // 58 STRINGS
  0x0018 - 0x001B: Number of strings (58)
  0x001C - 0x0103: 58 String headers { WORD Pointer; BYTE Unknown; BYTE Unknown; }
  0x0104 - 0x05CC: String data
  0x05CD - 0x05CF: 3 bytes padding (NULL)
  // CHARACTER IMAGES
  0x05D0 - 0x494F: Data (0x4380, 0x0100/0x05C0)
  // CHECK MEMORY CARD ANIMATION
  0x4950 - 0x4B4F: Palette
  0x4B50 - 0x61FF: Image Data (176x33)
 
In DIR 0 there are only 20 files. File 13 is SAVE & LOAD menu....
I meant File index 39h. I know it's the 13th file. I'll see what disassembling starting at 0x6200 gives me.
 
Thanks to Zande I was able to make the crc work. I'll release a beta soon!
EDIT: Uploaded a beta! :)
 
Last edited:
Just want to show some appreciation to the author for creating this save game editor.
I love the internet, what isn't available through thousands of searches one day, becomes available through a search for something completely different months and sometimes years later.  Was looking for an editor for this game for a long time, glad I stumbled onto this forum!  Thanks gjoerulv!
 
just a quick note about Mcr files, *.mcr,  *.mcd , *.bin , *.mc ,*.mci, *.ps, *.psm and *.dff  are identical except for the extention you might want to add the other ones to the open file filter just to so your able to open them easily.
 
Sounds good there sith. Haven't really looked into psx memcard file types yet.
Do all these always have the same, raw format? I mean same length, headers, etc. If I'm not mistaken, there should be encrypted/compressed types as well.
 
Sounds good there sith. Haven't really looked into psx memcard file types yet.
Do all these always have the same, raw format? I mean same length, headers, etc. If I'm not mistaken, there should be encrypted/compressed types as well.
there a few main types but not are encrypted just the newer formats have huge checksums as part of the header

the "Standard" memcard its just a raw image of a psx mem card (type 3)
the "vgs /mem type" thats a 0x40byte header then the standard format. (type_6)
the "dex-drive" a header of 0xF40 followed by the standard format(type_7)
the "PSP's vmp file" a header of 0x80 followed by the standard format (in the header is a checksum)(type_5)
and "PSV format" a header of 0x84 followed the save and a footer. (checksum and a short version of the memcard index )(type_4)

you might wish to consult the source for black chocobo as it will explain in better detail first you might want to look at

FF7SAVE.h - The first bit of the file sets const ints for each types size, header , etc.

and also you might want to look at

mainwindow.cpp - starting on line 167 is loadFullFile this functions does the loading  then later on line 478 there is a save function  it does stuff based on the format (types 3,5,6,7 are what ur looking at) after you
look there next you will want to look at

globals.cpp-fix_vmc_header() it starts on line 93 . this function ensures that any virtual memory card format get its header data updated (both region and times in the psx header) this is of course important because other wise the system won't reconize the game's save

hope this helps.
 
Status
Not open for further replies.
Back
Top