6 #define PF_WEAPONS_OFFS 0x38
7 #define PF_CURWEAPON_OFFS 0x24
8 #define PF_INVENTORY_OFFS 0xD8
9 #define PF_TELEPORTER_OFFS 0x158
10 #define PF_FLAGS_OFFS 0x218
12 #define MAX_WPN_SLOTS 8
13 #define MAX_TELE_SLOTS 8
15 // load savefile #num into the given Profile structure.
16 bool profile_load(const char *pfname
, Profile
*file
)
21 stat("Loading profile from %s...", pfname
);
22 memset(file
, 0, sizeof(Profile
));
24 fp
= fileopen(pfname
, "rb");
27 staterr("profile_load: unable to open '%s'", pfname
);
31 if (!fverifystring(fp
, "Do041220"))
33 staterr("profile_load: invalid savegame format: '%s'", pfname
);
38 file
->stage
= fgetl(fp
);
39 file
->songno
= fgetl(fp
);
43 file
->pdir
= CVTDir(fgetl(fp
));
45 file
->maxhp
= fgeti(fp
);
46 file
->num_whimstars
= fgeti(fp
);
49 fgeti(fp
); // unknown value
50 curweaponslot
= fgetl(fp
); // current weapon (slot, not number, converted below)
51 fgetl(fp
); // unknown value
52 file
->equipmask
= fgetl(fp
); // equipped items
55 fseek(fp
, PF_WEAPONS_OFFS
, SEEK_SET
);
56 for(i
=0;i
<MAX_WPN_SLOTS
;i
++)
61 int level
= fgetl(fp
);
63 int maxammo
= fgetl(fp
);
66 file
->weapons
[type
].hasWeapon
= true;
67 file
->weapons
[type
].level
= (level
- 1);
68 file
->weapons
[type
].xp
= xp
;
69 file
->weapons
[type
].ammo
= ammo
;
70 file
->weapons
[type
].maxammo
= maxammo
;
72 if (i
== curweaponslot
)
74 file
->curWeapon
= type
;
80 fseek(fp
, PF_INVENTORY_OFFS
, SEEK_SET
);
81 for(i
=0;i
<MAX_INVENTORY
;i
++)
86 file
->inventory
[file
->ninventory
++] = item
;
89 // load teleporter slots
90 file
->num_teleslots
= 0;
91 fseek(fp
, PF_TELEPORTER_OFFS
, SEEK_SET
);
92 for(i
=0;i
<NUM_TELEPORTER_SLOTS
;i
++)
94 int slotno
= fgetl(fp
);
95 int scriptno
= fgetl(fp
);
96 if (slotno
== 0) break;
98 file
->teleslots
[file
->num_teleslots
].slotno
= slotno
;
99 file
->teleslots
[file
->num_teleslots
].scriptno
= scriptno
;
100 file
->num_teleslots
++;
104 fseek(fp
, PF_FLAGS_OFFS
, SEEK_SET
);
105 if (!fverifystring(fp
, "FLAG"))
107 staterr("profile_load: missing 'FLAG' marker");
113 for(i
=0;i
<NUM_GAMEFLAGS
;i
++)
115 file
->flags
[i
] = fbooleanread(fp
);
123 bool profile_save(const char *pfname
, Profile
*file
)
128 //stat("Writing saved game to %s...", pfname);
129 fp
= fileopen(pfname
, "wb");
132 staterr("profile_save: unable to open %s", pfname
);
136 fputstringnonull("Do041220", fp
);
138 fputl(file
->stage
, fp
);
139 fputl(file
->songno
, fp
);
143 fputl((file
->pdir
== RIGHT
) ? 2:0, fp
);
145 fputi(file
->maxhp
, fp
);
146 fputi(file
->num_whimstars
, fp
);
149 fseek(fp
, 0x2C, SEEK_SET
);
150 fputi(file
->equipmask
, fp
);
153 fseek(fp
, PF_WEAPONS_OFFS
, SEEK_SET
);
154 int slotno
= 0, curweaponslot
= 0;
156 for(i
=0;i
<WPN_COUNT
;i
++)
158 if (file
->weapons
[i
].hasWeapon
)
161 fputl(file
->weapons
[i
].level
+ 1, fp
);
162 fputl(file
->weapons
[i
].xp
, fp
);
163 fputl(file
->weapons
[i
].maxammo
, fp
);
164 fputl(file
->weapons
[i
].ammo
, fp
);
166 if (i
== file
->curWeapon
)
167 curweaponslot
= slotno
;
170 if (slotno
>= MAX_WPN_SLOTS
) break;
174 if (slotno
< MAX_WPN_SLOTS
)
175 fputl(0, fp
); // 0-type weapon: terminator
177 // go back and save slot no of current weapon
178 fseek(fp
, PF_CURWEAPON_OFFS
, SEEK_SET
);
179 fputl(curweaponslot
, fp
);
182 fseek(fp
, PF_INVENTORY_OFFS
, SEEK_SET
);
183 for(i
=0;i
<file
->ninventory
;i
++)
185 fputl(file
->inventory
[i
], fp
);
190 // write teleporter slots
191 fseek(fp
, PF_TELEPORTER_OFFS
, SEEK_SET
);
192 for(i
=0;i
<MAX_TELE_SLOTS
;i
++)
194 if (i
< file
->num_teleslots
)
196 fputl(file
->teleslots
[i
].slotno
, fp
);
197 fputl(file
->teleslots
[i
].scriptno
, fp
);
207 fseek(fp
, PF_FLAGS_OFFS
, SEEK_SET
);
208 fputstringnonull("FLAG", fp
);
211 for(i
=0;i
<NUM_GAMEFLAGS
;i
++)
213 fbooleanwrite(file
->flags
[i
], fp
);
224 void c------------------------------() {}
227 // returns the filename for a save file given it's number
228 const char *GetProfileName(int num
)
231 return "profile.dat";
233 return stprintf("profile%d.dat", num
+1);
236 // returns whether the given save file slot exists
237 bool ProfileExists(int num
)
239 return file_exists(GetProfileName(num
));
242 bool AnyProfileExists()
244 for(int i
=0;i
<MAX_SAVE_SLOTS
;i
++)
245 if (ProfileExists(i
)) return true;