// load savefile #num into the given Profile structure. bool profile_load(const char *pfname, Profile *file) { int i, curweaponslot; VMFILE *fp; stat("Loading profile from %s...", pfname); memset(file, 0, sizeof(Profile)); fp = vm_fileopen(pfname, "rb"); if (!fp) { staterr("profile_load: unable to open '%s'", pfname); return 1; } if (!vm_fverifystring(fp, "Do041220")) { staterr("profile_load: invalid savegame format: '%s'", pfname); vm_fclose(fp); return 1; } file->stage = vm_fgetl(fp); file->songno = vm_fgetl(fp); file->px = vm_fgetl(fp); file->py = vm_fgetl(fp); file->pdir = CVTDir(vm_fgetl(fp)); file->maxhp = vm_fgeti(fp); file->num_whimstars = vm_fgeti(fp); file->hp = vm_fgeti(fp); vm_fgeti(fp); // unknown value curweaponslot = vm_fgetl(fp); // current weapon (slot, not number, converted below) vm_fgetl(fp); // unknown value file->equipmask = vm_fgetl(fp); // equipped items // load weapons vm_fseek(fp, PF_WEAPONS_OFFS, SEEK_SET); for(i=0;i<MAX_WPN_SLOTS;i++) { int type = vm_fgetl(fp); if (!type) break; int level = vm_fgetl(fp); int xp = vm_fgetl(fp); int maxammo = vm_fgetl(fp); int ammo = vm_fgetl(fp); file->weapons[type].hasWeapon = true; file->weapons[type].level = (level - 1); file->weapons[type].xp = xp; file->weapons[type].ammo = ammo; file->weapons[type].maxammo = maxammo; if (i == curweaponslot) { file->curWeapon = type; } } // load inventory file->ninventory = 0; vm_fseek(fp, PF_INVENTORY_OFFS, SEEK_SET); for(i=0;i<MAX_INVENTORY;i++) { int item = vm_fgetl(fp); if (!item) break; file->inventory[file->ninventory++] = item; } // load teleporter slots file->num_teleslots = 0; vm_fseek(fp, PF_TELEPORTER_OFFS, SEEK_SET); for(i=0;i<NUM_TELEPORTER_SLOTS;i++) { int slotno = vm_fgetl(fp); int scriptno = vm_fgetl(fp); if (slotno == 0) break; file->teleslots[file->num_teleslots].slotno = slotno; file->teleslots[file->num_teleslots].scriptno = scriptno; file->num_teleslots++; } // load flags vm_fseek(fp, PF_FLAGS_OFFS, SEEK_SET); if (!vm_fverifystring(fp, "FLAG")) { staterr("profile_load: missing 'FLAG' marker"); vm_fclose(fp); return 1; } vm_fresetboolean(); for(i=0;i<NUM_GAMEFLAGS;i++) { file->flags[i] = vm_fbooleanread(fp); } vm_fclose(fp); return 0; }
// load savefile #num into the given Profile structure. bool profile_load(const char *pfname, Profile *file) { int i, curweaponslot; FILE *fp = fopen(pfname, "rb"); memset(file, 0, sizeof(Profile)); if (!fp) return 1; if (!fverifystring(fp, "Do041220")) goto error; file->stage = fgetl(fp); file->songno = fgetl(fp); file->px = fgetl(fp); file->py = fgetl(fp); file->pdir = CVTDir(fgetl(fp)); file->maxhp = fgeti(fp); file->num_whimstars = fgeti(fp); file->hp = fgeti(fp); fgeti(fp); // unknown value curweaponslot = fgetl(fp); // current weapon (slot, not number, converted below) fgetl(fp); // unknown value file->equipmask = fgetl(fp); // equipped items // load weapons fseek(fp, PF_WEAPONS_OFFS, SEEK_SET); for(i=0;i<MAX_WPN_SLOTS;i++) { int level, xp, maxammo, ammo; int type = fgetl(fp); if (!type) break; level = fgetl(fp); xp = fgetl(fp); maxammo = fgetl(fp); ammo = fgetl(fp); file->weapons[type].hasWeapon = true; file->weapons[type].level = (level - 1); file->weapons[type].xp = xp; file->weapons[type].ammo = ammo; file->weapons[type].maxammo = maxammo; if (i == curweaponslot) file->curWeapon = type; } /* load inventory */ file->ninventory = 0; fseek(fp, PF_INVENTORY_OFFS, SEEK_SET); for(i=0;i<MAX_INVENTORY;i++) { int item = fgetl(fp); if (!item) break; file->inventory[file->ninventory++] = item; } /* load teleporter slots */ file->num_teleslots = 0; fseek(fp, PF_TELEPORTER_OFFS, SEEK_SET); for(i=0;i<NUM_TELEPORTER_SLOTS;i++) { int slotno = fgetl(fp); int scriptno = fgetl(fp); if (slotno == 0) break; file->teleslots[file->num_teleslots].slotno = slotno; file->teleslots[file->num_teleslots].scriptno = scriptno; file->num_teleslots++; } /* load flags */ fseek(fp, PF_FLAGS_OFFS, SEEK_SET); if (!fverifystring(fp, "FLAG")) { NX_ERR("profile_load: missing 'FLAG' marker\n"); goto error; } fresetboolean(); for(i=0;i<NUM_GAMEFLAGS;i++) file->flags[i] = fbooleanread(fp); fclose(fp); return 0; error: fclose(fp); return 1; }