int VDevicePrefs::delete_objects() { delete output_title; delete channel_picker; delete buz_swap_channels; delete device_title; delete device_text; delete port_title; delete device_port; delete number_title; delete device_number; if(firewire_port) delete firewire_port; if(channel_title) delete channel_title; if(firewire_channel) delete firewire_channel; if(firewire_path) delete firewire_path; if(syt_title) delete syt_title; if(firewire_syt) delete firewire_syt; reset_objects(); driver = -1; return 0; }
VDevicePrefs::VDevicePrefs(int x, int y, PreferencesWindow *pwindow, PreferencesDialog *dialog, VideoOutConfig *out_config, VideoInConfig *in_config, int mode) { this->pwindow = pwindow; this->dialog = dialog; this->driver = -1; this->mode = mode; this->out_config = out_config; this->in_config = in_config; this->x = x; this->y = y; menu = 0; reset_objects(); }
int load_mine_data_compiled_new(CFILE *LoadFile) { int i,segnum,sidenum; ubyte version; short temp_short; ushort temp_ushort; ubyte bit_mask; // 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 ============================== cfread( &version, sizeof(ubyte), 1, LoadFile ); // 1 byte = compiled version Assert( version==COMPILED_MINE_VERSION ); cfread( &temp_ushort, sizeof(ushort), 1, LoadFile ); // 2 bytes = Num_vertices Num_vertices = temp_ushort; Assert( Num_vertices <= MAX_VERTICES ); cfread( &temp_ushort, sizeof(ushort), 1, LoadFile ); // 2 bytes = Num_segments Num_segments = temp_ushort; Assert( Num_segments <= MAX_SEGMENTS ); cfread( Vertices, sizeof(vms_vector), Num_vertices, LoadFile ); for (segnum=0; segnum<Num_segments; segnum++ ) { int bit; #ifdef EDITOR Segments[segnum].segnum = segnum; Segments[segnum].group = 0; #endif cfread( &bit_mask, sizeof(ubyte), 1, LoadFile ); for (bit=0; bit<MAX_SIDES_PER_SEGMENT; bit++) { if (bit_mask & (1 << bit)) cfread( &Segments[segnum].children[bit], sizeof(short), 1, LoadFile ); else Segments[segnum].children[bit] = -1; } // Read short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT] cfread( Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, LoadFile ); Segments[segnum].objects = -1; if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) { // Read ubyte Segments[segnum].special cfread( &Segments[segnum].special, sizeof(ubyte), 1, LoadFile ); // Read byte Segments[segnum].matcen_num cfread( &Segments[segnum].matcen_num, sizeof(ubyte), 1, LoadFile ); // Read short Segments[segnum].value cfread( &Segments[segnum].value, sizeof(short), 1, LoadFile ); } else { Segments[segnum].special = 0; Segments[segnum].matcen_num = -1; Segments[segnum].value = 0; } // Read fix Segments[segnum].static_light (shift down 5 bits, write as short) cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile ); Segments[segnum].static_light = ((fix)temp_ushort) << 4; //cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile ); // Read the walls as a 6 byte array for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { Segments[segnum].sides[sidenum].pad = 0; } cfread( &bit_mask, sizeof(ubyte), 1, LoadFile ); for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) { ubyte byte_wallnum; if (bit_mask & (1 << sidenum)) { cfread( &byte_wallnum, sizeof(ubyte), 1, 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; cfread( &temp_ushort, sizeof(ushort), 1, LoadFile ); Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff; if (!(temp_ushort & 0x8000)) Segments[segnum].sides[sidenum].tmap_num2 = 0; else { // Read short Segments[segnum].sides[sidenum].tmap_num2; cfread( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, LoadFile ); } // 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++ ) { cfread( &temp_short, sizeof(short), 1, LoadFile ); Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5; cfread( &temp_short, sizeof(short), 1, LoadFile ); Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5; cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile ); Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1; //cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile ); } } 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. // Activate fuelcentes for (i=0; i< Num_segments; i++ ) { fuelcen_activate( &Segments[i], Segments[i].special ); } reset_objects(1); //one object, the player return 0; }
// ----------------------------------------------------------------------------- //loads from an already-open file // returns 0=everything ok, 1=old version, -1=error int load_mine_data(CFILE *LoadFile) { int i, j; short tmap_xlate; int translate; char *temptr; int mine_start = cftell(LoadFile); fuelcen_reset(); for (i=0; i<MAX_TEXTURES; i++ ) tmap_times_used[i] = 0; #ifdef EDITOR // Create a new mine to initialize things. //texpage_goto_first(); create_new_mine(); #endif //===================== READ FILE INFO ======================== // These are the default values... version and fileinfo_sizeof // don't have defaults. mine_fileinfo.header_offset = -1; mine_fileinfo.header_size = sizeof(mine_header); mine_fileinfo.editor_offset = -1; mine_fileinfo.editor_size = sizeof(mine_editor); mine_fileinfo.vertex_offset = -1; mine_fileinfo.vertex_howmany = 0; mine_fileinfo.vertex_sizeof = sizeof(vms_vector); mine_fileinfo.segment_offset = -1; mine_fileinfo.segment_howmany = 0; mine_fileinfo.segment_sizeof = sizeof(segment); mine_fileinfo.newseg_verts_offset = -1; mine_fileinfo.newseg_verts_howmany = 0; mine_fileinfo.newseg_verts_sizeof = sizeof(vms_vector); mine_fileinfo.group_offset = -1; mine_fileinfo.group_howmany = 0; mine_fileinfo.group_sizeof = sizeof(group); mine_fileinfo.texture_offset = -1; mine_fileinfo.texture_howmany = 0; mine_fileinfo.texture_sizeof = 13; // num characters in a name mine_fileinfo.walls_offset = -1; mine_fileinfo.walls_howmany = 0; mine_fileinfo.walls_sizeof = sizeof(wall); mine_fileinfo.triggers_offset = -1; mine_fileinfo.triggers_howmany = 0; mine_fileinfo.triggers_sizeof = sizeof(trigger); mine_fileinfo.object_offset = -1; mine_fileinfo.object_howmany = 1; mine_fileinfo.object_sizeof = sizeof(object); // Read in mine_top_fileinfo to get size of saved fileinfo. memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) ); if (cfseek( LoadFile, mine_start, SEEK_SET )) Error( "Error moving to top of file in gamemine.c" ); if (cfread( &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1, LoadFile )!=1) Error( "Error reading mine_top_fileinfo in gamemine.c" ); if (mine_top_fileinfo.fileinfo_signature != 0x2884) return -1; // Check version number if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION ) return -1; // Now, Read in the fileinfo if (cfseek( LoadFile, mine_start, SEEK_SET )) Error( "Error seeking to top of file in gamemine.c" ); if (cfread( &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1, LoadFile )!=1) Error( "Error reading mine_fileinfo in gamemine.c" ); //===================== READ HEADER INFO ======================== // Set default values. mine_header.num_vertices = 0; mine_header.num_segments = 0; if (mine_fileinfo.header_offset > -1 ) { if (cfseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET )) Error( "Error seeking to header_offset in gamemine.c" ); if (cfread( &mine_header, mine_fileinfo.header_size, 1, LoadFile )!=1) Error( "Error reading mine_header in gamemine.c" ); } //===================== READ EDITOR INFO ========================== // Set default values mine_editor.current_seg = 0; mine_editor.newsegment_offset = -1; // To be written mine_editor.newsegment_size = sizeof(segment); mine_editor.Curside = 0; mine_editor.Markedsegp = -1; mine_editor.Markedside = 0; if (mine_fileinfo.editor_offset > -1 ) { if (cfseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET )) Error( "Error seeking to editor_offset in gamemine.c" ); if (cfread( &mine_editor, mine_fileinfo.editor_size, 1, LoadFile )!=1) Error( "Error reading mine_editor in gamemine.c" ); } //===================== READ TEXTURE INFO ========================== if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0)) { if (cfseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET )) Error( "Error seeking to texture_offset in gamemine.c" ); for (i=0; i< mine_fileinfo.texture_howmany; i++ ) { if (cfread( &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1, LoadFile )!=1) Error( "Error reading old_tmap_list[i] in gamemine.c" ); } } //=============== GENERATE TEXTURE TRANSLATION TABLE =============== translate = 0; Assert (NumTextures < MAX_TEXTURES); { hashtable ht; hashtable_init( &ht, NumTextures ); // Remove all the file extensions in the textures list for (i=0;i<NumTextures;i++) { temptr = strchr(TmapInfo[i].filename, '.'); if (temptr) *temptr = '\0'; hashtable_insert( &ht, TmapInfo[i].filename, i ); } // For every texture, search through the texture list // to find a matching name. for (j=0;j<mine_fileinfo.texture_howmany;j++) { // Remove this texture name's extension temptr = strchr(old_tmap_list[j], '.'); if (temptr) *temptr = '\0'; tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]); if (tmap_xlate_table[j] < 0 ) { //tmap_xlate_table[j] = 0; // mprintf( (0, "Couldn't find texture '%s'\n", old_tmap_list[j] )); ; } if (tmap_xlate_table[j] != j ) translate = 1; if (tmap_xlate_table[j] >= 0) tmap_times_used[tmap_xlate_table[j]]++; } { int count = 0; for (i=0; i<MAX_TEXTURES; i++ ) if (tmap_times_used[i]) count++; mprintf( (0, "This mine has %d unique textures in it (~%d KB)\n", count, (count*4096) /1024 )); } mprintf( (0, "Translate=%d\n", translate )); hashtable_free( &ht ); } //====================== READ VERTEX INFO ========================== // New check added to make sure we don't read in too many vertices. if ( mine_fileinfo.vertex_howmany > MAX_VERTICES ) { mprintf((0, "Num vertices exceeds maximum. Loading MAX %d vertices\n", MAX_VERTICES)); mine_fileinfo.vertex_howmany = MAX_VERTICES; } if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0)) { if (cfseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET )) Error( "Error seeking to vertex_offset in gamemine.c" ); for (i=0; i< mine_fileinfo.vertex_howmany; i++ ) { // Set the default values for this vertex Vertices[i].x = 1; Vertices[i].y = 1; Vertices[i].z = 1; if (cfread( &Vertices[i], mine_fileinfo.vertex_sizeof, 1, LoadFile )!=1) Error( "Error reading Vertices[i] in gamemine.c" ); } } //==================== READ SEGMENT INFO =========================== // New check added to make sure we don't read in too many segments. if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) { mprintf((0, "Num segments exceeds maximum. Loading MAX %d segments\n", MAX_SEGMENTS)); mine_fileinfo.segment_howmany = MAX_SEGMENTS; } // [commented out by mk on 11/20/94 (weren't we supposed to hit final in October?) because it looks redundant. I think I'll test it now...] fuelcen_reset(); if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0)) { if (cfseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET )) Error( "Error seeking to segment_offset in gamemine.c" ); Highest_segment_index = mine_fileinfo.segment_howmany-1; for (i=0; i< mine_fileinfo.segment_howmany; i++ ) { segment v16_seg; // Set the default values for this segment (clear to zero ) //memset( &Segments[i], 0, sizeof(segment) ); if (mine_top_fileinfo.fileinfo_version >= 16) { Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg)); if (cfread( &v16_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1) Error( "Error reading segments in gamemine.c" ); } else Error("Invalid mine version"); Segments[i] = v16_seg; Segments[i].objects = -1; #ifdef EDITOR Segments[i].group = -1; #endif if (mine_top_fileinfo.fileinfo_version < 15) { //used old uvl ranges int sn,uvln; for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) for (uvln=0;uvln<4;uvln++) { Segments[i].sides[sn].uvls[uvln].u /= 64; Segments[i].sides[sn].uvls[uvln].v /= 64; Segments[i].sides[sn].uvls[uvln].l /= 32; } } fuelcen_activate( &Segments[i], Segments[i].special ); if (translate == 1) for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) { unsigned short orient; tmap_xlate = Segments[i].sides[j].tmap_num; Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate]; if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG)) if (Segments[i].sides[j].tmap_num < 0) { mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j)); Int3(); Segments[i].sides[j].tmap_num = 0; } tmap_xlate = Segments[i].sides[j].tmap_num2 & 0x3FFF; orient = Segments[i].sides[j].tmap_num2 & (~0x3FFF); if (tmap_xlate != 0) { int xlated_tmap = tmap_xlate_table[tmap_xlate]; if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG)) if (xlated_tmap <= 0) { mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j)); Int3(); Segments[i].sides[j].tmap_num2 = 0; } Segments[i].sides[j].tmap_num2 = xlated_tmap | orient; } } } } //===================== READ NEWSEGMENT INFO ===================== #ifdef EDITOR { // Default segment created. vms_vector sizevec; med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE)); // New_segment = Segments[0]; //memset( &New_segment, 0, sizeof(segment) ); } if (mine_editor.newsegment_offset > -1) { if (cfseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET )) Error( "Error seeking to newsegment_offset in gamemine.c" ); if (cfread( &New_segment, mine_editor.newsegment_size,1,LoadFile )!=1) Error( "Error reading new_segment in gamemine.c" ); } if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0)) { if (cfseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET )) Error( "Error seeking to newseg_verts_offset in gamemine.c" ); for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ ) { // Set the default values for this vertex Vertices[NEW_SEGMENT_VERTICES+i].x = 1; Vertices[NEW_SEGMENT_VERTICES+i].y = 1; Vertices[NEW_SEGMENT_VERTICES+i].z = 1; if (cfread( &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1,LoadFile )!=1) Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" ); New_segment.verts[i] = NEW_SEGMENT_VERTICES+i; } } #endif //========================= UPDATE VARIABLES ====================== #ifdef EDITOR // Setting to Markedsegp to NULL ignores Curside and Markedside, which // we want to do when reading in an old file. Markedside = mine_editor.Markedside; Curside = mine_editor.Curside; for (i=0;i<10;i++) Groupside[i] = mine_editor.Groupside[i]; if ( mine_editor.current_seg != -1 ) Cursegp = mine_editor.current_seg + Segments; else Cursegp = NULL; if (mine_editor.Markedsegp != -1 ) Markedsegp = mine_editor.Markedsegp + Segments; else Markedsegp = NULL; num_groups = 0; current_group = -1; #endif Num_vertices = mine_fileinfo.vertex_howmany; Num_segments = mine_fileinfo.segment_howmany; Highest_vertex_index = Num_vertices-1; Highest_segment_index = Num_segments-1; reset_objects(1); //one object, the player #ifdef EDITOR Highest_vertex_index = MAX_SEGMENT_VERTICES-1; Highest_segment_index = MAX_SEGMENTS-1; set_vertex_counts(); Highest_vertex_index = Num_vertices-1; Highest_segment_index = Num_segments-1; warn_if_concave_segments(); #endif #ifdef EDITOR validate_segment_all(); #endif //create_local_segment_data(); //gamemine_find_textures(); if (mine_top_fileinfo.fileinfo_version < MINE_VERSION ) return 1; //old version else return 0; }
// -------------------------------------------------------------------- // 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; }
// -------------------------------------------------------------------------------------- // Create a new mine, set global variables. int create_new_mine(void) { int s; vms_vector sizevec; vms_matrix m1 = IDENTITY_MATRIX; // initialize_mine_arrays(); // gamestate_not_restored = 1; // Clear refueling center code fuelcen_reset(); hostage_init_all(); init_all_vertices(); Current_level_num = 0; //0 means not a real level Current_level_name[0] = 0; Gamesave_current_version = LEVEL_FILE_VERSION; Cur_object_index = -1; reset_objects(1); //just one object, the player num_groups = 0; current_group = -1; Num_vertices = 0; // Number of vertices in global array. Highest_vertex_index = 0; Num_segments = 0; // Number of segments in global array, will get increased in med_create_segment Highest_segment_index = 0; Cursegp = Segments; // Say current segment is the only segment. Curside = WBACK; // The active side is the back side Markedsegp = 0; // Say there is no marked segment. Markedside = WBACK; // Shouldn't matter since Markedsegp == 0, but just in case... for (s=0;s<MAX_GROUPS+1;s++) { GroupList[s].num_segments = 0; GroupList[s].num_vertices = 0; Groupsegp[s] = NULL; Groupside[s] = 0; } Num_robot_centers = 0; Num_open_doors = 0; wall_init(); trigger_init(); // Create New_segment, which is the segment we will be adding at each instance. med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE)); // New_segment = Segments[0]; // med_create_segment(Segments,0,0,0,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE,vm_mat_make(&m1,F1_0,0,0,0,F1_0,0,0,0,F1_0)); med_create_segment(Segments,0,0,0,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE,&m1); N_found_segs = 0; N_selected_segs = 0; N_warning_segs = 0; //--repair-- create_local_segment_data(); ControlCenterTriggers.num_links = 0; create_new_mission(); //editor_status("New mine created."); return 0; // say no error }
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; }
// ----------------------------------------------------------------------------- //loads from an already-open file // returns 0=everything ok, 1=old version, -1=error int load_mine_data(PHYSFS_file *LoadFile) { int i, j; short tmap_xlate; int translate; char *temptr; int mine_start = PHYSFS_tell(LoadFile); fuelcen_reset(); for (i=0; i<sizeof(tmap_times_used)/sizeof(tmap_times_used[0]); i++ ) tmap_times_used[i] = 0; #ifdef EDITOR // Create a new mine to initialize things. //texpage_goto_first(); create_new_mine(); #endif //===================== READ FILE INFO ======================== // These are the default values... version and fileinfo_sizeof // don't have defaults. mine_fileinfo.header_offset = -1; mine_fileinfo.header_size = sizeof(mine_header); mine_fileinfo.editor_offset = -1; mine_fileinfo.editor_size = sizeof(mine_editor); mine_fileinfo.vertex_offset = -1; mine_fileinfo.vertex_howmany = 0; mine_fileinfo.vertex_sizeof = sizeof(vms_vector); mine_fileinfo.segment_offset = -1; mine_fileinfo.segment_howmany = 0; mine_fileinfo.segment_sizeof = sizeof(segment); mine_fileinfo.newseg_verts_offset = -1; mine_fileinfo.newseg_verts_howmany = 0; mine_fileinfo.newseg_verts_sizeof = sizeof(vms_vector); mine_fileinfo.group_offset = -1; mine_fileinfo.group_howmany = 0; mine_fileinfo.group_sizeof = sizeof(group); mine_fileinfo.texture_offset = -1; mine_fileinfo.texture_howmany = 0; mine_fileinfo.texture_sizeof = FILENAME_LEN; // num characters in a name mine_fileinfo.walls_offset = -1; mine_fileinfo.walls_howmany = 0; mine_fileinfo.walls_sizeof = sizeof(wall); mine_fileinfo.triggers_offset = -1; mine_fileinfo.triggers_howmany = 0; mine_fileinfo.triggers_sizeof = sizeof(trigger); mine_fileinfo.object_offset = -1; mine_fileinfo.object_howmany = 1; mine_fileinfo.object_sizeof = sizeof(object); mine_fileinfo.level_shake_frequency = 0; mine_fileinfo.level_shake_duration = 0; // Delta light stuff for blowing out light sources. // if (mine_top_fileinfo.fileinfo_version >= 19) { mine_fileinfo.dl_indices_offset = -1; mine_fileinfo.dl_indices_howmany = 0; mine_fileinfo.dl_indices_sizeof = sizeof(dl_index); mine_fileinfo.delta_light_offset = -1; mine_fileinfo.delta_light_howmany = 0; mine_fileinfo.delta_light_sizeof = sizeof(delta_light); // } mine_fileinfo.segment2_offset = -1; mine_fileinfo.segment2_howmany = 0; mine_fileinfo.segment2_sizeof = sizeof(segment2); // Read in mine_top_fileinfo to get size of saved fileinfo. memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) ); if (PHYSFSX_fseek( LoadFile, mine_start, SEEK_SET )) Error( "Error moving to top of file in gamemine.c" ); if (PHYSFS_read( LoadFile, &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1 )!=1) Error( "Error reading mine_top_fileinfo in gamemine.c" ); if (mine_top_fileinfo.fileinfo_signature != 0x2884) return -1; // Check version number if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION ) return -1; // Now, Read in the fileinfo if (PHYSFSX_fseek( LoadFile, mine_start, SEEK_SET )) Error( "Error seeking to top of file in gamemine.c" ); if (PHYSFS_read( LoadFile, &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1 )!=1) Error( "Error reading mine_fileinfo in gamemine.c" ); if (mine_top_fileinfo.fileinfo_version < 18) { Level_shake_frequency = 0; Level_shake_duration = 0; Secret_return_segment = 0; Secret_return_orient = vmd_identity_matrix; } else { Level_shake_frequency = mine_fileinfo.level_shake_frequency << 12; Level_shake_duration = mine_fileinfo.level_shake_duration << 12; Secret_return_segment = mine_fileinfo.secret_return_segment; Secret_return_orient = mine_fileinfo.secret_return_orient; } //===================== READ HEADER INFO ======================== // Set default values. mine_header.num_vertices = 0; mine_header.num_segments = 0; if (mine_fileinfo.header_offset > -1 ) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET )) Error( "Error seeking to header_offset in gamemine.c" ); if (PHYSFS_read( LoadFile, &mine_header, mine_fileinfo.header_size, 1 )!=1) Error( "Error reading mine_header in gamemine.c" ); } //===================== READ EDITOR INFO ========================== // Set default values mine_editor.current_seg = 0; mine_editor.newsegment_offset = -1; // To be written mine_editor.newsegment_size = sizeof(segment); mine_editor.Curside = 0; mine_editor.Markedsegp = -1; mine_editor.Markedside = 0; if (mine_fileinfo.editor_offset > -1 ) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET )) Error( "Error seeking to editor_offset in gamemine.c" ); if (PHYSFS_read( LoadFile, &mine_editor, mine_fileinfo.editor_size, 1 )!=1) Error( "Error reading mine_editor in gamemine.c" ); } //===================== READ TEXTURE INFO ========================== if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0)) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET )) Error( "Error seeking to texture_offset in gamemine.c" ); for (i=0; i< mine_fileinfo.texture_howmany; i++ ) { if (PHYSFS_read( LoadFile, &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1 )!=1) Error( "Error reading old_tmap_list[i] in gamemine.c" ); } } //=============== GENERATE TEXTURE TRANSLATION TABLE =============== translate = 0; Assert (NumTextures < MAX_TEXTURES); { hashtable ht; hashtable_init( &ht, NumTextures ); // Remove all the file extensions in the textures list for (i=0;i<NumTextures;i++) { temptr = strchr(TmapInfo[i].filename, '.'); if (temptr) *temptr = '\0'; hashtable_insert( &ht, TmapInfo[i].filename, i ); } // For every texture, search through the texture list // to find a matching name. for (j=0;j<mine_fileinfo.texture_howmany;j++) { // Remove this texture name's extension temptr = strchr(old_tmap_list[j], '.'); if (temptr) *temptr = '\0'; tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]); if (tmap_xlate_table[j] < 0 ) { ; } if (tmap_xlate_table[j] != j ) translate = 1; if (tmap_xlate_table[j] >= 0) tmap_times_used[tmap_xlate_table[j]]++; } { int count = 0; for (i=0; i<MAX_TEXTURES; i++ ) if (tmap_times_used[i]) count++; } hashtable_free( &ht ); } //====================== READ VERTEX INFO ========================== // New check added to make sure we don't read in too many vertices. if ( mine_fileinfo.vertex_howmany > MAX_VERTICES ) { mine_fileinfo.vertex_howmany = MAX_VERTICES; } if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0)) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET )) Error( "Error seeking to vertex_offset in gamemine.c" ); for (i=0; i< mine_fileinfo.vertex_howmany; i++ ) { // Set the default values for this vertex Vertices[i].x = 1; Vertices[i].y = 1; Vertices[i].z = 1; if (PHYSFS_read( LoadFile, &Vertices[i], mine_fileinfo.vertex_sizeof, 1 )!=1) Error( "Error reading Vertices[i] in gamemine.c" ); } } //==================== READ SEGMENT INFO =========================== // New check added to make sure we don't read in too many segments. if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) { mine_fileinfo.segment_howmany = MAX_SEGMENTS; mine_fileinfo.segment2_howmany = MAX_SEGMENTS; } // [commented out by mk on 11/20/94 (weren't we supposed to hit final in October?) because it looks redundant. I think I'll test it now...] fuelcen_reset(); if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0)) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET )) Error( "Error seeking to segment_offset in gamemine.c" ); Highest_segment_index = mine_fileinfo.segment_howmany-1; for (i=0; i< mine_fileinfo.segment_howmany; i++ ) { // Set the default values for this segment (clear to zero ) //memset( &Segments[i], 0, sizeof(segment) ); if (mine_top_fileinfo.fileinfo_version < 20) { v16_segment v16_seg; Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg)); if (PHYSFS_read( LoadFile, &v16_seg, mine_fileinfo.segment_sizeof, 1 )!=1) Error( "Error reading segments in gamemine.c" ); #ifdef EDITOR Segments[i].segnum = v16_seg.segnum; // -- Segments[i].pad = v16_seg.pad; #endif for (j=0; j<MAX_SIDES_PER_SEGMENT; j++) Segments[i].sides[j] = v16_seg.sides[j]; for (j=0; j<MAX_SIDES_PER_SEGMENT; j++) Segments[i].children[j] = v16_seg.children[j]; for (j=0; j<MAX_VERTICES_PER_SEGMENT; j++) Segments[i].verts[j] = v16_seg.verts[j]; Segment2s[i].special = v16_seg.special; Segment2s[i].value = v16_seg.value; Segment2s[i].s2_flags = 0; Segment2s[i].matcen_num = v16_seg.matcen_num; Segment2s[i].static_light = v16_seg.static_light; fuelcen_activate( &Segments[i], Segment2s[i].special ); } else { if (PHYSFS_read( LoadFile, &Segments[i], mine_fileinfo.segment_sizeof, 1 )!=1) Error("Unable to read segment %i\n", i); } Segments[i].objects = -1; #ifdef EDITOR Segments[i].group = -1; #endif if (mine_top_fileinfo.fileinfo_version < 15) { //used old uvl ranges int sn,uvln; for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) for (uvln=0;uvln<4;uvln++) { Segments[i].sides[sn].uvls[uvln].u /= 64; Segments[i].sides[sn].uvls[uvln].v /= 64; Segments[i].sides[sn].uvls[uvln].l /= 32; } } if (translate == 1) for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) { unsigned short orient; tmap_xlate = Segments[i].sides[j].tmap_num; Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate]; if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG)) if (Segments[i].sides[j].tmap_num < 0) { Int3(); Segments[i].sides[j].tmap_num = NumTextures-1; } tmap_xlate = Segments[i].sides[j].tmap_num2 & TMAP_NUM_MASK; orient = Segments[i].sides[j].tmap_num2 & (~TMAP_NUM_MASK); if (tmap_xlate != 0) { int xlated_tmap = tmap_xlate_table[tmap_xlate]; if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG)) if (xlated_tmap <= 0) { Int3(); Segments[i].sides[j].tmap_num2 = NumTextures-1; } Segments[i].sides[j].tmap_num2 = xlated_tmap | orient; } } } if (mine_top_fileinfo.fileinfo_version >= 20) for (i=0; i<=Highest_segment_index; i++) { PHYSFS_read(LoadFile, &Segment2s[i], sizeof(segment2), 1); fuelcen_activate( &Segments[i], Segment2s[i].special ); } } //===================== READ NEWSEGMENT INFO ===================== #ifdef EDITOR { // Default segment created. vms_vector sizevec; med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE)); // New_segment = Segments[0]; //memset( &New_segment, 0, sizeof(segment) ); } if (mine_editor.newsegment_offset > -1) { if (PHYSFSX_fseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET )) Error( "Error seeking to newsegment_offset in gamemine.c" ); if (PHYSFS_read( LoadFile, &New_segment, mine_editor.newsegment_size,1 )!=1) Error( "Error reading new_segment in gamemine.c" ); } if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0)) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET )) Error( "Error seeking to newseg_verts_offset in gamemine.c" ); for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ ) { // Set the default values for this vertex Vertices[NEW_SEGMENT_VERTICES+i].x = 1; Vertices[NEW_SEGMENT_VERTICES+i].y = 1; Vertices[NEW_SEGMENT_VERTICES+i].z = 1; if (PHYSFS_read( LoadFile, &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1 )!=1) Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" ); New_segment.verts[i] = NEW_SEGMENT_VERTICES+i; } } #endif //========================= UPDATE VARIABLES ====================== #ifdef EDITOR // Setting to Markedsegp to NULL ignores Curside and Markedside, which // we want to do when reading in an old file. Markedside = mine_editor.Markedside; Curside = mine_editor.Curside; for (i=0;i<10;i++) Groupside[i] = mine_editor.Groupside[i]; if ( mine_editor.current_seg != -1 ) Cursegp = mine_editor.current_seg + Segments; else Cursegp = NULL; if (mine_editor.Markedsegp != -1 ) Markedsegp = mine_editor.Markedsegp + Segments; else Markedsegp = NULL; num_groups = 0; current_group = -1; #endif Num_vertices = mine_fileinfo.vertex_howmany; Num_segments = mine_fileinfo.segment_howmany; Highest_vertex_index = Num_vertices-1; Highest_segment_index = Num_segments-1; reset_objects(1); //one object, the player #ifdef EDITOR Highest_vertex_index = MAX_SEGMENT_VERTICES-1; Highest_segment_index = MAX_SEGMENTS-1; set_vertex_counts(); Highest_vertex_index = Num_vertices-1; Highest_segment_index = Num_segments-1; warn_if_concave_segments(); #endif #ifdef EDITOR validate_segment_all(); #endif //create_local_segment_data(); //gamemine_find_textures(); if (mine_top_fileinfo.fileinfo_version < MINE_VERSION ) return 1; //old version else return 0; }
int state_restore_all_sub(char *filename, int multi) { int ObjectStartLocation; int BogusSaturnShit = 0; int version,i, j, segnum; object * obj; FILE *fp; int current_level, next_level; int between_levels; char mission[16]; char desc[DESC_LENGTH+1]; char id[5]; char org_callsign[CALLSIGN_LEN+16]; if ( Game_mode & GM_MULTI ) { #ifdef MULTI_SAVE if ( !FindArg( "-multisave" ) ) #endif return 0; } fp = fopen( filename, "rb" ); if ( !fp ) return 0; //Read id fread( id, sizeof(char)*4, 1, fp ); if ( memcmp( id, dgss_id, 4 )) { fclose(fp); return 0; } //Read version fread( &version, sizeof(int), 1, fp ); if (version < STATE_COMPATIBLE_VERSION) { fclose(fp); return 0; } // Read description fread( desc, sizeof(char)*DESC_LENGTH, 1, fp ); // Skip the current screen shot... fseek( fp, THUMBNAIL_W*THUMBNAIL_H, SEEK_CUR ); // Read the Between levels flag... fread( &between_levels, sizeof(int), 1, fp ); // Read the mission info... fread( mission, sizeof(char)*9, 1, fp ); #ifdef MAC_SHAREWARE if (strcmp(mission, "") ) { nm_messagebox( NULL, 1, "Ok", "Error!\nUnable to load mission\n'%s'\n", mission ); fclose(fp); return 0; } #else if (!load_mission_by_name( mission )) { nm_messagebox( NULL, 1, "Ok", "Error!\nUnable to load mission\n'%s'\n", mission ); fclose(fp); return 0; } #endif //Read level info fread( ¤t_level, sizeof(int), 1, fp ); fread( &next_level, sizeof(int), 1, fp ); //Restore GameTime fread( &GameTime, sizeof(fix), 1, fp ); // Start new game.... if (!multi) { Game_mode = GM_NORMAL; Function_mode = FMODE_GAME; #ifdef NETWORK change_playernum_to(0); #endif strcpy( org_callsign, Players[0].callsign ); N_players = 1; InitPlayerObject(); //make sure player's object set up init_player_stats_game(); //clear all stats } else { strcpy( org_callsign, Players[Player_num].callsign ); } //Read player info if ( between_levels ) { int saved_offset; fread( &Players[Player_num], sizeof(player), 1, fp ); saved_offset = ftell(fp); fclose( fp ); do_briefing_screens(next_level); fp = fopen( filename, "rb" ); fseek( fp, saved_offset, SEEK_SET ); StartNewLevelSub( next_level, 0 ); } else { StartNewLevelSub(current_level, 0); fread( &Players[Player_num], sizeof(player), 1, fp ); } strcpy( Players[Player_num].callsign, org_callsign ); // Set the right level if ( between_levels ) Players[Player_num].level = next_level; // Restore the weapon states fread( &Primary_weapon, sizeof(byte), 1, fp ); fread( &Secondary_weapon, sizeof(byte), 1, fp ); select_weapon(Primary_weapon, 0, 0, 0); select_weapon(Secondary_weapon, 1, 0, 0); // Restore the difficulty level fread( &Difficulty_level, sizeof(int), 1, fp ); // Restore the cheats enabled flag fread( &Cheats_enabled, sizeof(int), 1, fp ); fread( &Game_turbo_mode, sizeof(int), 1, fp ); if ( !between_levels ) { Do_appearance_effect = 0; // Don't do this for middle o' game stuff. ObjectStartLocation = ftell( fp ); RetryObjectLoading: //Clear out all the objects from the lvl file for (segnum=0; segnum <= Highest_segment_index; segnum++) Segments[segnum].objects = -1; reset_objects(1); //Read objects, and pop 'em into their respective segments. fread( &i, sizeof(int), 1, fp ); Highest_object_index = i-1; if ( !BogusSaturnShit ) fread( Objects, sizeof(object)*i, 1, fp ); else { ubyte tmp_object[sizeof(object)]; for (i=0; i<=Highest_object_index; i++ ) { fread( tmp_object, sizeof(object)-3, 1, fp ); // Insert 3 bytes after the read in obj->rtype.pobj_info.alt_textures field. memcpy( &Objects[i], tmp_object, sizeof(object)-3 ); Objects[i].rtype.pobj_info.alt_textures = -1; } } Object_next_signature = 0; for (i=0; i<=Highest_object_index; i++ ) { obj = &Objects[i]; obj->rtype.pobj_info.alt_textures = -1; segnum = obj->segnum; obj->next = obj->prev = obj->segnum = -1; if ( obj->type != OBJ_NONE ) { // Check for a bogus Saturn version!!!! if (!BogusSaturnShit ) { if ( (segnum<0) || (segnum>Highest_segment_index) ) { BogusSaturnShit = 1; mprintf(( 1, "READING BOGUS SATURN VERSION OBJECTS!!! (Object:%d)\n", i )); fseek( fp, ObjectStartLocation, SEEK_SET ); goto RetryObjectLoading; } } obj_link(i,segnum); if ( obj->signature > Object_next_signature ) Object_next_signature = obj->signature; } } special_reset_objects(); Object_next_signature++; //Restore wall info fread( &i, sizeof(int), 1, fp ); Num_walls = i; // Check for a bogus Saturn version!!!! if (!BogusSaturnShit ) { if ( (Num_walls<0) || (Num_walls>MAX_WALLS) ) { BogusSaturnShit = 1; mprintf(( 1, "READING BOGUS SATURN VERSION OBJECTS!!! (Num_walls)\n" )); fseek( fp, ObjectStartLocation, SEEK_SET ); goto RetryObjectLoading; } } fread( Walls, sizeof(wall)*Num_walls, 1, fp ); // Check for a bogus Saturn version!!!! if (!BogusSaturnShit ) { for (i=0; i<Num_walls; i++ ) { if ( (Walls[i].segnum<0) || (Walls[i].segnum>Highest_segment_index) || (Walls[i].sidenum<-1) || (Walls[i].sidenum>5) ) { BogusSaturnShit = 1; mprintf(( 1, "READING BOGUS SATURN VERSION OBJECTS!!! (Wall %d)\n", i )); fseek( fp, ObjectStartLocation, SEEK_SET ); goto RetryObjectLoading; } } } //Restore door info fread( &i, sizeof(int), 1, fp ); Num_open_doors = i; fread( ActiveDoors, sizeof(active_door)*Num_open_doors, 1, fp ); //Restore trigger info fread( &Num_triggers, sizeof(int), 1, fp ); fread( Triggers, sizeof(trigger)*Num_triggers, 1, fp ); //Restore tmap info for (i=0; i<=Highest_segment_index; i++ ) { for (j=0; j<6; j++ ) { fread( &Segments[i].sides[j].wall_num, sizeof(short), 1, fp ); fread( &Segments[i].sides[j].tmap_num, sizeof(short), 1, fp ); fread( &Segments[i].sides[j].tmap_num2, sizeof(short), 1, fp ); } } //Restore the fuelcen info fread( &Fuelcen_control_center_destroyed, sizeof(int), 1, fp ); fread( &Fuelcen_seconds_left, sizeof(int), 1, fp ); fread( &Num_robot_centers, sizeof(int), 1, fp ); fread( RobotCenters, sizeof(matcen_info)*Num_robot_centers, 1, fp ); fread( &ControlCenterTriggers, sizeof(control_center_triggers), 1, fp ); fread( &Num_fuelcenters, sizeof(int), 1, fp ); fread( Station, sizeof(FuelCenter)*Num_fuelcenters, 1, fp ); // Restore the control cen info fread( &Control_center_been_hit, sizeof(int), 1, fp ); fread( &Control_center_player_been_seen, sizeof(int), 1, fp ); fread( &Control_center_next_fire_time, sizeof(int), 1, fp ); fread( &Control_center_present, sizeof(int), 1, fp ); fread( &Dead_controlcen_object_num, sizeof(int), 1, fp ); // Restore the AI state ai_restore_state( fp ); // Restore the automap visited info fread( Automap_visited, sizeof(ubyte)*MAX_SEGMENTS, 1, fp ); // Restore hacked up weapon system stuff. Fusion_next_sound_time = GameTime; Auto_fire_fusion_cannon_time = 0; Next_laser_fire_time = GameTime; Next_missile_fire_time = GameTime; Last_laser_fired_time = GameTime; } state_game_id = 0; if ( version >= 7 ) { int tmp_Lunacy; fread( &state_game_id, sizeof(uint), 1, fp ); fread( &Laser_rapid_fire, sizeof(int), 1, fp ); fread( &Ugly_robot_cheat, sizeof(int), 1, fp ); fread( &Ugly_robot_texture, sizeof(int), 1, fp ); fread( &Physics_cheat_flag, sizeof(int), 1, fp ); fread( &tmp_Lunacy, sizeof(int), 1, fp ); if ( tmp_Lunacy ) do_lunacy_on(); } fclose(fp); // Load in bitmaps, etc.. piggy_load_level_data(); return 1; }
int state_restore_all_sub(char *filename, int multi, int secret_restore) { int ObjectStartLocation; int version,i, j, segnum; object * obj; PHYSFS_file *fp; int current_level, next_level; int between_levels; char mission[16]; char desc[DESC_LENGTH+1]; char id[5]; char org_callsign[CALLSIGN_LEN+16]; #ifdef NETWORK int found; int nplayers = 0; //,playid[12],mynum; player restore_players[MAX_PLAYERS]; #endif fix old_gametime = GameTime; short TempTmapNum[MAX_SEGMENTS][MAX_SIDES_PER_SEGMENT]; short TempTmapNum2[MAX_SEGMENTS][MAX_SIDES_PER_SEGMENT]; #if defined(MACINTOSH) && !defined(NDEBUG) if (strncmp(filename, PLAYER_DIR, 9)) Int3(); #endif fp = PHYSFSX_openReadBuffered(filename); if ( !fp ) return 0; //Read id //FIXME: check for swapped file, react accordingly... PHYSFS_read(fp, id, sizeof(char) * 4, 1); if ( memcmp( id, dgss_id, 4 )) { PHYSFS_close(fp); return 0; } //Read version PHYSFS_read(fp, &version, sizeof(int), 1); if (version < STATE_COMPATIBLE_VERSION) { PHYSFS_close(fp); return 0; } // Read description PHYSFS_read(fp, desc, sizeof(char) * DESC_LENGTH, 1); // Skip the current screen shot... PHYSFS_seek(fp, PHYSFS_tell(fp) + THUMBNAIL_W * THUMBNAIL_H); // And now...skip the goddamn palette stuff that somebody forgot to add PHYSFS_seek(fp, PHYSFS_tell(fp) + 768); // Read the Between levels flag... PHYSFS_read(fp, &between_levels, sizeof(int), 1); Assert(between_levels == 0); //between levels save ripped out // Read the mission info... PHYSFS_read(fp, mission, sizeof(char) * 9, 1); mprintf ((0,"Missionname to load = %s\n",mission)); if (!load_mission_by_name( mission )) { nm_messagebox( NULL, 1, "Ok", "Error!\nUnable to load mission\n'%s'\n", mission ); PHYSFS_close(fp); return 0; } //Read level info PHYSFS_read(fp, ¤t_level, sizeof(int), 1); PHYSFS_read(fp, &next_level, sizeof(int), 1); //Restore GameTime PHYSFS_read(fp, &GameTime, sizeof(fix), 1); // Start new game.... if (!multi) { Game_mode = GM_NORMAL; Function_mode = FMODE_GAME; #ifdef NETWORK change_playernum_to(0); #endif strcpy( org_callsign, Players[0].callsign ); N_players = 1; if (!secret_restore) { InitPlayerObject(); //make sure player's object set up init_player_stats_game(); //clear all stats } } else { strcpy( org_callsign, Players[Player_num].callsign ); } #ifdef NETWORK if (Game_mode & GM_MULTI) { PHYSFS_read(fp, &state_game_id, sizeof(int), 1); PHYSFS_read(fp, &Netgame, sizeof(netgame_info), 1); PHYSFS_read(fp, &NetPlayers, sizeof(AllNetPlayers_info), 1); PHYSFS_read(fp, &nplayers, sizeof(N_players), 1); PHYSFS_read(fp, &Player_num, sizeof(Player_num), 1); for (i=0;i<nplayers;i++) PHYSFS_read(fp, &restore_players[i], sizeof(player), 1); #ifdef RISKY_PROPOSITION PHYSFS_read(fp, &robot_controlled[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_read(fp, &robot_agitation[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_read(fp, &robot_controlled_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_read(fp, &robot_last_send_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_read(fp, &robot_last_message_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_read(fp, &robot_send_pending[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_read(fp, &robot_fired[0], 4 * MAX_ROBOTS_CONTROLLED, 1); for (i=0;i<MAX_ROBOTS_CONTROLLED;i++) PHYSFS_read(fp, &robot_fire_buf[i][0],21,1); #endif for (i=0;i<nplayers;i++) { found=0; for (j=0;j<nplayers;j++) { if ((!strcmp (restore_players[i].callsign,Players[j].callsign)) && Players[j].connected==1) found=1; } restore_players[i].connected=found; } memcpy (&Players,&restore_players,sizeof(player)*nplayers); N_players=nplayers; if (network_i_am_master()) { for (i=0;i<N_players;i++) { if (i==Player_num) continue; Players[i].connected=0; } } //Viewer = ConsoleObject = &Objects[Players[Player_num].objnum]; } #endif //Read player info { StartNewLevelSub(current_level, 1, secret_restore); if (secret_restore) { player dummy_player; PHYSFS_read(fp, &dummy_player, sizeof(player), 1); if (secret_restore == 1) { // This means he didn't die, so he keeps what he got in the secret level. Players[Player_num].level = dummy_player.level; Players[Player_num].last_score = dummy_player.last_score; Players[Player_num].time_level = dummy_player.time_level; Players[Player_num].num_robots_level = dummy_player.num_robots_level; Players[Player_num].num_robots_total = dummy_player.num_robots_total; Players[Player_num].hostages_rescued_total = dummy_player.hostages_rescued_total; Players[Player_num].hostages_total = dummy_player.hostages_total; Players[Player_num].hostages_on_board = dummy_player.hostages_on_board; Players[Player_num].hostages_level = dummy_player.hostages_level; Players[Player_num].homing_object_dist = dummy_player.homing_object_dist; Players[Player_num].hours_level = dummy_player.hours_level; Players[Player_num].hours_total = dummy_player.hours_total; do_cloak_invul_secret_stuff(old_gametime); } else { Players[Player_num] = dummy_player; } } else { PHYSFS_read(fp, &Players[Player_num], sizeof(player), 1); } } strcpy( Players[Player_num].callsign, org_callsign ); // Set the right level if ( between_levels ) Players[Player_num].level = next_level; // Restore the weapon states PHYSFS_read(fp, &Primary_weapon, sizeof(sbyte), 1); PHYSFS_read(fp, &Secondary_weapon, sizeof(sbyte), 1); select_weapon(Primary_weapon, 0, 0, 0); select_weapon(Secondary_weapon, 1, 0, 0); // Restore the difficulty level PHYSFS_read(fp, &Difficulty_level, sizeof(int), 1); // Restore the cheats enabled flag { int cheats_enabled; PHYSFS_read(fp, &cheats_enabled, sizeof(int), 1); cvar_setint(&Cheats_enabled, cheats_enabled); } if ( !between_levels ) { Do_appearance_effect = 0; // Don't do this for middle o' game stuff. ObjectStartLocation = (int)PHYSFS_tell(fp); //Clear out all the objects from the lvl file for (segnum=0; segnum <= Highest_segment_index; segnum++) Segments[segnum].objects = -1; reset_objects(1); //Read objects, and pop 'em into their respective segments. PHYSFS_read(fp, &i, sizeof(int), 1); Highest_object_index = i-1; PHYSFS_read(fp, Objects, sizeof(object) * i, 1); Object_next_signature = 0; for (i=0; i<=Highest_object_index; i++ ) { obj = &Objects[i]; obj->rtype.pobj_info.alt_textures = -1; segnum = obj->segnum; obj->next = obj->prev = obj->segnum = -1; if ( obj->type != OBJ_NONE ) { obj_link(i,segnum); if ( obj->signature > Object_next_signature ) Object_next_signature = obj->signature; } //look for, and fix, boss with bogus shields if (obj->type == OBJ_ROBOT && Robot_info[obj->id].boss_flag) { fix save_shields = obj->shields; copy_defaults_to_robot(obj); //calculate starting shields //if in valid range, use loaded shield value if (save_shields > 0 && save_shields <= obj->shields) obj->shields = save_shields; else obj->shields /= 2; //give player a break } } special_reset_objects(); Object_next_signature++; // 1 = Didn't die on secret level. // 2 = Died on secret level. if (secret_restore && (Current_level_num >= 0)) { set_pos_from_return_segment(); if (secret_restore == 2) init_player_stats_new_ship(); } //Restore wall info PHYSFS_read(fp, &i, sizeof(int), 1); Num_walls = i; PHYSFS_read(fp, Walls, sizeof(wall), Num_walls); //now that we have the walls, check if any sounds are linked to //walls that are now open for (i=0;i<Num_walls;i++) { if (Walls[i].type == WALL_OPEN) digi_kill_sound_linked_to_segment(Walls[i].segnum,Walls[i].sidenum,-1); //-1 means kill any sound } //Restore exploding wall info if (version >= 10) { PHYSFS_read(fp, &i, sizeof(int), 1); PHYSFS_read(fp, expl_wall_list, sizeof(*expl_wall_list), i); } //Restore door info PHYSFS_read(fp, &i, sizeof(int), 1); Num_open_doors = i; PHYSFS_read(fp, ActiveDoors, sizeof(active_door), Num_open_doors); if (version >= 14) { //Restore cloaking wall info PHYSFS_read(fp, &i, sizeof(int), 1); Num_cloaking_walls = i; PHYSFS_read(fp, CloakingWalls, sizeof(cloaking_wall), Num_cloaking_walls); } //Restore trigger info PHYSFS_read(fp, &Num_triggers, sizeof(int), 1); PHYSFS_read(fp, Triggers, sizeof(trigger), Num_triggers); //Restore tmap info (to temp values so we can use compiled-in tmap info to compute static_light) for (i=0; i<=Highest_segment_index; i++ ) { for (j=0; j<6; j++ ) { PHYSFS_read(fp, &Segments[i].sides[j].wall_num, sizeof(short), 1); PHYSFS_read(fp, &TempTmapNum[i][j], sizeof(short), 1); PHYSFS_read(fp, &TempTmapNum2[i][j], sizeof(short), 1); } } //Restore the fuelcen info PHYSFS_read(fp, &Control_center_destroyed, sizeof(int), 1); PHYSFS_read(fp, &Countdown_timer, sizeof(int), 1); PHYSFS_read(fp, &Num_robot_centers, sizeof(int), 1); PHYSFS_read(fp, RobotCenters, sizeof(matcen_info), Num_robot_centers); PHYSFS_read(fp, &ControlCenterTriggers, sizeof(control_center_triggers), 1); PHYSFS_read(fp, &Num_fuelcenters, sizeof(int), 1); PHYSFS_read(fp, Station, sizeof(FuelCenter), Num_fuelcenters); // Restore the control cen info PHYSFS_read(fp, &Control_center_been_hit, sizeof(int), 1); PHYSFS_read(fp, &Control_center_player_been_seen, sizeof(int), 1); PHYSFS_read(fp, &Control_center_next_fire_time, sizeof(int), 1); PHYSFS_read(fp, &Control_center_present, sizeof(int), 1); PHYSFS_read(fp, &Dead_controlcen_object_num, sizeof(int), 1); // Restore the AI state ai_restore_state( fp, version ); // Restore the automap visited info PHYSFS_read(fp, Automap_visited, sizeof(ubyte), MAX_SEGMENTS); // Restore hacked up weapon system stuff. Fusion_next_sound_time = GameTime; Auto_fire_fusion_cannon_time = 0; Next_laser_fire_time = GameTime; Next_missile_fire_time = GameTime; Last_laser_fired_time = GameTime; } state_game_id = 0; if ( version >= 7 ) { PHYSFS_read(fp, &state_game_id, sizeof(uint), 1); PHYSFS_read(fp, &Laser_rapid_fire, sizeof(int), 1); PHYSFS_read(fp, &Lunacy, sizeof(int), 1); // Yes, writing this twice. Removed the Ugly robot system, but didn't want to change savegame format. PHYSFS_read(fp, &Lunacy, sizeof(int), 1); if ( Lunacy ) do_lunacy_on(); } if (version >= 17) { PHYSFS_read(fp, MarkerObject, sizeof(MarkerObject), 1); PHYSFS_read(fp, MarkerOwner, sizeof(MarkerOwner), 1); PHYSFS_read(fp, MarkerMessage, sizeof(MarkerMessage), 1); } else { int num,dummy; // skip dummy info PHYSFS_read(fp, &num,sizeof(int), 1); // was NumOfMarkers PHYSFS_read(fp, &dummy,sizeof(int), 1); // was CurMarker PHYSFS_seek(fp, PHYSFS_tell(fp) + num * (sizeof(vms_vector) + 40)); for (num=0;num<NUM_MARKERS;num++) MarkerObject[num] = -1; } if (version>=11) { if (secret_restore != 1) PHYSFS_read(fp, &Afterburner_charge, sizeof(fix), 1); else { fix dummy_fix; PHYSFS_read(fp, &dummy_fix, sizeof(fix), 1); } } if (version>=12) { //read last was super information PHYSFS_read(fp, &Primary_last_was_super, sizeof(Primary_last_was_super), 1); PHYSFS_read(fp, &Secondary_last_was_super, sizeof(Secondary_last_was_super), 1); } if (version >= 12) { PHYSFS_read(fp, &Flash_effect, sizeof(int), 1); PHYSFS_read(fp, &Time_flash_last_played, sizeof(int), 1); PHYSFS_read(fp, &PaletteRedAdd, sizeof(int), 1); PHYSFS_read(fp, &PaletteGreenAdd, sizeof(int), 1); PHYSFS_read(fp, &PaletteBlueAdd, sizeof(int), 1); } else { Flash_effect = 0; Time_flash_last_played = 0; PaletteRedAdd = 0; PaletteGreenAdd = 0; PaletteBlueAdd = 0; } // Load Light_subtracted if (version >= 16) { PHYSFS_read(fp, Light_subtracted, sizeof(Light_subtracted[0]), MAX_SEGMENTS); apply_all_changed_light(); } else { int i; for (i=0; i<=Highest_segment_index; i++) Light_subtracted[i] = 0; } // static_light should now be computed - now actually set tmap info for (i=0; i<=Highest_segment_index; i++ ) { for (j=0; j<6; j++ ) { Segments[i].sides[j].tmap_num=TempTmapNum[i][j]; Segments[i].sides[j].tmap_num2=TempTmapNum2[i][j]; } } if (!secret_restore) { if (version >= 20) { PHYSFS_read(fp, &First_secret_visit, sizeof(First_secret_visit), 1); mprintf((0, "File: [%s] Read First_secret_visit: New value = %i\n", filename, First_secret_visit)); } else First_secret_visit = 1; } else First_secret_visit = 0; if (version >= 22) { if (secret_restore != 1) PHYSFS_read(fp, &Omega_charge, sizeof(fix), 1); else { fix dummy_fix; PHYSFS_read(fp, &dummy_fix, sizeof(fix), 1); } } PHYSFS_close(fp); #ifdef NETWORK if (Game_mode & GM_MULTI) // Get rid of ships that aren't { // connected in the restored game for (i=0;i<nplayers;i++) { mprintf ((0,"Testing %s = %d\n",Players[i].callsign,Players[i].connected)); if (Players[i].connected!=1) { network_disconnect_player (i); create_player_appearance_effect(&Objects[Players[i].objnum]); mprintf ((0,"Killing player ship %s!\n",Players[i].callsign)); } } } #endif // Load in bitmaps, etc.. //!! piggy_load_level_data(); //already done by StartNewLevelSub() return 1; }
int load_mine_data_compiled(CFILE *LoadFile) { int i,segnum,sidenum; ubyte version; short temp_short; ushort temp_ushort; ubyte bit_mask; // 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 ============================== // cfread( &version, sizeof(ubyte), 1, LoadFile ); // 1 byte = compiled version version = read_byte(LoadFile); Assert( version==COMPILED_MINE_VERSION ); // cfread( &temp_ushort, sizeof(ushort), 1, LoadFile ); // 2 bytes = Num_vertices // Num_vertices = temp_ushort; Num_vertices = read_short(LoadFile); Assert( Num_vertices <= MAX_VERTICES ); // cfread( &temp_ushort, sizeof(ushort), 1, LoadFile ); // 2 bytes = Num_segments // Num_segments = INTEL_SHORT(temp_ushort); Num_segments = read_short(LoadFile); Assert( Num_segments <= MAX_SEGMENTS ); // cfread( Vertices, sizeof(vms_vector), Num_vertices, LoadFile ); for (i = 0; i < Num_vertices; i++) read_vector( &(Vertices[i]), LoadFile); for (segnum=0; segnum<Num_segments; segnum++ ) { #ifdef EDITOR Segments[segnum].segnum = segnum; Segments[segnum].group = 0; #endif cfread( &bit_mask, sizeof(ubyte), 1, LoadFile ); #if defined(SHAREWARE) && !defined(MACINTOSH) // -- 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); // --read_special(segnum,bit_mask,LoadFile); #endif Segments[segnum].objects = -1; // Read fix Segments[segnum].static_light (shift down 5 bits, write as short) // cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile ); // temp_ushort = read_short(LoadFile); // Segment2s[segnum].static_light = ((fix)temp_ushort) << 4; //cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile ); // Read the walls as a 6 byte array for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { Segments[segnum].sides[sidenum].pad = 0; } cfread( &bit_mask, sizeof(ubyte), 1, LoadFile ); for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) { ubyte byte_wallnum; if (bit_mask & (1 << sidenum)) { cfread( &byte_wallnum, sizeof(ubyte), 1, 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; // cfread( &temp_ushort, sizeof(ushort), 1, LoadFile ); temp_ushort = read_short(LoadFile); Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff; if (!(temp_ushort & 0x8000)) Segments[segnum].sides[sidenum].tmap_num2 = 0; else { // Read short Segments[segnum].sides[sidenum].tmap_num2; // cfread( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, LoadFile ); Segments[segnum].sides[sidenum].tmap_num2 = read_short(LoadFile); } // 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++ ) { // cfread( &temp_short, sizeof(short), 1, LoadFile ); temp_short = read_short(LoadFile); Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5; // cfread( &temp_short, sizeof(short), 1, LoadFile ); temp_short = read_short(LoadFile); Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5; // cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile ); temp_ushort = read_short(LoadFile); Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1; //cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile ); } } 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++) { byte 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. // MIKE!!!!! You should know better than this when the mac is involved!!!!!! for (i=0; i<Num_segments; i++) { // NO NO!!!! cfread( &Segment2s[i], sizeof(segment2), 1, LoadFile ); Segment2s[i].special = read_byte(LoadFile); Segment2s[i].matcen_num = read_byte(LoadFile); Segment2s[i].value = read_byte(LoadFile); Segment2s[i].s2_flags = read_byte(LoadFile); Segment2s[i].static_light = read_fix(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; }