/* * 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 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; }
/* * reads a v16_wall structure from a PHYSFS_file */ extern void v16_wall_read(v16_wall *w, PHYSFS_file *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); }
/* * 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 segment2 structure from a PHYSFS_file */ void segment2_read(segment *s2, PHYSFS_file *fp) { s2->special = PHYSFSX_readByte(fp); if (s2->special >= MAX_CENTER_TYPES) s2->special = SEGMENT_IS_NOTHING; // remove goals etc. s2->matcen_num = PHYSFSX_readByte(fp); s2->value = PHYSFSX_readByte(fp); /*s2->s2_flags =*/ PHYSFSX_readByte(fp); // descent 2 ambient sound handling s2->static_light = PHYSFSX_readFix(fp); }
/* * 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); }
static void tmap_info_read(tmap_info &ti, PHYSFS_File *fp) { ti.flags = PHYSFSX_readByte(fp); PHYSFSX_readByte(fp); PHYSFSX_readByte(fp); PHYSFSX_readByte(fp); ti.lighting = PHYSFSX_readFix(fp); ti.damage = PHYSFSX_readFix(fp); ti.eclip_num = PHYSFSX_readShort(fp); ti.destroyed = PHYSFSX_readShort(fp); ti.slide_u = PHYSFSX_readShort(fp); ti.slide_v = PHYSFSX_readShort(fp); }
void read_special(int segnum,ubyte bit_mask,PHYSFS_file *LoadFile) { if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) { // Read ubyte Segment2s[segnum].special Segment2s[segnum].special = PHYSFSX_readByte(LoadFile); // Read byte Segment2s[segnum].matcen_num Segment2s[segnum].matcen_num = PHYSFSX_readByte(LoadFile); // Read short Segment2s[segnum].value Segment2s[segnum].value = PHYSFSX_readShort(LoadFile); } else { Segment2s[segnum].special = 0; Segment2s[segnum].matcen_num = -1; Segment2s[segnum].value = 0; } }
/* * reads a segment2 structure from a PHYSFS_File */ static void segment2_read(shared_segment &s2, unique_segment &u2, PHYSFS_File *fp) { s2.special = PHYSFSX_readByte(fp); s2.matcen_num = PHYSFSX_readByte(fp); /* station_idx overwritten by caller */ PHYSFSX_readByte(fp); const auto s2_flags = PHYSFSX_readByte(fp); #if defined(DXX_BUILD_DESCENT_I) (void)s2_flags; // descent 2 ambient sound handling if (s2.special >= MAX_CENTER_TYPES) s2.special = SEGMENT_IS_NOTHING; // remove goals etc. #elif defined(DXX_BUILD_DESCENT_II) s2.s2_flags = s2_flags; #endif u2.static_light = PHYSFSX_readFix(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 n tmap_info structs from a PHYSFS_file */ static int tmap_info_read_n(tmap_info *ti, int n, PHYSFS_file *fp) { int i; for (i = 0; i < n; i++) { ti[i].flags = PHYSFSX_readByte(fp); ti[i].pad[0] = PHYSFSX_readByte(fp); ti[i].pad[1] = PHYSFSX_readByte(fp); ti[i].pad[2] = PHYSFSX_readByte(fp); ti[i].lighting = PHYSFSX_readFix(fp); ti[i].damage = PHYSFSX_readFix(fp); ti[i].eclip_num = PHYSFSX_readShort(fp); ti[i].destroyed = PHYSFSX_readShort(fp); ti[i].slide_u = PHYSFSX_readShort(fp); ti[i].slide_v = PHYSFSX_readShort(fp); } return i; }
/* * 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); }
/* * reads a wclip structure from a PHYSFS_file */ int wclip_read_n(wclip *wc, int n, PHYSFS_file *fp) { int i, j; for (i = 0; i < n; i++) { wc[i].play_time = PHYSFSX_readFix(fp); wc[i].num_frames = PHYSFSX_readShort(fp); for (j = 0; j < MAX_CLIP_FRAMES; j++) wc[i].frames[j] = PHYSFSX_readShort(fp); wc[i].open_sound = PHYSFSX_readShort(fp); wc[i].close_sound = PHYSFSX_readShort(fp); wc[i].flags = PHYSFSX_readShort(fp); PHYSFS_read(fp, wc[i].filename, 13, 1); wc[i].pad = PHYSFSX_readByte(fp); } return i; }
/* * reads n PCXHeader structs from a PHYSFS_file */ static int PCXHeader_read_n(PCXHeader *ph, int n, PHYSFS_file *fp) { int i; for (i = 0; i < n; i++) { ph->Manufacturer = PHYSFSX_readByte(fp); ph->Version = PHYSFSX_readByte(fp); ph->Encoding = PHYSFSX_readByte(fp); ph->BitsPerPixel = PHYSFSX_readByte(fp); ph->Xmin = PHYSFSX_readShort(fp); ph->Ymin = PHYSFSX_readShort(fp); ph->Xmax = PHYSFSX_readShort(fp); ph->Ymax = PHYSFSX_readShort(fp); ph->Hdpi = PHYSFSX_readShort(fp); ph->Vdpi = PHYSFSX_readShort(fp); PHYSFS_read(fp, &ph->ColorMap, 16*3, 1); ph->Reserved = PHYSFSX_readByte(fp); ph->Nplanes = PHYSFSX_readByte(fp); ph->BytesPerLine = PHYSFSX_readShort(fp); PHYSFS_read(fp, &ph->filler, 60, 1); } 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; }
//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(); } }
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; }
/* * reads n weapon_info structs from a PHYSFS_file */ int weapon_info_read_n(weapon_info *wi, int n, PHYSFS_file *fp, int file_version) { int i, j; for (i = 0; i < n; i++) { wi[i].render_type = PHYSFSX_readByte(fp); wi[i].persistent = PHYSFSX_readByte(fp); wi[i].model_num = PHYSFSX_readShort(fp); wi[i].model_num_inner = PHYSFSX_readShort(fp); wi[i].flash_vclip = PHYSFSX_readByte(fp); wi[i].robot_hit_vclip = PHYSFSX_readByte(fp); wi[i].flash_sound = PHYSFSX_readShort(fp); wi[i].wall_hit_vclip = PHYSFSX_readByte(fp); wi[i].fire_count = PHYSFSX_readByte(fp); wi[i].robot_hit_sound = PHYSFSX_readShort(fp); wi[i].ammo_usage = PHYSFSX_readByte(fp); wi[i].weapon_vclip = PHYSFSX_readByte(fp); wi[i].wall_hit_sound = PHYSFSX_readShort(fp); wi[i].destroyable = PHYSFSX_readByte(fp); wi[i].matter = PHYSFSX_readByte(fp); wi[i].bounce = PHYSFSX_readByte(fp); wi[i].homing_flag = PHYSFSX_readByte(fp); wi[i].speedvar = PHYSFSX_readByte(fp); wi[i].flags = PHYSFSX_readByte(fp); wi[i].flash = PHYSFSX_readByte(fp); wi[i].afterburner_size = PHYSFSX_readByte(fp); if (file_version >= 3) wi[i].children = PHYSFSX_readByte(fp); else /* Set the type of children correctly when using old * datafiles. In earlier descent versions this was simply * hard-coded in create_smart_children(). */ switch (i) { case SMART_ID: wi[i].children = PLAYER_SMART_HOMING_ID; break; case SUPERPROX_ID: wi[i].children = SMART_MINE_HOMING_ID; break; #if 0 /* not present in shareware */ case ROBOT_SUPERPROX_ID: wi[i].children = ROBOT_SMART_MINE_HOMING_ID; break; case EARTHSHAKER_ID: wi[i].children = EARTHSHAKER_MEGA_ID; break; #endif default: wi[i].children = -1; break; } wi[i].energy_usage = PHYSFSX_readFix(fp); wi[i].fire_wait = PHYSFSX_readFix(fp); if (file_version >= 3) wi[i].multi_damage_scale = PHYSFSX_readFix(fp); else /* FIXME: hack this to set the real values */ wi[i].multi_damage_scale = F1_0; bitmap_index_read(&wi[i].bitmap, fp); wi[i].blob_size = PHYSFSX_readFix(fp); wi[i].flash_size = PHYSFSX_readFix(fp); wi[i].impact_size = PHYSFSX_readFix(fp); for (j = 0; j < NDL; j++) wi[i].strength[j] = PHYSFSX_readFix(fp); for (j = 0; j < NDL; j++) wi[i].speed[j] = PHYSFSX_readFix(fp); wi[i].mass = PHYSFSX_readFix(fp); wi[i].drag = PHYSFSX_readFix(fp); wi[i].thrust = PHYSFSX_readFix(fp); wi[i].po_len_to_width_ratio = PHYSFSX_readFix(fp); wi[i].light = PHYSFSX_readFix(fp); wi[i].lifetime = PHYSFSX_readFix(fp); wi[i].damage_radius = PHYSFSX_readFix(fp); bitmap_index_read(&wi[i].picture, fp); if (file_version >= 3) bitmap_index_read(&wi[i].hires_picture, fp); else wi[i].hires_picture.index = wi[i].picture.index; } return i; }