/* * reads a polymodel structure from a PHYSFS_file */ extern void polymodel_read(polymodel *pm, PHYSFS_file *fp) { int i; pm->n_models = PHYSFSX_readInt(fp); pm->model_data_size = PHYSFSX_readInt(fp); pm->model_data = (ubyte *)(size_t)PHYSFSX_readInt(fp); // garbage, read it anyway just for consistency for (i = 0; i < MAX_SUBMODELS; i++) pm->submodel_ptrs[i] = PHYSFSX_readInt(fp); for (i = 0; i < MAX_SUBMODELS; i++) PHYSFSX_readVector(&(pm->submodel_offsets[i]), fp); for (i = 0; i < MAX_SUBMODELS; i++) PHYSFSX_readVector(&(pm->submodel_norms[i]), fp); for (i = 0; i < MAX_SUBMODELS; i++) PHYSFSX_readVector(&(pm->submodel_pnts[i]), fp); for (i = 0; i < MAX_SUBMODELS; i++) pm->submodel_rads[i] = PHYSFSX_readFix(fp); PHYSFS_read(fp, pm->submodel_parents, MAX_SUBMODELS, 1); for (i = 0; i < MAX_SUBMODELS; i++) PHYSFSX_readVector(&(pm->submodel_mins[i]), fp); for (i = 0; i < MAX_SUBMODELS; i++) PHYSFSX_readVector(&(pm->submodel_maxs[i]), fp); PHYSFSX_readVector(&(pm->mins), fp); PHYSFSX_readVector(&(pm->maxs), fp); pm->rad = PHYSFSX_readFix(fp); pm->n_textures = PHYSFSX_readByte(fp); pm->first_texture = PHYSFSX_readShort(fp); pm->simpler_model = PHYSFSX_readByte(fp); }
/* * reads a DiskSoundHeader structure from a PHYSFS_file */ void DiskSoundHeader_read(DiskSoundHeader *dsh, PHYSFS_file *fp) { PHYSFS_read(fp, dsh->name, 8, 1); dsh->length = PHYSFSX_readInt(fp); dsh->data_length = PHYSFSX_readInt(fp); dsh->offset = PHYSFSX_readInt(fp); }
/* * reads n polymodel structs from a PHYSFS_file */ extern int polymodel_read_n(polymodel *pm, int n, PHYSFS_file *fp) { int i, j; for (i = 0; i < n; i++) { pm[i].n_models = PHYSFSX_readInt(fp); pm[i].model_data_size = PHYSFSX_readInt(fp); pm[i].model_data = (ubyte *) (size_t)PHYSFSX_readInt(fp); for (j = 0; j < MAX_SUBMODELS; j++) pm[i].submodel_ptrs[j] = PHYSFSX_readInt(fp); for (j = 0; j < MAX_SUBMODELS; j++) PHYSFSX_readVector(&(pm[i].submodel_offsets[j]), fp); for (j = 0; j < MAX_SUBMODELS; j++) PHYSFSX_readVector(&(pm[i].submodel_norms[j]), fp); for (j = 0; j < MAX_SUBMODELS; j++) PHYSFSX_readVector(&(pm[i].submodel_pnts[j]), fp); for (j = 0; j < MAX_SUBMODELS; j++) pm[i].submodel_rads[j] = PHYSFSX_readFix(fp); PHYSFS_read(fp, pm[i].submodel_parents, MAX_SUBMODELS, 1); for (j = 0; j < MAX_SUBMODELS; j++) PHYSFSX_readVector(&(pm[i].submodel_mins[j]), fp); for (j = 0; j < MAX_SUBMODELS; j++) PHYSFSX_readVector(&(pm[i].submodel_maxs[j]), fp); PHYSFSX_readVector(&(pm[i].mins), fp); PHYSFSX_readVector(&(pm[i].maxs), fp); pm[i].rad = PHYSFSX_readFix(fp); pm[i].n_textures = PHYSFSX_readByte(fp); pm[i].first_texture = PHYSFSX_readShort(fp); pm[i].simpler_model = PHYSFSX_readByte(fp); } return i; }
void load_hostage_data(PHYSFS_file * fp,int do_read) { int version,i,num,num_hostages; hostage_init_all(); num_hostages = 0; // Find number of hostages in mine... for (i=0; i<=Highest_object_index; i++ ) { if ( Objects[i].type == OBJ_HOSTAGE ) { num = Objects[i].id; if (num+1 > num_hostages) num_hostages = num+1; if (Hostages[num].objnum != -1) { //slot already used num = hostage_get_next_slot(); //..so get new slot if (num+1 > num_hostages) num_hostages = num+1; Objects[i].id = num; } if ( num > -1 && num < MAX_HOSTAGES ) { Assert(Hostages[num].objnum == -1); //make sure not used // -- Matt -- commented out by MK on 11/19/94, hit often in level 3, level 4. Assert(Hostages[num].objnum == -1); //make sure not used Hostages[num].objnum = i; Hostages[num].objsig = Objects[i].signature; } } } if (do_read) { version = PHYSFSX_readInt(fp); for (i=0;i<num_hostages;i++) { Assert(Hostages[i].objnum != -1); //make sure slot filled in Hostages[i].vclip_num = PHYSFSX_readInt(fp); #ifndef SHAREWARE if (Hostages[i].vclip_num<0 || Hostages[i].vclip_num>=MAX_HOSTAGES || Hostage_face_clip[Hostages[i].vclip_num].num_frames<=0) Hostages[i].vclip_num=0; Assert(Hostage_face_clip[Hostages[i].vclip_num].num_frames); #endif PHYSFSX_fgets(Hostages[i].text, HOSTAGE_MESSAGE_LEN, fp); } } else for (i=0;i<num_hostages;i++) { Assert(Hostages[i].objnum != -1); //make sure slot filled in Hostages[i].vclip_num = 0; } }
/* * reads n powerup_type_info structs from a PHYSFS_file */ int powerup_type_info_read_n(powerup_type_info *pti, int n, PHYSFS_file *fp) { int i; for (i = 0; i < n; i++) { pti[i].vclip_num = PHYSFSX_readInt(fp); pti[i].hit_sound = PHYSFSX_readInt(fp); pti[i].size = PHYSFSX_readFix(fp); pti[i].light = PHYSFSX_readFix(fp); } return i; }
/* * reads a v19_wall structure from a PHYSFS_file */ extern void v19_wall_read(v19_wall *w, PHYSFS_file *fp) { w->segnum = PHYSFSX_readInt(fp); w->sidenum = PHYSFSX_readInt(fp); w->type = PHYSFSX_readByte(fp); w->flags = PHYSFSX_readByte(fp); w->hps = PHYSFSX_readFix(fp); w->trigger = PHYSFSX_readByte(fp); w->clip_num = PHYSFSX_readByte(fp); w->keys = PHYSFSX_readByte(fp); w->linked_wall = PHYSFSX_readInt(fp); }
void player_ship_read(player_ship *ps, PHYSFS_file *fp) { int i; ps->model_num = PHYSFSX_readInt(fp); ps->expl_vclip_num = PHYSFSX_readInt(fp); ps->mass = PHYSFSX_readFix(fp); ps->drag = PHYSFSX_readFix(fp); ps->max_thrust = PHYSFSX_readFix(fp); ps->reverse_thrust = PHYSFSX_readFix(fp); ps->brakes = PHYSFSX_readFix(fp); ps->wiggle = PHYSFSX_readFix(fp); ps->max_rotthrust = PHYSFSX_readFix(fp); for (i = 0; i < N_PLAYER_GUNS; i++) PHYSFSX_readVector(&ps->gun_points[i], fp); }
/* * reads a wall structure from a PHYSFS_file */ extern void wall_read(wall *w, PHYSFS_file *fp) { w->segnum = PHYSFSX_readInt(fp); w->sidenum = PHYSFSX_readInt(fp); w->hps = PHYSFSX_readFix(fp); w->linked_wall = PHYSFSX_readInt(fp); w->type = PHYSFSX_readByte(fp); w->flags = PHYSFSX_readByte(fp); w->state = PHYSFSX_readByte(fp); w->trigger = PHYSFSX_readByte(fp); w->clip_num = PHYSFSX_readByte(fp); w->keys = PHYSFSX_readByte(fp); w->controlling_trigger = PHYSFSX_readByte(fp); w->cloak_value = PHYSFSX_readByte(fp); }
static void tmap_info_read(tmap_info &ti, PHYSFS_File *fp) { PHYSFS_read(fp, ti.filename, 13, 1); ti.flags = PHYSFSX_readByte(fp); ti.lighting = PHYSFSX_readFix(fp); ti.damage = PHYSFSX_readFix(fp); ti.eclip_num = PHYSFSX_readInt(fp); }
/* * reads an active_door structure from a PHYSFS_file */ extern void active_door_read(active_door *ad, PHYSFS_file *fp) { ad->n_parts = PHYSFSX_readInt(fp); ad->front_wallnum[0] = PHYSFSX_readShort(fp); ad->front_wallnum[1] = PHYSFSX_readShort(fp); ad->back_wallnum[0] = PHYSFSX_readShort(fp); ad->back_wallnum[1] = PHYSFSX_readShort(fp); ad->time = PHYSFSX_readFix(fp); }
/* * reads a DiskBitmapHeader structure from a PHYSFS_file */ void DiskBitmapHeader_read(DiskBitmapHeader *dbh, PHYSFS_file *fp) { PHYSFS_read(fp, dbh->name, 8, 1); dbh->dflags = PHYSFSX_readByte(fp); dbh->width = PHYSFSX_readByte(fp); dbh->height = PHYSFSX_readByte(fp); dbh->flags = PHYSFSX_readByte(fp); dbh->avg_color = PHYSFSX_readByte(fp); dbh->offset = PHYSFSX_readInt(fp); }
/* * reads a v19_door structure from a PHYSFS_file */ extern void v19_door_read(v19_door *d, PHYSFS_file *fp) { d->n_parts = PHYSFSX_readInt(fp); d->seg[0] = PHYSFSX_readShort(fp); d->seg[1] = PHYSFSX_readShort(fp); d->side[0] = PHYSFSX_readShort(fp); d->side[1] = PHYSFSX_readShort(fp); d->type[0] = PHYSFSX_readShort(fp); d->type[1] = PHYSFSX_readShort(fp); d->open = PHYSFSX_readFix(fp); }
/* * reads n eclip structs from a PHYSFS_file */ int eclip_read_n(eclip *ec, int n, PHYSFS_file *fp) { int i; for (i = 0; i < n; i++) { vclip_read_n(&ec[i].vc, 1, fp); ec[i].time_left = PHYSFSX_readFix(fp); ec[i].frame_count = PHYSFSX_readInt(fp); ec[i].changing_wall_texture = PHYSFSX_readShort(fp); ec[i].changing_object_texture = PHYSFSX_readShort(fp); ec[i].flags = PHYSFSX_readInt(fp); ec[i].crit_clip = PHYSFSX_readInt(fp); ec[i].dest_bm_num = PHYSFSX_readInt(fp); ec[i].dest_vclip = PHYSFSX_readInt(fp); ec[i].dest_eclip = PHYSFSX_readInt(fp); ec[i].dest_size = PHYSFSX_readFix(fp); ec[i].sound_num = PHYSFSX_readInt(fp); ec[i].segnum = (segnum_t)PHYSFSX_readInt(fp); ec[i].sidenum = PHYSFSX_readInt(fp); } return i; }
void bm_read_all(PHYSFS_File * fp) { unsigned t; NumTextures = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, partial_range(Textures, NumTextures)); range_for (tmap_info &ti, partial_range(TmapInfo, NumTextures)) tmap_info_read(ti, fp); t = PHYSFSX_readInt(fp); PHYSFS_read( fp, Sounds, sizeof(ubyte), t ); PHYSFS_read( fp, AltSounds, sizeof(ubyte), t ); Num_vclips = PHYSFSX_readInt(fp); range_for (vclip &vc, partial_range(Vclip, Num_vclips)) vclip_read(fp, vc); Num_effects = PHYSFSX_readInt(fp); range_for (eclip &ec, partial_range(Effects, Num_effects)) eclip_read(fp, ec); Num_wall_anims = PHYSFSX_readInt(fp); range_for (auto &w, partial_range(WallAnims, Num_wall_anims)) wclip_read(fp, w); N_robot_types = PHYSFSX_readInt(fp); range_for (auto &r, partial_range(Robot_info, N_robot_types)) robot_info_read(fp, r); N_robot_joints = PHYSFSX_readInt(fp); range_for (auto &r, partial_range(Robot_joints, N_robot_joints)) jointpos_read(fp, r); N_weapon_types = PHYSFSX_readInt(fp); weapon_info_read_n(Weapon_info, N_weapon_types, fp, Piggy_hamfile_version); N_powerup_types = PHYSFSX_readInt(fp); range_for (auto &p, partial_range(Powerup_info, N_powerup_types)) powerup_type_info_read(fp, p); N_polygon_models = PHYSFSX_readInt(fp); { const auto &&r = partial_range(Polygon_models, N_polygon_models); range_for (auto &p, r) polymodel_read(&p, fp); range_for (auto &p, r) polygon_model_data_read(&p, fp); } range_for (auto &i, partial_range(Dying_modelnums, N_polygon_models)) i = PHYSFSX_readInt(fp); range_for (auto &i, partial_range(Dead_modelnums, N_polygon_models)) i = PHYSFSX_readInt(fp); t = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, partial_range(Gauges, t)); bitmap_index_read_n(fp, partial_range(Gauges_hires, t)); N_ObjBitmaps = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, partial_range(ObjBitmaps, N_ObjBitmaps)); range_for (auto &i, partial_range(ObjBitmapPtrs, N_ObjBitmaps)) i = PHYSFSX_readShort(fp); player_ship_read(&only_player_ship, fp); Num_cockpits = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, partial_range(cockpit_bitmap, Num_cockpits)); //@@ PHYSFS_read( fp, &Num_total_object_types, sizeof(int), 1 ); //@@ PHYSFS_read( fp, ObjType, sizeof(byte), Num_total_object_types ); //@@ PHYSFS_read( fp, ObjId, sizeof(byte), Num_total_object_types ); //@@ PHYSFS_read( fp, ObjStrength, sizeof(fix), Num_total_object_types ); First_multi_bitmap_num = PHYSFSX_readInt(fp); Num_reactors = PHYSFSX_readInt(fp); reactor_read_n(fp, partial_range(Reactors, Num_reactors)); Marker_model_num = PHYSFSX_readInt(fp); //@@PHYSFS_read( fp, &N_controlcen_guns, sizeof(int), 1 ); //@@PHYSFS_read( fp, controlcen_gun_points, sizeof(vms_vector), N_controlcen_guns ); //@@PHYSFS_read( fp, controlcen_gun_dirs, sizeof(vms_vector), N_controlcen_guns ); if (Piggy_hamfile_version < 3) { exit_modelnum = PHYSFSX_readInt(fp); destroyed_exit_modelnum = PHYSFSX_readInt(fp); } else exit_modelnum = destroyed_exit_modelnum = N_polygon_models; }
// Read compiled properties data from descent.pig void properties_read_cmp(PHYSFS_File * fp) { // bitmap_index is a short NumTextures = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, Textures); range_for (tmap_info &ti, TmapInfo) tmap_info_read(ti, fp); PHYSFS_read(fp, Sounds, sizeof(Sounds[0]), Sounds.size()); PHYSFS_read(fp, AltSounds, sizeof(AltSounds[0]), AltSounds.size()); Num_vclips = PHYSFSX_readInt(fp); range_for (vclip &vc, Vclip) vclip_read(fp, vc); Num_effects = PHYSFSX_readInt(fp); range_for (eclip &ec, Effects) eclip_read(fp, ec); Num_wall_anims = PHYSFSX_readInt(fp); range_for (auto &w, WallAnims) wclip_read(fp, w); N_robot_types = PHYSFSX_readInt(fp); range_for (auto &r, Robot_info) robot_info_read(fp, r); N_robot_joints = PHYSFSX_readInt(fp); range_for (auto &r, Robot_joints) jointpos_read(fp, r); N_weapon_types = PHYSFSX_readInt(fp); weapon_info_read_n(Weapon_info, MAX_WEAPON_TYPES, fp, 0); N_powerup_types = PHYSFSX_readInt(fp); range_for (auto &p, Powerup_info) powerup_type_info_read(fp, p); N_polygon_models = PHYSFSX_readInt(fp); { const auto &&r = partial_range(Polygon_models, N_polygon_models); range_for (auto &p, r) polymodel_read(&p, fp); range_for (auto &p, r) polygon_model_data_read(&p, fp); } bitmap_index_read_n(fp, partial_range(Gauges, MAX_GAUGE_BMS)); range_for (auto &i, Dying_modelnums) i = PHYSFSX_readInt(fp); range_for (auto &i, Dead_modelnums) i = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, ObjBitmaps); range_for (auto &i, ObjBitmapPtrs) i = PHYSFSX_readShort(fp); player_ship_read(&only_player_ship, fp); Num_cockpits = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, cockpit_bitmap); PHYSFS_read(fp, Sounds, sizeof(Sounds[0]), Sounds.size()); PHYSFS_read(fp, AltSounds, sizeof(AltSounds[0]), AltSounds.size()); Num_total_object_types = PHYSFSX_readInt(fp); PHYSFS_read( fp, ObjType, sizeof(ubyte), MAX_OBJTYPE ); PHYSFS_read( fp, ObjId, sizeof(ubyte), MAX_OBJTYPE ); range_for (auto &i, ObjStrength) i = PHYSFSX_readFix(fp); First_multi_bitmap_num = PHYSFSX_readInt(fp); Reactors[0].n_guns = PHYSFSX_readInt(fp); range_for (auto &i, Reactors[0].gun_points) PHYSFSX_readVector(fp, i); range_for (auto &i, Reactors[0].gun_dirs) PHYSFSX_readVector(fp, i); exit_modelnum = PHYSFSX_readInt(fp); destroyed_exit_modelnum = PHYSFSX_readInt(fp); #if DXX_USE_EDITOR //Build tmaplist auto &&effect_range = partial_const_range(Effects, Num_effects); Num_tmaps = TextureEffects + std::count_if(effect_range.begin(), effect_range.end(), [](const eclip &e) { return e.changing_wall_texture >= 0; }); #endif }
//read in the player's saved games. returns errno (0 == no error) int read_player_file() { char filename[PATH_MAX]; PHYSFS_file *file; int player_file_size, shareware_file = -1, id = 0; short saved_game_version, player_struct_version; Assert(Player_num>=0 && Player_num<MAX_PLAYERS); memset(filename, '\0', PATH_MAX); snprintf(filename, PATH_MAX, GameArg.SysUsePlayersDir? "Players/%.8s.plr" : "%.8s.plr", Players[Player_num].callsign); if (!PHYSFSX_exists(filename,0)) return ENOENT; file = PHYSFSX_openReadBuffered(filename); if (!file) goto read_player_file_failed; new_player_config(); // Set defaults! // Unfortunatly d1x has been writing both shareware and registered // player files with a saved_game_version of 7 and 8, whereas the // original decent used 4 for shareware games and 7 for registered // games. Because of this the player files didn't get properly read // when reading d1x shareware player files in d1x registered or // vica versa. The problem is that the sizeof of the taunt macros // differ between the share and registered versions, causing the // reading of the player file to go wrong. Thus we now determine the // sizeof the player file to determine what kinda player file we are // dealing with so that we can do the right thing PHYSFS_seek(file, 0); player_file_size = PHYSFS_fileLength(file); PHYSFS_readSLE32(file, &id); saved_game_version = PHYSFSX_readShort(file); player_struct_version = PHYSFSX_readShort(file); PlayerCfg.NHighestLevels = PHYSFSX_readInt(file); PlayerCfg.DefaultDifficulty = PHYSFSX_readInt(file); PlayerCfg.AutoLeveling = PHYSFSX_readInt(file); if (id!=SAVE_FILE_ID) { nm_messagebox(TXT_ERROR, 1, TXT_OK, "Invalid player file"); PHYSFS_close(file); return -1; } if (saved_game_version<COMPATIBLE_SAVED_GAME_VERSION || player_struct_version<COMPATIBLE_PLAYER_STRUCT_VERSION) { nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_ERROR_PLR_VERSION); PHYSFS_close(file); return -1; } /* determine if we're dealing with a shareware or registered playerfile */ switch (saved_game_version) { case 4: shareware_file = 1; break; case 5: case 6: shareware_file = 0; break; case 7: /* version 7 doesn't have the saved games array */ if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 - sizeof(saved_games))) shareware_file = 1; if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 - sizeof(saved_games))) shareware_file = 0; break; case 8: if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2212) shareware_file = 1; if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2252) shareware_file = 0; /* d1x-rebirth v0.31 to v0.42 broke things by adding stuff to the player struct without thinking (sigh) */ if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 + 2*sizeof(int))) { shareware_file = 1; /* skip the cruft added to the player_info struct */ PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int)); } if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 + 2*sizeof(int))) { shareware_file = 0; /* skip the cruft added to the player_info struct */ PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int)); } } if (shareware_file == -1) { nm_messagebox(TXT_ERROR, 1, TXT_OK, "Error invalid or unknown\nplayerfile-size"); PHYSFS_close(file); return -1; } if (saved_game_version <= 5) { //deal with old-style highest level info PlayerCfg.HighestLevels[0].Shortname[0] = 0; //no name for mission 0 PlayerCfg.HighestLevels[0].LevelNum = PlayerCfg.NHighestLevels; //was highest level in old struct //This hack allows the player to start on level 8 if he's made it to //level 7 on the shareware. We do this because the shareware didn't //save the information that the player finished level 7, so the most //we know is that he made it to level 7. if (PlayerCfg.NHighestLevels==7) PlayerCfg.HighestLevels[0].LevelNum = 8; } else { //read new highest level info if (PHYSFS_read(file,PlayerCfg.HighestLevels,sizeof(hli),PlayerCfg.NHighestLevels) != PlayerCfg.NHighestLevels) goto read_player_file_failed; } if ( saved_game_version != 7 ) { // Read old & SW saved games. if (PHYSFS_read(file,saved_games,sizeof(saved_games),1) != 1) goto read_player_file_failed; } //read taunt macros { int i; int len = shareware_file? 25:35; #ifdef NETWORK for (i = 0; i < 4; i++) if (PHYSFS_read(file, PlayerCfg.NetworkMessageMacro[i], len, 1) != 1) goto read_player_file_failed; #else i = 0; PHYSFS_seek( file, PHYSFS_tell(file)+4*len ); #endif } //read kconfig data { ubyte dummy_joy_sens; if (PHYSFS_read(file, &PlayerCfg.KeySettings[0], sizeof(PlayerCfg.KeySettings[0]),1)!=1) goto read_player_file_failed; if (PHYSFS_read(file, &PlayerCfg.KeySettings[1], sizeof(PlayerCfg.KeySettings[1]),1)!=1) goto read_player_file_failed; PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS*3) ); // Skip obsolete Flightstick/Thrustmaster/Gravis map fields if (PHYSFS_read(file, &PlayerCfg.KeySettings[2], sizeof(PlayerCfg.KeySettings[2]),1)!=1) goto read_player_file_failed; PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS) ); // Skip obsolete Cyberman map field if (PHYSFS_read(file, &PlayerCfg.ControlType, sizeof(ubyte), 1 )!=1) goto read_player_file_failed; else if (PHYSFS_read(file, &dummy_joy_sens, sizeof(ubyte), 1 )!=1) goto read_player_file_failed; } if ( saved_game_version != 7 ) { int i, found=0; Assert( N_SAVE_SLOTS == 10 ); for (i=0; i<N_SAVE_SLOTS; i++ ) { if ( saved_games[i].name[0] ) { state_save_old_game(i, saved_games[i].name, &saved_games[i].sg_player, saved_games[i].difficulty_level, saved_games[i].primary_weapon, saved_games[i].secondary_weapon, saved_games[i].next_level_num ); // make sure we do not do this again, which would possibly overwrite // a new newstyle savegame saved_games[i].name[0] = 0; found++; } } if (found) write_player_file(); } if (!PHYSFS_close(file)) goto read_player_file_failed; filename[strlen(filename) - 4] = 0; strcat(filename, ".plx"); read_player_d1x(filename); kc_set_controls(); return EZERO; read_player_file_failed: nm_messagebox(TXT_ERROR, 1, TXT_OK, "%s\n\n%s", "Error reading PLR file", PHYSFS_getLastError()); if (file) PHYSFS_close(file); return -1; }
//type==1 means 1.1, type==2 means 1.2 (with weapons) void bm_read_extra_robots(char *fname,int type) { PHYSFS_file *fp; int t,i,version; fp = PHYSFSX_openReadBuffered(fname); if (!fp) { Error("Failed to open HAM file \"%s\"", fname); return; } if (type == 2) { int sig; sig = PHYSFSX_readInt(fp); if (sig != MAKE_SIG('X','H','A','M')) return; version = PHYSFSX_readInt(fp); } else version = 0; (void)version; // NOTE: we do not need it, but keep it for possible further use bm_free_extra_models(); bm_free_extra_objbitmaps(); //read extra weapons t = PHYSFSX_readInt(fp); N_weapon_types = N_D2_WEAPON_TYPES+t; if (N_weapon_types >= MAX_WEAPON_TYPES) Error("Too many weapons (%d) in <%s>. Max is %d.",t,fname,MAX_WEAPON_TYPES-N_D2_WEAPON_TYPES); weapon_info_read_n(&Weapon_info[N_D2_WEAPON_TYPES], t, fp, 3); //now read robot info t = PHYSFSX_readInt(fp); N_robot_types = N_D2_ROBOT_TYPES+t; if (N_robot_types >= MAX_ROBOT_TYPES) Error("Too many robots (%d) in <%s>. Max is %d.",t,fname,MAX_ROBOT_TYPES-N_D2_ROBOT_TYPES); robot_info_read_n(&Robot_info[N_D2_ROBOT_TYPES], t, fp); t = PHYSFSX_readInt(fp); N_robot_joints = N_D2_ROBOT_JOINTS+t; if (N_robot_joints >= MAX_ROBOT_JOINTS) Error("Too many robot joints (%d) in <%s>. Max is %d.",t,fname,MAX_ROBOT_JOINTS-N_D2_ROBOT_JOINTS); jointpos_read_n(&Robot_joints[N_D2_ROBOT_JOINTS], t, fp); t = PHYSFSX_readInt(fp); N_polygon_models = N_D2_POLYGON_MODELS+t; if (N_polygon_models >= MAX_POLYGON_MODELS) Error("Too many polygon models (%d) in <%s>. Max is %d.",t,fname,MAX_POLYGON_MODELS-N_D2_POLYGON_MODELS); polymodel_read_n(&Polygon_models[N_D2_POLYGON_MODELS], t, fp); for (i=N_D2_POLYGON_MODELS; i<N_polygon_models; i++ ) polygon_model_data_read(&Polygon_models[i], fp); for (i = N_D2_POLYGON_MODELS; i < N_polygon_models; i++) Dying_modelnums[i] = PHYSFSX_readInt(fp); for (i = N_D2_POLYGON_MODELS; i < N_polygon_models; i++) Dead_modelnums[i] = PHYSFSX_readInt(fp); t = PHYSFSX_readInt(fp); if (N_D2_OBJBITMAPS+t >= MAX_OBJ_BITMAPS) Error("Too many object bitmaps (%d) in <%s>. Max is %d.",t,fname,MAX_OBJ_BITMAPS-N_D2_OBJBITMAPS); bitmap_index_read_n(&ObjBitmaps[N_D2_OBJBITMAPS], t, fp); t = PHYSFSX_readInt(fp); if (N_D2_OBJBITMAPPTRS+t >= MAX_OBJ_BITMAPS) Error("Too many object bitmap pointers (%d) in <%s>. Max is %d.",t,fname,MAX_OBJ_BITMAPS-N_D2_OBJBITMAPPTRS); for (i = N_D2_OBJBITMAPPTRS; i < (N_D2_OBJBITMAPPTRS + t); i++) ObjBitmapPtrs[i] = PHYSFSX_readShort(fp); PHYSFS_close(fp); }
int properties_init() { int sbytes = 0; char temp_name_read[16]; char temp_name[16]; grs_bitmap temp_bitmap; digi_sound temp_sound; DiskBitmapHeader bmh; DiskSoundHeader sndh; int header_size, N_bitmaps, N_sounds; int i,size; int Pigdata_start; int pigsize; int retval; hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES ); hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES ); for (i=0; i<MAX_SOUND_FILES; i++ ) { #ifdef ALLEGRO GameSounds[i].len = 0; #else GameSounds[i].length = 0; #endif GameSounds[i].data = NULL; SoundOffset[i] = 0; //added on 11/13/99 by Victor Rachels to ready for changing freq GameSounds[i].bits = 0; GameSounds[i].freq = 0; //end this section addition - VR } for (i=0; i<MAX_BITMAP_FILES; i++ ) { GameBitmapXlat[i] = i; GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT; } if ( !bogus_bitmap_initialized ) { int i; ubyte c; bogus_bitmap_initialized = 1; c = gr_find_closest_color( 0, 0, 63 ); for (i=0; i<4096; i++ ) bogus_data[i] = c; c = gr_find_closest_color( 63, 0, 0 ); // Make a big red X ! for (i=0; i<64; i++ ) { bogus_data[i*64+i] = c; bogus_data[i*64+(63-i)] = c; } gr_init_bitmap (&bogus_bitmap, 0, 0, 0, 64, 64, 64, bogus_data); piggy_register_bitmap( &bogus_bitmap, "bogus", 1 ); #ifdef ALLEGRO bogus_sound.len = 64*64; #else bogus_sound.length = 64*64; #endif bogus_sound.data = bogus_data; //added on 11/13/99 by Victor Rachels to ready for changing freq bogus_sound.freq = 11025; bogus_sound.bits = 8; //end this section addition - VR GameBitmapOffset[0] = 0; } Piggy_fp = PHYSFSX_openReadBuffered(DEFAULT_PIGFILE_REGISTERED); if (Piggy_fp==NULL) { if (!PHYSFSX_exists("BITMAPS.TBL",1) && !PHYSFSX_exists("BITMAPS.BIN",1)) Error("Cannot find " DEFAULT_PIGFILE_REGISTERED " or BITMAPS.TBL"); return 1; // need to run gamedata_read_tbl } pigsize = PHYSFS_fileLength(Piggy_fp); switch (pigsize) { case D1_SHARE_BIG_PIGSIZE: case D1_SHARE_10_PIGSIZE: case D1_SHARE_PIGSIZE: PCSharePig = 1; Pigdata_start = 0; break; case D1_10_BIG_PIGSIZE: case D1_10_PIGSIZE: Pigdata_start = 0; break; default: Warning("Unknown size for " DEFAULT_PIGFILE_REGISTERED); Int3(); // fall through case D1_MAC_PIGSIZE: case D1_MAC_SHARE_PIGSIZE: MacPig = 1; case D1_PIGSIZE: case D1_OEM_PIGSIZE: Pigdata_start = PHYSFSX_readInt(Piggy_fp ); break; } HiresGFXAvailable = MacPig; // for now at least if (PCSharePig) retval = PIGGY_PC_SHAREWARE; // run gamedata_read_tbl in shareware mode else if (GameArg.EdiNoBm || (!PHYSFSX_exists("BITMAPS.TBL",1) && !PHYSFSX_exists("BITMAPS.BIN",1))) { properties_read_cmp( Piggy_fp ); // Note connection to above if!!! for (i = 0; i < MAX_BITMAP_FILES; i++) { GameBitmapXlat[i] = PHYSFSX_readShort(Piggy_fp); if (PHYSFS_eof(Piggy_fp)) break; } retval = 0; // don't run gamedata_read_tbl } else retval = 1; // run gamedata_read_tbl PHYSFSX_fseek( Piggy_fp, Pigdata_start, SEEK_SET ); size = PHYSFS_fileLength(Piggy_fp) - Pigdata_start; N_bitmaps = PHYSFSX_readInt(Piggy_fp); size -= sizeof(int); N_sounds = PHYSFSX_readInt(Piggy_fp); size -= sizeof(int); header_size = (N_bitmaps*sizeof(DiskBitmapHeader)) + (N_sounds*sizeof(DiskSoundHeader)); for (i=0; i<N_bitmaps; i++ ) { DiskBitmapHeader_read(&bmh, Piggy_fp); GameBitmapFlags[i+1] = 0; if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT; if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT; if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING; if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE; GameBitmapOffset[i+1] = bmh.offset + header_size + (sizeof(int)*2) + Pigdata_start; Assert( (i+1) == Num_bitmap_files ); //size -= sizeof(DiskBitmapHeader); memcpy( temp_name_read, bmh.name, 8 ); temp_name_read[8] = 0; if ( bmh.dflags & DBM_FLAG_ABM ) sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 ); else strcpy( temp_name, temp_name_read ); memset( &temp_bitmap, 0, sizeof(grs_bitmap) ); gr_init_bitmap( &temp_bitmap, 0, 0, 0, (bmh.dflags & DBM_FLAG_LARGE) ? bmh.width + 256 : bmh.width, bmh.height, (bmh.dflags & DBM_FLAG_LARGE) ? bmh.width + 256 : bmh.width, Piggy_bitmap_cache_data); temp_bitmap.bm_flags |= BM_FLAG_PAGED_OUT; temp_bitmap.avg_color = bmh.avg_color; if (MacPig) { // HACK HACK HACK!!!!! if (!strnicmp(bmh.name, "cockpit", 7) || !strnicmp(bmh.name, "status", 6) || !strnicmp(bmh.name, "rearview", 8)) { temp_bitmap.bm_w = temp_bitmap.bm_rowsize = 640; if (GameBitmapFlags[i+1] & BM_FLAG_RLE) GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG; } if (!strnicmp(bmh.name, "cockpit", 7) || !strnicmp(bmh.name, "rearview", 8)) temp_bitmap.bm_h = 480; } piggy_register_bitmap( &temp_bitmap, temp_name, 1 ); } for (i=0; !MacPig && i<N_sounds; i++ ) { DiskSoundHeader_read(&sndh, Piggy_fp); //size -= sizeof(DiskSoundHeader); #ifdef ALLEGRO temp_sound.len = sndh.length; #else temp_sound.length = sndh.length; #endif //added on 11/13/99 by Victor Rachels to ready for changing freq temp_sound.bits = 8; temp_sound.freq = 11025; //end this section addition - VR temp_sound.data = (ubyte *)(sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start); SoundOffset[Num_sound_files] = sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start; if (PCSharePig) SoundCompressed[Num_sound_files] = sndh.data_length; memcpy( temp_name_read, sndh.name, 8 ); temp_name_read[8] = 0; piggy_register_sound( &temp_sound, temp_name_read, 1 ); sbytes += sndh.length; } if (!MacPig) { SoundBits = d_malloc( sbytes + 16 ); if ( SoundBits == NULL ) Error( "Not enough memory to load DESCENT.PIG sounds\n"); } #if 1 //def EDITOR Piggy_bitmap_cache_size = size - header_size - sbytes + 16; Assert( Piggy_bitmap_cache_size > 0 ); #else Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE; if (GameArg.SysLowMem) Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE; #endif BitmapBits = d_malloc( Piggy_bitmap_cache_size ); if ( BitmapBits == NULL ) Error( "Not enough memory to load DESCENT.PIG bitmaps\n" ); Piggy_bitmap_cache_data = BitmapBits; Piggy_bitmap_cache_next = 0; return retval; }
int load_mine_data_compiled(PHYSFS_file *LoadFile) { int i, segnum, sidenum; ubyte compiled_version; short temp_short; ushort temp_ushort = 0; ubyte bit_mask; d1_pig_present = PHYSFSX_exists(D1_PIGFILE,1); #if 0 // the following will be deleted once reading old pigfiles works reliably if (d1_pig_present) { PHYSFS_file * d1_Piggy_fp = PHYSFSX_openReadBuffered( D1_PIGFILE ); switch (PHYSFS_fileLength(d1_Piggy_fp)) { case D1_SHARE_BIG_PIGSIZE: case D1_SHARE_10_PIGSIZE: case D1_SHARE_PIGSIZE: case D1_10_BIG_PIGSIZE: case D1_10_PIGSIZE: //d1_pig_present = 0; } PHYSFS_close (d1_Piggy_fp); } #endif if (!strcmp(strchr(Gamesave_current_filename, '.'), ".sdl")) New_file_format_load = 0; // descent 1 shareware else New_file_format_load = 1; // For compiled levels, textures map to themselves, prevent tmap_override always being gray, // bug which Matt and John refused to acknowledge, so here is Mike, fixing it. #ifdef EDITOR for (i=0; i<MAX_TEXTURES; i++) tmap_xlate_table[i] = i; #endif // memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS ); fuelcen_reset(); //=============================== Reading part ============================== compiled_version = PHYSFSX_readByte(LoadFile); (void)compiled_version; if (New_file_format_load) Num_vertices = PHYSFSX_readShort(LoadFile); else Num_vertices = PHYSFSX_readInt(LoadFile); Assert( Num_vertices <= MAX_VERTICES ); if (New_file_format_load) Num_segments = PHYSFSX_readShort(LoadFile); else Num_segments = PHYSFSX_readInt(LoadFile); Assert( Num_segments <= MAX_SEGMENTS ); for (i = 0; i < Num_vertices; i++) PHYSFSX_readVector( &(Vertices[i]), LoadFile); for (segnum=0; segnum<Num_segments; segnum++ ) { #ifdef EDITOR Segments[segnum].segnum = segnum; Segments[segnum].group = 0; #endif if (New_file_format_load) bit_mask = PHYSFSX_readByte(LoadFile); else bit_mask = 0x7f; // read all six children and special stuff... if (Gamesave_current_version == 5) { // d2 SHAREWARE level read_special(segnum,bit_mask,LoadFile); read_verts(segnum,LoadFile); read_children(segnum,bit_mask,LoadFile); } else { read_children(segnum,bit_mask,LoadFile); read_verts(segnum,LoadFile); if (Gamesave_current_version <= 1) { // descent 1 level read_special(segnum,bit_mask,LoadFile); } } Segments[segnum].objects = -1; if (Gamesave_current_version <= 5) { // descent 1 thru d2 SHAREWARE level // Read fix Segments[segnum].static_light (shift down 5 bits, write as short) temp_ushort = PHYSFSX_readShort(LoadFile); Segment2s[segnum].static_light = ((fix)temp_ushort) << 4; //PHYSFS_read( LoadFile, &Segments[segnum].static_light, sizeof(fix), 1 ); } // Read the walls as a 6 byte array for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { Segments[segnum].sides[sidenum].pad = 0; } if (New_file_format_load) bit_mask = PHYSFSX_readByte(LoadFile); else bit_mask = 0x3f; // read all six sides for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) { ubyte byte_wallnum; if (bit_mask & (1 << sidenum)) { byte_wallnum = PHYSFSX_readByte(LoadFile); if ( byte_wallnum == 255 ) Segments[segnum].sides[sidenum].wall_num = -1; else Segments[segnum].sides[sidenum].wall_num = byte_wallnum; } else Segments[segnum].sides[sidenum].wall_num = -1; } for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) ) { // Read short Segments[segnum].sides[sidenum].tmap_num; if (New_file_format_load) { temp_ushort = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff; } else Segments[segnum].sides[sidenum].tmap_num = PHYSFSX_readShort(LoadFile); if (Gamesave_current_version <= 1) Segments[segnum].sides[sidenum].tmap_num = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num); if (New_file_format_load && !(temp_ushort & 0x8000)) Segments[segnum].sides[sidenum].tmap_num2 = 0; else { // Read short Segments[segnum].sides[sidenum].tmap_num2; Segments[segnum].sides[sidenum].tmap_num2 = PHYSFSX_readShort(LoadFile); if (Gamesave_current_version <= 1 && Segments[segnum].sides[sidenum].tmap_num2 != 0) Segments[segnum].sides[sidenum].tmap_num2 = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num2); } // Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short) for (i=0; i<4; i++ ) { temp_short = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5; temp_short = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5; temp_ushort = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1; //PHYSFS_read( LoadFile, &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1 ); } } else { Segments[segnum].sides[sidenum].tmap_num = 0; Segments[segnum].sides[sidenum].tmap_num2 = 0; for (i=0; i<4; i++ ) { Segments[segnum].sides[sidenum].uvls[i].u = 0; Segments[segnum].sides[sidenum].uvls[i].v = 0; Segments[segnum].sides[sidenum].uvls[i].l = 0; } } } } #if 0 { FILE *fp; fp = fopen("segments.out", "wt"); for (i = 0; i <= Highest_segment_index; i++) { side sides[MAX_SIDES_PER_SEGMENT]; // 6 sides short children[MAX_SIDES_PER_SEGMENT]; // indices of 6 children segments, front, left, top, right, bottom, back short verts[MAX_VERTICES_PER_SEGMENT]; // vertex ids of 4 front and 4 back vertices int objects; // pointer to objects in this segment for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) { sbyte type; // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation ubyte pad; //keep us longword alligned short wall_num; short tmap_num; short tmap_num2; uvl uvls[4]; vms_vector normals[2]; // 2 normals, if quadrilateral, both the same. fprintf(fp, "%d\n", Segments[i].sides[j].type); fprintf(fp, "%d\n", Segments[i].sides[j].pad); fprintf(fp, "%d\n", Segments[i].sides[j].wall_num); fprintf(fp, "%d\n", Segments[i].tmap_num); } fclose(fp); } } #endif Highest_vertex_index = Num_vertices-1; Highest_segment_index = Num_segments-1; validate_segment_all(); // Fill in side type and normals. for (i=0; i<Num_segments; i++) { if (Gamesave_current_version > 5) segment2_read(&Segment2s[i], LoadFile); fuelcen_activate( &Segments[i], Segment2s[i].special ); } reset_objects(1); //one object, the player return 0; }
int load_mine_data_compiled(PHYSFS_file *LoadFile) { int i, segnum, sidenum; ubyte compiled_version; short temp_short; ushort temp_ushort = 0; ubyte bit_mask; if (!strcmp(strchr(Gamesave_current_filename, '.'), ".sdl")) New_file_format_load = 0; // descent 1 shareware else New_file_format_load = 1; // For compiled levels, textures map to themselves, prevent tmap_override always being gray, // bug which Matt and John refused to acknowledge, so here is Mike, fixing it. // // Although in a cloud of arrogant glee, he forgot to ifdef it on EDITOR! // (Matt told me to write that!) #ifdef EDITOR for (i=0; i<MAX_TEXTURES; i++) tmap_xlate_table[i] = i; #endif // memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS ); fuelcen_reset(); //=============================== Reading part ============================== compiled_version = PHYSFSX_readByte(LoadFile); (void)compiled_version; if (New_file_format_load) Num_vertices = PHYSFSX_readShort(LoadFile); else Num_vertices = PHYSFSX_readInt(LoadFile); Assert( Num_vertices <= MAX_VERTICES ); if (New_file_format_load) Num_segments = PHYSFSX_readShort(LoadFile); else Num_segments = PHYSFSX_readInt(LoadFile); Assert( Num_segments <= MAX_SEGMENTS ); for (i = 0; i < Num_vertices; i++) PHYSFSX_readVector( &(Vertices[i]), LoadFile); for (segnum=0; segnum<Num_segments; segnum++ ) { #ifdef EDITOR Segments[segnum].segnum = segnum; Segments[segnum].group = 0; #endif if (New_file_format_load) bit_mask = PHYSFSX_readByte(LoadFile); else bit_mask = 0x7f; // read all six children and special stuff... if (Gamesave_current_version == 5) { // d2 SHAREWARE level read_special(segnum,bit_mask,LoadFile); read_verts(segnum,LoadFile); read_children(segnum,bit_mask,LoadFile); } else { read_children(segnum,bit_mask,LoadFile); read_verts(segnum,LoadFile); if (Gamesave_current_version <= 1) { // descent 1 level read_special(segnum,bit_mask,LoadFile); } } Segments[segnum].objects = -1; if (Gamesave_current_version <= 5) { // descent 1 thru d2 SHAREWARE level // Read fix Segments[segnum].static_light (shift down 5 bits, write as short) temp_ushort = PHYSFSX_readShort(LoadFile); Segments[segnum].static_light = ((fix)temp_ushort) << 4; //PHYSFS_read( LoadFile, &Segments[segnum].static_light, sizeof(fix), 1 ); } // Read the walls as a 6 byte array for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { Segments[segnum].sides[sidenum].pad = 0; } if (New_file_format_load) bit_mask = PHYSFSX_readByte(LoadFile); else bit_mask = 0x3f; // read all six sides for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) { ubyte byte_wallnum; if (bit_mask & (1 << sidenum)) { byte_wallnum = PHYSFSX_readByte(LoadFile); if ( byte_wallnum == 255 ) Segments[segnum].sides[sidenum].wall_num = -1; else Segments[segnum].sides[sidenum].wall_num = byte_wallnum; } else Segments[segnum].sides[sidenum].wall_num = -1; } for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) ) { // Read short Segments[segnum].sides[sidenum].tmap_num; temp_ushort = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].tmap_num = convert_tmap(temp_ushort & 0x7fff); if (New_file_format_load && !(temp_ushort & 0x8000)) Segments[segnum].sides[sidenum].tmap_num2 = 0; else { // Read short Segments[segnum].sides[sidenum].tmap_num2; Segments[segnum].sides[sidenum].tmap_num2 = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].tmap_num2 = (convert_tmap(Segments[segnum].sides[sidenum].tmap_num2 & 0x3fff)) | (Segments[segnum].sides[sidenum].tmap_num2 & 0xc000); } // Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short) for (i=0; i<4; i++ ) { temp_short = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5; temp_short = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5; temp_ushort = PHYSFSX_readShort(LoadFile); Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1; //PHYSFS_read( LoadFile, &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1 ); } } else { Segments[segnum].sides[sidenum].tmap_num = 0; Segments[segnum].sides[sidenum].tmap_num2 = 0; for (i=0; i<4; i++ ) { Segments[segnum].sides[sidenum].uvls[i].u = 0; Segments[segnum].sides[sidenum].uvls[i].v = 0; Segments[segnum].sides[sidenum].uvls[i].l = 0; } } } } Highest_vertex_index = Num_vertices-1; Highest_segment_index = Num_segments-1; validate_segment_all(); // Fill in side type and normals. for (i=0; i<Num_segments; i++) { if (Gamesave_current_version > 5) segment2_read(&Segments[i], LoadFile); fuelcen_activate( &Segments[i], Segments[i].special ); } reset_objects(1); //one object, the player return 0; }
void bm_read_all(PHYSFS_file * fp) { int i,t; NumTextures = PHYSFSX_readInt(fp); bitmap_index_read_n(Textures, NumTextures, fp ); tmap_info_read_n(TmapInfo, NumTextures, fp); t = PHYSFSX_readInt(fp); PHYSFS_read( fp, Sounds, sizeof(ubyte), t ); PHYSFS_read( fp, AltSounds, sizeof(ubyte), t ); Num_vclips = PHYSFSX_readInt(fp); vclip_read_n(Vclip, Num_vclips, fp); Num_effects = PHYSFSX_readInt(fp); eclip_read_n(Effects, Num_effects, fp); Num_wall_anims = PHYSFSX_readInt(fp); wclip_read_n(WallAnims, Num_wall_anims, fp); N_robot_types = PHYSFSX_readInt(fp); robot_info_read_n(Robot_info, N_robot_types, fp); N_robot_joints = PHYSFSX_readInt(fp); jointpos_read_n(Robot_joints, N_robot_joints, fp); N_weapon_types = PHYSFSX_readInt(fp); weapon_info_read_n(Weapon_info, N_weapon_types, fp, Piggy_hamfile_version); N_powerup_types = PHYSFSX_readInt(fp); powerup_type_info_read_n(Powerup_info, N_powerup_types, fp); N_polygon_models = PHYSFSX_readInt(fp); polymodel_read_n(Polygon_models, N_polygon_models, fp); for (i=0; i<N_polygon_models; i++ ) polygon_model_data_read(&Polygon_models[i], fp); for (i = 0; i < N_polygon_models; i++) Dying_modelnums[i] = PHYSFSX_readInt(fp); for (i = 0; i < N_polygon_models; i++) Dead_modelnums[i] = PHYSFSX_readInt(fp); t = PHYSFSX_readInt(fp); bitmap_index_read_n(Gauges, t, fp); bitmap_index_read_n(Gauges_hires, t, fp); N_ObjBitmaps = PHYSFSX_readInt(fp); bitmap_index_read_n(ObjBitmaps, N_ObjBitmaps, fp); for (i = 0; i < N_ObjBitmaps; i++) ObjBitmapPtrs[i] = PHYSFSX_readShort(fp); player_ship_read(&only_player_ship, fp); Num_cockpits = PHYSFSX_readInt(fp); bitmap_index_read_n(cockpit_bitmap, Num_cockpits, fp); //@@ PHYSFS_read( fp, &Num_total_object_types, sizeof(int), 1 ); //@@ PHYSFS_read( fp, ObjType, sizeof(byte), Num_total_object_types ); //@@ PHYSFS_read( fp, ObjId, sizeof(byte), Num_total_object_types ); //@@ PHYSFS_read( fp, ObjStrength, sizeof(fix), Num_total_object_types ); First_multi_bitmap_num = PHYSFSX_readInt(fp); Num_reactors = PHYSFSX_readInt(fp); reactor_read_n(Reactors, Num_reactors, fp); Marker_model_num = PHYSFSX_readInt(fp); //@@PHYSFS_read( fp, &N_controlcen_guns, sizeof(int), 1 ); //@@PHYSFS_read( fp, controlcen_gun_points, sizeof(vms_vector), N_controlcen_guns ); //@@PHYSFS_read( fp, controlcen_gun_dirs, sizeof(vms_vector), N_controlcen_guns ); if (Piggy_hamfile_version < 3) { exit_modelnum = PHYSFSX_readInt(fp); destroyed_exit_modelnum = PHYSFSX_readInt(fp); } else exit_modelnum = destroyed_exit_modelnum = N_polygon_models; }
//type==1 means 1.1, type==2 means 1.2 (with weapons) void bm_read_extra_robots(const char *fname, Mission::descent_version_type type) { int t,version; auto fp = PHYSFSX_openReadBuffered(fname); if (!fp) { Error("Failed to open HAM file \"%s\"", fname); return; } if (type == Mission::descent_version_type::descent2z) { int sig; sig = PHYSFSX_readInt(fp); if (sig != MAKE_SIG('X','H','A','M')) return; version = PHYSFSX_readInt(fp); } else version = 0; (void)version; // NOTE: we do not need it, but keep it for possible further use bm_free_extra_models(); bm_free_extra_objbitmaps(); //read extra weapons t = PHYSFSX_readInt(fp); N_weapon_types = N_D2_WEAPON_TYPES+t; weapon_info_read_n(Weapon_info, N_weapon_types, fp, 3, N_D2_WEAPON_TYPES); //now read robot info t = PHYSFSX_readInt(fp); N_robot_types = N_D2_ROBOT_TYPES+t; if (N_robot_types >= MAX_ROBOT_TYPES) Error("Too many robots (%d) in <%s>. Max is %d.",t,fname,MAX_ROBOT_TYPES-N_D2_ROBOT_TYPES); range_for (auto &r, partial_range(Robot_info, N_D2_ROBOT_TYPES.value, N_robot_types)) robot_info_read(fp, r); t = PHYSFSX_readInt(fp); N_robot_joints = N_D2_ROBOT_JOINTS+t; if (N_robot_joints >= MAX_ROBOT_JOINTS) Error("Too many robot joints (%d) in <%s>. Max is %d.",t,fname,MAX_ROBOT_JOINTS-N_D2_ROBOT_JOINTS); range_for (auto &r, partial_range(Robot_joints, N_D2_ROBOT_JOINTS.value, N_robot_joints)) jointpos_read(fp, r); unsigned u = PHYSFSX_readInt(fp); N_polygon_models = N_D2_POLYGON_MODELS+u; if (N_polygon_models >= MAX_POLYGON_MODELS) Error("Too many polygon models (%d) in <%s>. Max is %d.",u,fname,MAX_POLYGON_MODELS-N_D2_POLYGON_MODELS); { const auto &&r = partial_range(Polygon_models, N_D2_POLYGON_MODELS.value, N_polygon_models); range_for (auto &p, r) polymodel_read(&p, fp); range_for (auto &p, r) polygon_model_data_read(&p, fp); } range_for (auto &i, partial_range(Dying_modelnums, N_D2_POLYGON_MODELS.value, N_polygon_models)) i = PHYSFSX_readInt(fp); range_for (auto &i, partial_range(Dead_modelnums, N_D2_POLYGON_MODELS.value, N_polygon_models)) i = PHYSFSX_readInt(fp); t = PHYSFSX_readInt(fp); if (N_D2_OBJBITMAPS+t >= ObjBitmaps.size()) Error("Too many object bitmaps (%d) in <%s>. Max is %" DXX_PRI_size_type ".", t, fname, ObjBitmaps.size() - N_D2_OBJBITMAPS); bitmap_index_read_n(fp, partial_range(ObjBitmaps, N_D2_OBJBITMAPS.value, N_D2_OBJBITMAPS + t)); t = PHYSFSX_readInt(fp); if (N_D2_OBJBITMAPPTRS+t >= ObjBitmapPtrs.size()) Error("Too many object bitmap pointers (%d) in <%s>. Max is %" DXX_PRI_size_type ".", t, fname, ObjBitmapPtrs.size() - N_D2_OBJBITMAPPTRS); range_for (auto &i, partial_range(ObjBitmapPtrs, N_D2_OBJBITMAPPTRS.value, N_D2_OBJBITMAPPTRS + t)) i = PHYSFSX_readShort(fp); }
//loads a level (.LVL) file from disk //returns 0 if success, else error code int load_level(const char * filename_passed) { #ifdef EDITOR int use_compiled_level=1; #endif PHYSFS_file * LoadFile; char filename[PATH_MAX]; int sig, minedata_offset, gamedata_offset, hostagetext_offset; int mine_err, game_err; #ifdef NETWORK int i; #endif #ifdef NETWORK if (Game_mode & GM_NETWORK) { for (i=0;i<MAX_POWERUP_TYPES;i++) { MaxPowerupsAllowed[i]=0; PowerupsInMine[i]=0; } } #endif #ifdef COMPACT_SEGS ncache_flush(); #endif #ifndef RELEASE Level_being_loaded = filename_passed; #endif strcpy(filename,filename_passed); #ifdef EDITOR //if we have the editor, try the LVL first, no matter what was passed. //if we don't have an LVL, try what was passed or SDL/RDL //if we don't have the editor, we just use what was passed change_filename_extension(filename,filename_passed,".lvl"); use_compiled_level = 0; if (!PHYSFSX_exists(filename,1)) { char *p = strrchr(filename_passed, '.'); if (d_stricmp(p, ".lvl")) strcpy(filename, filename_passed); // set to what was passed else change_filename_extension(filename, filename, ".rdl"); use_compiled_level = 1; } #endif if (!PHYSFSX_exists(filename,1)) sprintf(filename,"%s%s",MISSION_DIR,filename_passed); LoadFile = PHYSFSX_openReadBuffered( filename ); if (!LoadFile) { #ifdef EDITOR return 1; #else Error("Can't open file <%s>\n",filename); #endif } strcpy( Gamesave_current_filename, filename ); sig = PHYSFSX_readInt(LoadFile); Gamesave_current_version = PHYSFSX_readInt(LoadFile); minedata_offset = PHYSFSX_readInt(LoadFile); gamedata_offset = PHYSFSX_readInt(LoadFile); Assert(sig == MAKE_SIG('P','L','V','L')); (void)sig; if (Gamesave_current_version < 5) hostagetext_offset = PHYSFSX_readInt(LoadFile); PHYSFSX_fseek(LoadFile,minedata_offset,SEEK_SET); #ifdef EDITOR if (!use_compiled_level) mine_err = load_mine_data(LoadFile); else #endif //NOTE LINK TO ABOVE!! mine_err = load_mine_data_compiled(LoadFile); /* !!!HACK!!! * Descent 1 - Level 19: OBERON MINE has some ugly overlapping rooms (segment 484). * HACK to make this issue less visible by moving one vertex a little. */ if (Current_mission && !d_stricmp("Descent: First Strike",Current_mission_longname) && !d_stricmp("level19.rdl",filename) && PHYSFS_fileLength(LoadFile) == 136706) Vertices[1905].z =-385*F1_0; if (mine_err == -1) { //error!! PHYSFS_close(LoadFile); return 2; } PHYSFSX_fseek(LoadFile,gamedata_offset,SEEK_SET); game_err = load_game_data(LoadFile); if (game_err == -1) { //error!! PHYSFS_close(LoadFile); return 3; } (void)hostagetext_offset; //======================== CLOSE FILE ============================= PHYSFS_close( LoadFile ); #if 0 //def EDITOR #ifndef RELEASE write_game_text_file(filename); if (Errors_in_mine) { if (is_real_level(filename)) { char ErrorMessage[200]; sprintf( ErrorMessage, "Warning: %i errors in %s!\n", Errors_in_mine, Level_being_loaded ); stop_time(); gr_palette_load(gr_palette); nm_messagebox( NULL, 1, "Continue", ErrorMessage ); start_time(); } } #endif #endif #ifdef EDITOR //If an old version, ask the use if he wants to save as new version if (((LEVEL_FILE_VERSION>1) && Gamesave_current_version<LEVEL_FILE_VERSION) || mine_err==1 || game_err==1) { char ErrorMessage[200]; sprintf( ErrorMessage, "You just loaded a old version level. Would\n" "you like to save it as a current version level?"); gr_palette_load(gr_palette); if (nm_messagebox( NULL, 2, "Don't Save", "Save", ErrorMessage )==1) save_level(filename); } #endif #ifdef EDITOR if (EditorWindow) editor_status_fmt("Loaded NEW mine %s, \"%s\"",filename,Current_level_name); #endif #if !defined(NDEBUG) && !defined(COMPACT_SEGS) if (check_segment_connections()) nm_messagebox( "ERROR", 1, "Ok", "Connectivity errors detected in\n" "mine. See monochrome screen for\n" "details, and contact Matt or Mike." ); #endif return 0; }
void load_robot_replacements(const d_fname &level_name) { int t,i,j; char ifile_name[FILENAME_LEN]; change_filename_extension(ifile_name, level_name, ".HXM" ); auto fp = PHYSFSX_openReadBuffered(ifile_name); if (!fp) //no robot replacement file return; t = PHYSFSX_readInt(fp); //read id "HXM!" if (t!= 0x21584d48) Error("ID of HXM! file incorrect"); t = PHYSFSX_readInt(fp); //read version if (t<1) Error("HXM! version too old (%d)",t); t = PHYSFSX_readInt(fp); //read number of robots for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read robot number if (i<0 || i>=N_robot_types) Error("Robots number (%d) out of range in (%s). Range = [0..%d].",i,static_cast<const char *>(level_name),N_robot_types-1); robot_info_read(fp, Robot_info[i]); } t = PHYSFSX_readInt(fp); //read number of joints for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read joint number if (i<0 || i>=N_robot_joints) Error("Robots joint (%d) out of range in (%s). Range = [0..%d].",i,static_cast<const char *>(level_name),N_robot_joints-1); jointpos_read(fp, Robot_joints[i]); } t = PHYSFSX_readInt(fp); //read number of polygon models for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read model number if (i<0 || i>=N_polygon_models) Error("Polygon model (%d) out of range in (%s). Range = [0..%d].",i,static_cast<const char *>(level_name),N_polygon_models-1); free_model(Polygon_models[i]); polymodel_read(&Polygon_models[i], fp); polygon_model_data_read(&Polygon_models[i], fp); Dying_modelnums[i] = PHYSFSX_readInt(fp); Dead_modelnums[i] = PHYSFSX_readInt(fp); } t = PHYSFSX_readInt(fp); //read number of objbitmaps for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read objbitmap number if (i < 0 || i >= ObjBitmaps.size()) Error("Object bitmap number (%d) out of range in (%s). Range = [0..%" DXX_PRI_size_type "].", i, static_cast<const char *>(level_name), ObjBitmaps.size() - 1); bitmap_index_read(fp, ObjBitmaps[i]); } t = PHYSFSX_readInt(fp); //read number of objbitmapptrs for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read objbitmapptr number if (i < 0 || i >= ObjBitmapPtrs.size()) Error("Object bitmap pointer (%d) out of range in (%s). Range = [0..%" DXX_PRI_size_type "].", i, static_cast<const char *>(level_name), ObjBitmapPtrs.size() - 1); ObjBitmapPtrs[i] = PHYSFSX_readShort(fp); } Robot_replacements_loaded = 1; }
//reads one object of the given version from the given file void read_object(object *obj,PHYSFS_file *f,int version) { obj->type = PHYSFSX_readByte(f); obj->id = PHYSFSX_readByte(f); if (obj->type == OBJ_ROBOT && obj->id > 23) { obj->id = obj->id % 24; } obj->control_type = PHYSFSX_readByte(f); obj->movement_type = PHYSFSX_readByte(f); obj->render_type = PHYSFSX_readByte(f); obj->flags = PHYSFSX_readByte(f); obj->segnum = PHYSFSX_readShort(f); obj->attached_obj = -1; PHYSFSX_readVector(&obj->pos,f); PHYSFSX_readMatrix(&obj->orient,f); obj->size = PHYSFSX_readFix(f); obj->shields = PHYSFSX_readFix(f); PHYSFSX_readVector(&obj->last_pos,f); obj->contains_type = PHYSFSX_readByte(f); obj->contains_id = PHYSFSX_readByte(f); obj->contains_count = PHYSFSX_readByte(f); switch (obj->movement_type) { case MT_PHYSICS: PHYSFSX_readVector(&obj->mtype.phys_info.velocity,f); PHYSFSX_readVector(&obj->mtype.phys_info.thrust,f); obj->mtype.phys_info.mass = PHYSFSX_readFix(f); obj->mtype.phys_info.drag = PHYSFSX_readFix(f); obj->mtype.phys_info.brakes = PHYSFSX_readFix(f); PHYSFSX_readVector(&obj->mtype.phys_info.rotvel,f); PHYSFSX_readVector(&obj->mtype.phys_info.rotthrust,f); obj->mtype.phys_info.turnroll = PHYSFSX_readFixAng(f); obj->mtype.phys_info.flags = PHYSFSX_readShort(f); break; case MT_SPINNING: PHYSFSX_readVector(&obj->mtype.spin_rate,f); break; case MT_NONE: break; default: Int3(); } switch (obj->control_type) { case CT_AI: { int i; obj->ctype.ai_info.behavior = PHYSFSX_readByte(f); for (i=0;i<MAX_AI_FLAGS;i++) obj->ctype.ai_info.flags[i] = PHYSFSX_readByte(f); obj->ctype.ai_info.hide_segment = PHYSFSX_readShort(f); obj->ctype.ai_info.hide_index = PHYSFSX_readShort(f); obj->ctype.ai_info.path_length = PHYSFSX_readShort(f); obj->ctype.ai_info.cur_path_index = PHYSFSX_readShort(f); if (version <= 25) { obj->ctype.ai_info.follow_path_start_seg = PHYSFSX_readShort(f); obj->ctype.ai_info.follow_path_end_seg = PHYSFSX_readShort(f); } break; } case CT_EXPLOSION: obj->ctype.expl_info.spawn_time = PHYSFSX_readFix(f); obj->ctype.expl_info.delete_time = PHYSFSX_readFix(f); obj->ctype.expl_info.delete_objnum = PHYSFSX_readShort(f); obj->ctype.expl_info.next_attach = obj->ctype.expl_info.prev_attach = obj->ctype.expl_info.attach_parent = -1; break; case CT_WEAPON: //do I really need to read these? Are they even saved to disk? obj->ctype.laser_info.parent_type = PHYSFSX_readShort(f); obj->ctype.laser_info.parent_num = PHYSFSX_readShort(f); obj->ctype.laser_info.parent_signature = PHYSFSX_readInt(f); break; case CT_LIGHT: obj->ctype.light_info.intensity = PHYSFSX_readFix(f); break; case CT_POWERUP: if (version >= 25) obj->ctype.powerup_info.count = PHYSFSX_readInt(f); else obj->ctype.powerup_info.count = 1; if (obj->id == POW_VULCAN_WEAPON) obj->ctype.powerup_info.count = VULCAN_WEAPON_AMMO_AMOUNT; break; case CT_NONE: case CT_FLYING: case CT_DEBRIS: break; case CT_SLEW: //the player is generally saved as slew break; case CT_CNTRLCEN: break; case CT_MORPH: case CT_FLYTHROUGH: case CT_REPAIRCEN: default: Int3(); } switch (obj->render_type) { case RT_NONE: break; case RT_MORPH: case RT_POLYOBJ: { int i,tmo; obj->rtype.pobj_info.model_num = convert_polymod(PHYSFSX_readInt(f)); for (i=0;i<MAX_SUBMODELS;i++) PHYSFSX_readAngleVec(&obj->rtype.pobj_info.anim_angles[i],f); obj->rtype.pobj_info.subobj_flags = PHYSFSX_readInt(f); tmo = PHYSFSX_readInt(f); #ifndef EDITOR obj->rtype.pobj_info.tmap_override = convert_tmap(tmo); #else if (tmo==-1) obj->rtype.pobj_info.tmap_override = -1; else { int xlated_tmo = tmap_xlate_table[tmo]; if (xlated_tmo < 0) { Int3(); xlated_tmo = 0; } obj->rtype.pobj_info.tmap_override = xlated_tmo; } #endif obj->rtype.pobj_info.alt_textures = 0; break; } case RT_WEAPON_VCLIP: case RT_HOSTAGE: case RT_POWERUP: case RT_FIREBALL: obj->rtype.vclip_info.vclip_num = convert_vclip(PHYSFSX_readInt(f)); obj->rtype.vclip_info.frametime = PHYSFSX_readFix(f); obj->rtype.vclip_info.framenum = PHYSFSX_readByte(f); break; case RT_LASER: break; default: Int3(); } }
/* * reads n eclip structs from a PHYSFS_file */ int eclip_read_n(eclip *ec, int n, PHYSFS_file *fp) { int i, j; for (i = 0; i < n; i++) { ec[i].vc.play_time = PHYSFSX_readFix(fp); ec[i].vc.num_frames = PHYSFSX_readInt(fp); ec[i].vc.frame_time = PHYSFSX_readFix(fp); ec[i].vc.flags = PHYSFSX_readInt(fp); ec[i].vc.sound_num = PHYSFSX_readShort(fp); for (j = 0; j < VCLIP_MAX_FRAMES; j++) ec[i].vc.frames[j].index = PHYSFSX_readShort(fp); ec[i].vc.light_value = PHYSFSX_readFix(fp); ec[i].time_left = PHYSFSX_readFix(fp); ec[i].frame_count = PHYSFSX_readInt(fp); ec[i].changing_wall_texture = PHYSFSX_readShort(fp); ec[i].changing_object_texture = PHYSFSX_readShort(fp); ec[i].flags = PHYSFSX_readInt(fp); ec[i].crit_clip = PHYSFSX_readInt(fp); ec[i].dest_bm_num = PHYSFSX_readInt(fp); ec[i].dest_vclip = PHYSFSX_readInt(fp); ec[i].dest_eclip = PHYSFSX_readInt(fp); ec[i].dest_size = PHYSFSX_readFix(fp); ec[i].sound_num = PHYSFSX_readInt(fp); ec[i].segnum = PHYSFSX_readInt(fp); ec[i].sidenum = PHYSFSX_readInt(fp); } return i; }
// -------------------------------------------------------------------- // Load game // Loads all the relevant data for a level. // If level != -1, it loads the filename with extension changed to .min // Otherwise it loads the appropriate level mine. // returns 0=everything ok, 1=old version, -1=error int load_game_data(PHYSFS_file *LoadFile) { int i,j; short game_top_fileinfo_version; int object_offset; int gs_num_objects; int trig_size; //===================== READ FILE INFO ======================== #if 0 PHYSFS_read(LoadFile, &game_top_fileinfo, sizeof(game_top_fileinfo), 1); #endif // Check signature if (PHYSFSX_readShort(LoadFile) != 0x6705) return -1; // Read and check version number game_top_fileinfo_version = PHYSFSX_readShort(LoadFile); if (game_top_fileinfo_version < GAME_COMPATIBLE_VERSION ) return -1; // We skip some parts of the former game_top_fileinfo PHYSFSX_fseek(LoadFile, 31, SEEK_CUR); object_offset = PHYSFSX_readInt(LoadFile); gs_num_objects = PHYSFSX_readInt(LoadFile); PHYSFSX_fseek(LoadFile, 8, SEEK_CUR); Num_walls = PHYSFSX_readInt(LoadFile); PHYSFSX_fseek(LoadFile, 20, SEEK_CUR); Num_triggers = PHYSFSX_readInt(LoadFile); PHYSFSX_fseek(LoadFile, 24, SEEK_CUR); trig_size = PHYSFSX_readInt(LoadFile); Assert(trig_size == sizeof(ControlCenterTriggers)); (void)trig_size; PHYSFSX_fseek(LoadFile, 4, SEEK_CUR); Num_robot_centers = PHYSFSX_readInt(LoadFile); PHYSFSX_fseek(LoadFile, 4, SEEK_CUR); if (game_top_fileinfo_version >= 31) //load mine filename // read newline-terminated string, not sure what version this changed. PHYSFSX_fgets(Current_level_name,sizeof(Current_level_name),LoadFile); else if (game_top_fileinfo_version >= 14) { //load mine filename // read null-terminated string char *p=Current_level_name; //must do read one char at a time, since no PHYSFSX_fgets() do *p = PHYSFSX_fgetc(LoadFile); while (*p++!=0); } else Current_level_name[0]=0; if (game_top_fileinfo_version >= 19) { //load pof names N_save_pof_names = PHYSFSX_readShort(LoadFile); if (N_save_pof_names != 0x614d && N_save_pof_names != 0x5547) { // "Ma"de w/DMB beta/"GU"ILE Assert(N_save_pof_names < MAX_POLYGON_MODELS); PHYSFS_read(LoadFile,Save_pof_names,N_save_pof_names,FILENAME_LEN); } } //===================== READ PLAYER INFO ========================== //===================== READ OBJECT INFO ========================== Gamesave_num_org_robots = 0; Gamesave_num_players = 0; if (object_offset > -1) { if (PHYSFSX_fseek( LoadFile, object_offset, SEEK_SET )) Error( "Error seeking to object_offset in gamesave.c" ); for (i = 0; i < gs_num_objects; i++) { read_object(&Objects[i], LoadFile, game_top_fileinfo_version); Objects[i].signature = obj_get_signature(); verify_object( &Objects[i] ); } } //===================== READ WALL INFO ============================ for (i = 0; i < Num_walls; i++) { if (game_top_fileinfo_version >= 20) wall_read(&Walls[i], LoadFile); // v20 walls and up. else if (game_top_fileinfo_version >= 17) { v19_wall w; v19_wall_read(&w, LoadFile); Walls[i].segnum = w.segnum; Walls[i].sidenum = w.sidenum; Walls[i].linked_wall = w.linked_wall; Walls[i].type = w.type; Walls[i].flags = w.flags; Walls[i].hps = w.hps; Walls[i].trigger = w.trigger; Walls[i].clip_num = convert_wclip(w.clip_num); Walls[i].keys = w.keys; Walls[i].state = WALL_DOOR_CLOSED; } else { v16_wall w; v16_wall_read(&w, LoadFile); Walls[i].segnum = Walls[i].sidenum = Walls[i].linked_wall = -1; Walls[i].type = w.type; Walls[i].flags = w.flags; Walls[i].hps = w.hps; Walls[i].trigger = w.trigger; Walls[i].clip_num = convert_wclip(w.clip_num); Walls[i].keys = w.keys; } } #if 0 //===================== READ DOOR INFO ============================ if (game_fileinfo.doors_offset > -1) { if (!PHYSFSX_fseek( LoadFile, game_fileinfo.doors_offset,SEEK_SET )) { for (i=0;i<game_fileinfo.doors_howmany;i++) { if (game_top_fileinfo_version >= 20) active_door_read(&ActiveDoors[i], LoadFile); // version 20 and up else { v19_door d; int p; v19_door_read(&d, LoadFile); ActiveDoors[i].n_parts = d.n_parts; for (p=0;p<d.n_parts;p++) { int cseg,cside; cseg = Segments[d.seg[p]].children[d.side[p]]; cside = find_connect_side(&Segments[d.seg[p]],&Segments[cseg]); ActiveDoors[i].front_wallnum[p] = Segments[d.seg[p]].sides[d.side[p]].wall_num; ActiveDoors[i].back_wallnum[p] = Segments[cseg].sides[cside].wall_num; } } } } } #endif // 0 //==================== READ TRIGGER INFO ========================== for (i = 0; i < Num_triggers; i++) { if (game_top_fileinfo_version <= 25) trigger_read(&Triggers[i], LoadFile); else { int type; switch ((type = PHYSFSX_readByte(LoadFile))) { case 0: // door Triggers[i].type = 0; Triggers[i].flags = TRIGGER_CONTROL_DOORS; break; case 2: // matcen Triggers[i].type = 0; Triggers[i].flags = TRIGGER_MATCEN; break; case 3: // exit Triggers[i].type = 0; Triggers[i].flags = TRIGGER_EXIT; break; case 4: // secret exit Triggers[i].type = 0; Triggers[i].flags = TRIGGER_SECRET_EXIT; break; case 5: // illusion off Triggers[i].type = 0; Triggers[i].flags = TRIGGER_ILLUSION_OFF; break; case 6: // illusion on Triggers[i].type = 0; Triggers[i].flags = TRIGGER_ILLUSION_ON; break; default: con_printf(CON_URGENT,"Warning: unsupported trigger type %d (%d)\n", type, i); } if (PHYSFSX_readByte(LoadFile) & 2) // one shot Triggers[i].flags |= TRIGGER_ONE_SHOT; Triggers[i].num_links = PHYSFSX_readShort(LoadFile); Triggers[i].value = PHYSFSX_readInt(LoadFile); Triggers[i].time = PHYSFSX_readInt(LoadFile); for (j=0; j<MAX_WALLS_PER_LINK; j++ ) Triggers[i].seg[j] = PHYSFSX_readShort(LoadFile); for (j=0; j<MAX_WALLS_PER_LINK; j++ ) Triggers[i].side[j] = PHYSFSX_readShort(LoadFile); } } //================ READ CONTROL CENTER TRIGGER INFO =============== control_center_triggers_read_n(&ControlCenterTriggers, 1, LoadFile); //================ READ MATERIALOGRIFIZATIONATORS INFO =============== for (i = 0; i < Num_robot_centers; i++) { matcen_info_read(&RobotCenters[i], LoadFile, game_top_fileinfo_version); // Set links in RobotCenters to Station array for (j = 0; j <= Highest_segment_index; j++) if (Segments[j].special == SEGMENT_IS_ROBOTMAKER) if (Segments[j].matcen_num == i) RobotCenters[i].fuelcen_num = Segments[j].value; } //========================= UPDATE VARIABLES ====================== reset_objects(gs_num_objects); for (i=0; i<MAX_OBJECTS; i++) { Objects[i].next = Objects[i].prev = -1; if (Objects[i].type != OBJ_NONE) { int objsegnum = Objects[i].segnum; if (objsegnum > Highest_segment_index) //bogus object Objects[i].type = OBJ_NONE; else { Objects[i].segnum = -1; //avoid Assert() obj_link(i,objsegnum); } } } clear_transient_objects(1); //1 means clear proximity bombs // Make sure non-transparent doors are set correctly. for (i=0; i< Num_segments; i++) for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) { side *sidep = &Segments[i].sides[j]; if ((sidep->wall_num != -1) && (Walls[sidep->wall_num].clip_num != -1)) { if (WallAnims[Walls[sidep->wall_num].clip_num].flags & WCF_TMAP1) { sidep->tmap_num = WallAnims[Walls[sidep->wall_num].clip_num].frames[0]; sidep->tmap_num2 = 0; } } } reset_walls(); #if 0 Num_open_doors = game_fileinfo.doors_howmany; #endif // 0 Num_open_doors = 0; //go through all walls, killing references to invalid triggers for (i=0;i<Num_walls;i++) if (Walls[i].trigger >= Num_triggers) { Walls[i].trigger = -1; //kill trigger } //go through all triggers, killing unused ones for (i=0;i<Num_triggers;) { int w; // Find which wall this trigger is connected to. for (w=0; w<Num_walls; w++) if (Walls[w].trigger == i) break; #ifdef EDITOR if (w == Num_walls) { remove_trigger_num(i); } else #endif i++; } // MK, 10/17/95: Make walls point back at the triggers that control them. // Go through all triggers, stuffing controlling_trigger field in Walls. { int t; for (t=0; t<Num_triggers; t++) { int l; for (l=0; l<Triggers[t].num_links; l++) { int seg_num; seg_num = Triggers[t].seg[l]; //check to see that if a trigger requires a wall that it has one, //and if it requires a matcen that it has one if (Triggers[t].type == TRIGGER_MATCEN) { if (Segments[seg_num].special != SEGMENT_IS_ROBOTMAKER) Int3(); //matcen trigger doesn't point to matcen } } } } //fix old wall structs if (game_top_fileinfo_version < 17) { int segnum,sidenum,wallnum; for (segnum=0; segnum<=Highest_segment_index; segnum++) for (sidenum=0;sidenum<6;sidenum++) if ((wallnum=Segments[segnum].sides[sidenum].wall_num) != -1) { Walls[wallnum].segnum = segnum; Walls[wallnum].sidenum = sidenum; } } #ifndef NDEBUG { int sidenum; for (sidenum=0; sidenum<6; sidenum++) { int wallnum = Segments[Highest_segment_index].sides[sidenum].wall_num; if (wallnum != -1) if ((Walls[wallnum].segnum != Highest_segment_index) || (Walls[wallnum].sidenum != sidenum)) Int3(); // Error. Bogus walls in this segment. // Consult Yuan or Mike. } } #endif //create_local_segment_data(); fix_object_segs(); #ifndef NDEBUG dump_mine_info(); #endif if (game_top_fileinfo_version < GAME_VERSION) return 1; //means old version else return 0; }
void piggy_bitmap_page_in( bitmap_index bitmap ) { grs_bitmap * bmp; int i,org_i; org_i = 0; i = bitmap.index; Assert( i >= 0 ); Assert( i < MAX_BITMAP_FILES ); Assert( i < Num_bitmap_files ); Assert( Piggy_bitmap_cache_size > 0 ); if ( i < 1 ) return; if ( i >= MAX_BITMAP_FILES ) return; if ( i >= Num_bitmap_files ) return; if ( GameBitmapOffset[i] == 0 ) return; // A read-from-disk bitmap!!! if ( GameArg.SysLowMem ) { org_i = i; i = GameBitmapXlat[i]; // Xlat for low-memory settings! } bmp = &GameBitmaps[i]; if ( bmp->bm_flags & BM_FLAG_PAGED_OUT ) { stop_time(); ReDoIt: descent_critical_error = 0; PHYSFSX_fseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET ); if ( descent_critical_error ) { piggy_critical_error(); goto ReDoIt; } gr_set_bitmap_flags (bmp, GameBitmapFlags[i]); gr_set_bitmap_data (bmp, &Piggy_bitmap_cache_data [Piggy_bitmap_cache_next]); if ( bmp->bm_flags & BM_FLAG_RLE ) { int zsize = 0; descent_critical_error = 0; zsize = PHYSFSX_readInt(Piggy_fp); if ( descent_critical_error ) { piggy_critical_error(); goto ReDoIt; } // GET JOHN NOW IF YOU GET THIS ASSERT!!! Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size ); if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size ) { piggy_bitmap_page_out_all(); goto ReDoIt; } memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) ); Piggy_bitmap_cache_next += sizeof(int); descent_critical_error = 0; PHYSFS_read( Piggy_fp, &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, zsize-4 ); if ( descent_critical_error ) { piggy_critical_error(); goto ReDoIt; } if (MacPig) { rle_swap_0_255(bmp); memcpy(&zsize, bmp->bm_data, 4); } Piggy_bitmap_cache_next += zsize-4; } else { // GET JOHN NOW IF YOU GET THIS ASSERT!!! Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size ); if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size ) { piggy_bitmap_page_out_all(); goto ReDoIt; } descent_critical_error = 0; PHYSFS_read( Piggy_fp, &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w ); if ( descent_critical_error ) { piggy_critical_error(); goto ReDoIt; } if (MacPig) swap_0_255(bmp); Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w; } #ifdef BITMAP_SELECTOR if ( bmp->bm_selector ) { if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data )) Error( "Error modifying selector base in piggy.c\n" ); } #endif compute_average_rgb(bmp, bmp->avg_color_rgb); start_time(); } if ( GameArg.SysLowMem ) { if ( org_i != i ) GameBitmaps[org_i] = GameBitmaps[i]; } }
void load_robot_replacements(char *level_name) { PHYSFS_file *fp; int t,i,j; char ifile_name[FILENAME_LEN]; change_filename_extension(ifile_name, level_name, ".HXM" ); fp = PHYSFSX_openReadBuffered(ifile_name); if (!fp) //no robot replacement file return; t = PHYSFSX_readInt(fp); //read id "HXM!" if (t!= 0x21584d48) Error("ID of HXM! file incorrect"); t = PHYSFSX_readInt(fp); //read version if (t<1) Error("HXM! version too old (%d)",t); t = PHYSFSX_readInt(fp); //read number of robots for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read robot number if (i<0 || i>=N_robot_types) Error("Robots number (%d) out of range in (%s). Range = [0..%d].",i,level_name,N_robot_types-1); robot_info_read_n(&Robot_info[i], 1, fp); } t = PHYSFSX_readInt(fp); //read number of joints for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read joint number if (i<0 || i>=N_robot_joints) Error("Robots joint (%d) out of range in (%s). Range = [0..%d].",i,level_name,N_robot_joints-1); jointpos_read_n(&Robot_joints[i], 1, fp); } t = PHYSFSX_readInt(fp); //read number of polygon models for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read model number if (i<0 || i>=N_polygon_models) Error("Polygon model (%d) out of range in (%s). Range = [0..%d].",i,level_name,N_polygon_models-1); free_model(&Polygon_models[i]); polymodel_read(&Polygon_models[i], fp); polygon_model_data_read(&Polygon_models[i], fp); Dying_modelnums[i] = PHYSFSX_readInt(fp); Dead_modelnums[i] = PHYSFSX_readInt(fp); } t = PHYSFSX_readInt(fp); //read number of objbitmaps for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read objbitmap number if (i<0 || i>=MAX_OBJ_BITMAPS) Error("Object bitmap number (%d) out of range in (%s). Range = [0..%d].",i,level_name,MAX_OBJ_BITMAPS-1); bitmap_index_read(&ObjBitmaps[i], fp); } t = PHYSFSX_readInt(fp); //read number of objbitmapptrs for (j=0;j<t;j++) { i = PHYSFSX_readInt(fp); //read objbitmapptr number if (i<0 || i>=MAX_OBJ_BITMAPS) Error("Object bitmap pointer (%d) out of range in (%s). Range = [0..%d].",i,level_name,MAX_OBJ_BITMAPS-1); ObjBitmapPtrs[i] = PHYSFSX_readShort(fp); } PHYSFS_close(fp); Robot_replacements_loaded = 1; }