bool pmd_load(const char *fname) { FILE *fp; int i, t; stat("----------------------"); stat("pmd_load: opening '%s'", fname); fp = fopen(fname, "rb"); if (!fp) { staterr("pmd_load: failed to open '%s'", fname); return 1; } if (!fverifystring(fp, "PMD")) { staterr("pmd_load: not a PMD file: '%s'", fname); fclose(fp); return 1; } fgetc(fp); // I dunno fgetl(fp); // I dunno song.ms_per_beat = fgetl(fp); // music wait song.loop_start = fgetl(fp); song.loop_end = fgetl(fp); song.nnotes = fgetl(fp); stat("song wait: %d (0x%04x)", song.ms_per_beat, song.ms_per_beat); stat("nnotes: %d (0x%04x)", song.nnotes, song.nnotes); stat("loop: %d-%d", song.loop_start, song.loop_end); // original PiyoPiyo and Ikachan seem to play things slightly slower than specified, // although PiyoPiyoPlayer plays it as spec'd in the file. if (strstr(fname, "Buriki")) song.ms_per_beat += 10; else song.ms_per_beat += 5; // load instrument samples for(i=0;i<NUM_TRACKS;i++) load_instrument(fp, &song.track[i].instrument); for(i=0;i<TOTAL_TRACKS;i++) song.track[i].no = i; // drum volume song.drum_volume = fgetl(fp); // load music notes for(t=0;t<TOTAL_TRACKS;t++) { stTrack *track = &song.track[t]; for(i=0;i<song.nnotes;i++) { uint32_t mask = fgetl(fp); track->note[i].notemask = (mask & 0xffffff); track->note[i].panning = (mask >> 24); if (!track->note[i].panning) track->note[i].panning = PAN_CENTER; else track->note[i].panning--; } } 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; }