Example #1
0
int state_save_all_sub(char *filename, char *desc, int between_levels)
{
	int i,j;
	FILE * fp;
	grs_canvas * cnv;
	FInfo finfo;
	OSErr err;
	Str255 pfilename;

	if ( Game_mode & GM_MULTI )	{
#ifdef MULTI_SAVE
		if ( !FindArg( "-multisave" ) ) 
#endif  
			return 0;
	}

	fp = fopen( filename, "wb" );
	if ( !fp ) {
		start_time();
		return 0;
	}

//Save id
	fwrite( dgss_id, sizeof(char)*4, 1, fp );

//Save version
	i = STATE_VERSION;
	fwrite( &i, sizeof(int), 1, fp );

//Save description
	fwrite( desc, sizeof(char)*DESC_LENGTH, 1, fp );
	
// Save the current screen shot...
	cnv = gr_create_canvas( THUMBNAIL_W, THUMBNAIL_H );
	if ( cnv )	{
		gr_set_current_canvas( cnv );
		if ( between_levels )	{
			char * pcx_file;
			ubyte pcx_palette[768];
			grs_bitmap bmp;

			gr_clear_canvas( BM_XRGB(0,0,0) );
			pcx_file = get_briefing_screen( Next_level_num );
			if ( pcx_file != NULL )	{
				bmp.bm_data = NULL;
				if (pcx_read_bitmap( pcx_file, &bmp, BM_LINEAR, pcx_palette )==PCX_ERROR_NONE)	{
					grs_point vertbuf[3];
					gr_clear_canvas( TRANSPARENCY_COLOR );
					vertbuf[0].x = vertbuf[0].y = -F1_0*6;		// -6 pixel rows for ascpect
					vertbuf[1].x = vertbuf[1].y = 0;
					vertbuf[2].x = i2f(THUMBNAIL_W); vertbuf[2].y = i2f(THUMBNAIL_H+7);	// + 7 pixel rows for ascpect
					scale_bitmap(&bmp, vertbuf );
					gr_remap_bitmap_good( &cnv->cv_bitmap, pcx_palette, -1, -1 );
					myfree( bmp.bm_data );
				}
			}
		} else {
			render_frame(0);
		}
		fwrite( cnv->cv_bitmap.bm_data, THUMBNAIL_W*THUMBNAIL_H, 1, fp );
		gr_free_canvas( cnv );
	} else {
	 	ubyte color = 0;
	 	for ( i=0; i<THUMBNAIL_W*THUMBNAIL_H; i++ )
	 		fwrite( &color, sizeof(ubyte), 1, fp );		
	}

// Save the Between levels flag...
	fwrite( &between_levels, sizeof(int), 1, fp );

// Save the mission info...
#ifdef MAC_SHAREWARE
	fwrite( mission_save, sizeof(char)*9, 1, fp);
#else
	fwrite( &Mission_list[Current_mission_num], sizeof(char)*9, 1, fp );
#endif

//Save level info
	fwrite( &Current_level_num, sizeof(int), 1, fp );
	fwrite( &Next_level_num, sizeof(int), 1, fp );

//Save GameTime
	fwrite( &GameTime, sizeof(fix), 1, fp );

//Save player info
	fwrite( &Players[Player_num], sizeof(player), 1, fp );

// Save the current weapon info
	fwrite( &Primary_weapon, sizeof(byte), 1, fp );
	fwrite( &Secondary_weapon, sizeof(byte), 1, fp );

// Save the difficulty level
	fwrite( &Difficulty_level, sizeof(int), 1, fp );

// Save the Cheats_enabled
	fwrite( &Cheats_enabled, sizeof(int), 1, fp );
	fwrite( &Game_turbo_mode, sizeof(int), 1, fp );


	if ( !between_levels )	{

	//Finish all morph objects
		for (i=0; i<=Highest_object_index; i++ )	{
			if ( (Objects[i].type != OBJ_NONE) && (Objects[i].render_type==RT_MORPH))	{
				morph_data *md;
				md = find_morph_data(&Objects[i]);
				if (md) {					
					md->obj->control_type = md->morph_save_control_type;
					md->obj->movement_type = md->morph_save_movement_type;
					md->obj->render_type = RT_POLYOBJ;
					md->obj->mtype.phys_info = md->morph_save_phys_info;
					md->obj = NULL;
				} else {						//maybe loaded half-morphed from disk
					Objects[i].flags |= OF_SHOULD_BE_DEAD;
					Objects[i].render_type = RT_POLYOBJ;
					Objects[i].control_type = CT_NONE;
					Objects[i].movement_type = MT_NONE;
				}
			}
		}
	
	//Save object info
		i = Highest_object_index+1;
		fwrite( &i, sizeof(int), 1, fp );
		fwrite( Objects, sizeof(object)*i, 1, fp );
		
	//Save wall info
		i = Num_walls;
		fwrite( &i, sizeof(int), 1, fp );
		fwrite( Walls, sizeof(wall)*i, 1, fp );
	
	//Save door info
		i = Num_open_doors;
		fwrite( &i, sizeof(int), 1, fp );
		fwrite( ActiveDoors, sizeof(active_door)*i, 1, fp );
	
	//Save trigger info
		fwrite( &Num_triggers, sizeof(int), 1, fp );
		fwrite( Triggers, sizeof(trigger)*Num_triggers, 1, fp );
	
	//Save tmap info
		for (i=0; i<=Highest_segment_index; i++ )	{
			for (j=0; j<6; j++ )	{
				fwrite( &Segments[i].sides[j].wall_num, sizeof(short), 1, fp );
				fwrite( &Segments[i].sides[j].tmap_num, sizeof(short), 1, fp );
				fwrite( &Segments[i].sides[j].tmap_num2, sizeof(short), 1, fp );
			}
		}
	
	// Save the fuelcen info
		fwrite( &Fuelcen_control_center_destroyed, sizeof(int), 1, fp );
		fwrite( &Fuelcen_seconds_left, sizeof(int), 1, fp );
		fwrite( &Num_robot_centers, sizeof(int), 1, fp );
		fwrite( RobotCenters, sizeof(matcen_info)*Num_robot_centers, 1, fp );
		fwrite( &ControlCenterTriggers, sizeof(control_center_triggers), 1, fp );
		fwrite( &Num_fuelcenters, sizeof(int), 1, fp );
		fwrite( Station, sizeof(FuelCenter)*Num_fuelcenters, 1, fp );
	
	// Save the control cen info
		fwrite( &Control_center_been_hit, sizeof(int), 1, fp );
		fwrite( &Control_center_player_been_seen, sizeof(int), 1, fp );
		fwrite( &Control_center_next_fire_time, sizeof(int), 1, fp );
		fwrite( &Control_center_present, sizeof(int), 1, fp );
		fwrite( &Dead_controlcen_object_num, sizeof(int), 1, fp );
	
	// Save the AI state
		ai_save_state( fp );
	
	// Save the automap visited info
		fwrite( Automap_visited, sizeof(ubyte)*MAX_SEGMENTS, 1, fp );
	}
	fwrite( &state_game_id, sizeof(uint), 1, fp );
	fwrite( &Laser_rapid_fire, sizeof(int), 1, fp );
	fwrite( &Ugly_robot_cheat, sizeof(int), 1, fp );
	fwrite( &Ugly_robot_texture, sizeof(int), 1, fp );
	fwrite( &Physics_cheat_flag, sizeof(int), 1, fp );
	fwrite( &Lunacy, sizeof(int), 1, fp );

	fclose(fp);
	
// set the type and creator of the saved game file

	strcpy(pfilename, filename);
	c2pstr(pfilename);
	err = HGetFInfo(0, 0, pfilename, &finfo);
	finfo.fdType = 'SVGM';
	finfo.fdCreator = 'DCNT';
	err = HSetFInfo(0, 0, pfilename, &finfo);

	start_time();

	return 1;
}
Example #2
0
File: state.c Project: btb/d2x
int state_save_all_sub(char *filename, char *desc, int between_levels)
{
	int i,j;
	PHYSFS_file *fp;
	grs_canvas * cnv;
	ubyte *pal;

	Assert(between_levels == 0);	//between levels save ripped out

/*	if ( Game_mode & GM_MULTI )	{
		{
		start_time();
		return 0;
		}
	}*/

	#if defined(MACINTOSH) && !defined(NDEBUG)
	if ( strncmp(filename, PLAYER_DIR, 9) )
		Int3();
	#endif

	fp = PHYSFSX_openWriteBuffered(filename);
	if ( !fp ) {
		if ( !(Game_mode & GM_MULTI) )
			nm_messagebox(NULL, 1, TXT_OK, "Error writing savegame.\nPossibly out of disk\nspace.");
		start_time();
		return 0;
	}

//Save id
	PHYSFS_write(fp, dgss_id, sizeof(char) * 4, 1);

//Save version
	i = STATE_VERSION;
	PHYSFS_write(fp, &i, sizeof(int), 1);

//Save description
	PHYSFS_write(fp, desc, sizeof(char) * DESC_LENGTH, 1);
	
// Save the current screen shot...

	cnv = gr_create_canvas( THUMBNAIL_W, THUMBNAIL_H );
	if ( cnv )
	{
#ifdef OGL
		ubyte *buf;
		int k;
		GLint gl_draw_buffer;
#endif
		grs_canvas * cnv_save;
		cnv_save = grd_curcanv;

		gr_set_current_canvas( cnv );

		render_frame(0, 0);

#if defined(OGL)
		buf = d_malloc(THUMBNAIL_W * THUMBNAIL_H * 3);
		glGetIntegerv(GL_DRAW_BUFFER, &gl_draw_buffer);
		glReadBuffer(gl_draw_buffer);
		glReadPixels(0, SHEIGHT - THUMBNAIL_H, THUMBNAIL_W, THUMBNAIL_H, GL_RGB, GL_UNSIGNED_BYTE, buf);
		k = THUMBNAIL_H;
		for (i = 0; i < THUMBNAIL_W * THUMBNAIL_H; i++) {
			if (!(j = i % THUMBNAIL_W))
				k--;
			cnv->cv_bitmap.bm_data[THUMBNAIL_W * k + j] =
				gr_find_closest_color(buf[3*i]/4, buf[3*i+1]/4, buf[3*i+2]/4);
		}
		d_free(buf);
#endif

		pal = gr_palette;

		PHYSFS_write(fp, cnv->cv_bitmap.bm_data, THUMBNAIL_W * THUMBNAIL_H, 1);

		gr_set_current_canvas(cnv_save);
		gr_free_canvas( cnv );
		PHYSFS_write(fp, pal, 3, 256);
	}
	else
	{
	 	ubyte color = 0;
	 	for ( i=0; i<THUMBNAIL_W*THUMBNAIL_H; i++ )
			PHYSFS_write(fp, &color, sizeof(ubyte), 1);		
	} 

// Save the Between levels flag...
	PHYSFS_write(fp, &between_levels, sizeof(int), 1);

// Save the mission info...
        mprintf ((0, "HEY! Mission name is %s\n", Current_mission_filename));
	PHYSFS_write(fp, Current_mission_filename, 9 * sizeof(char), 1);

//Save level info
	PHYSFS_write(fp, &Current_level_num, sizeof(int), 1);
	PHYSFS_write(fp, &Next_level_num, sizeof(int), 1);

//Save GameTime
	PHYSFS_write(fp, &GameTime, sizeof(fix), 1);

// If coop save, save all
#ifdef NETWORK
   if (Game_mode & GM_MULTI_COOP)
	 {
		PHYSFS_write(fp, &state_game_id,sizeof(int), 1);
		PHYSFS_write(fp, &Netgame,sizeof(netgame_info), 1);
		PHYSFS_write(fp, &NetPlayers,sizeof(AllNetPlayers_info), 1);
		PHYSFS_write(fp, &N_players,sizeof(int), 1);
		PHYSFS_write(fp, &Player_num,sizeof(int), 1);
		for (i=0;i<N_players;i++)
			PHYSFS_write(fp, &Players[i], sizeof(player), 1);

#ifdef RISKY_PROPOSITION
		PHYSFS_write(fp, &robot_controlled[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_write(fp, &robot_agitation[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_write(fp, &robot_controlled_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_write(fp, &robot_last_send_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_write(fp, &robot_last_message_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_write(fp, &robot_send_pending[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_write(fp, &robot_fired[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
 
      for (i=0;i<MAX_ROBOTS_CONTROLLED;i++)
			PHYSFS_write(fp, robot_fire_buf[i][0], 18 + 3, 1);
#endif

	 }
#endif

//Save player info
	PHYSFS_write(fp, &Players[Player_num], sizeof(player), 1);

// Save the current weapon info
	PHYSFS_write(fp, &Primary_weapon, sizeof(sbyte), 1);
	PHYSFS_write(fp, &Secondary_weapon, sizeof(sbyte), 1);

// Save the difficulty level
	PHYSFS_write(fp, &Difficulty_level, sizeof(int), 1);
// Save cheats enabled
	PHYSFS_write(fp, &Cheats_enabled.intval, sizeof(int), 1);

	if ( !between_levels )	{

	//Finish all morph objects
		for (i=0; i<=Highest_object_index; i++ )	{
			if ( (Objects[i].type != OBJ_NONE) && (Objects[i].render_type==RT_MORPH))	{
				morph_data *md;
				md = find_morph_data(&Objects[i]);
				if (md) {					
					md->obj->control_type = md->morph_save_control_type;
					md->obj->movement_type = md->morph_save_movement_type;
					md->obj->render_type = RT_POLYOBJ;
					md->obj->mtype.phys_info = md->morph_save_phys_info;
					md->obj = NULL;
				} else {						//maybe loaded half-morphed from disk
					Objects[i].flags |= OF_SHOULD_BE_DEAD;
					Objects[i].render_type = RT_POLYOBJ;
					Objects[i].control_type = CT_NONE;
					Objects[i].movement_type = MT_NONE;
				}
			}
		}
	
	//Save object info
		i = Highest_object_index+1;
		PHYSFS_write(fp, &i, sizeof(int), 1);
		PHYSFS_write(fp, Objects, sizeof(object), i);
		
	//Save wall info
		i = Num_walls;
		PHYSFS_write(fp, &i, sizeof(int), 1);
		PHYSFS_write(fp, Walls, sizeof(wall), i);

	//Save exploding wall info
		i = MAX_EXPLODING_WALLS;
		PHYSFS_write(fp, &i, sizeof(int), 1);
		PHYSFS_write(fp, expl_wall_list, sizeof(*expl_wall_list), i);
	
	//Save door info
		i = Num_open_doors;
		PHYSFS_write(fp, &i, sizeof(int), 1);
		PHYSFS_write(fp, ActiveDoors, sizeof(active_door), i);
	
	//Save cloaking wall info
		i = Num_cloaking_walls;
		PHYSFS_write(fp, &i, sizeof(int), 1);
		PHYSFS_write(fp, CloakingWalls, sizeof(cloaking_wall), i);
	
	//Save trigger info
		PHYSFS_write(fp, &Num_triggers, sizeof(int), 1);
		PHYSFS_write(fp, Triggers, sizeof(trigger), Num_triggers);
	
	//Save tmap info
		for (i = 0; i <= Highest_segment_index; i++)
		{
			for (j = 0; j < 6; j++)
			{
				PHYSFS_write(fp, &Segments[i].sides[j].wall_num, sizeof(short), 1);
				PHYSFS_write(fp, &Segments[i].sides[j].tmap_num, sizeof(short), 1);
				PHYSFS_write(fp, &Segments[i].sides[j].tmap_num2, sizeof(short), 1);
			}
		}
	
	// Save the fuelcen info
		PHYSFS_write(fp, &Control_center_destroyed, sizeof(int), 1);
		PHYSFS_write(fp, &Countdown_timer, sizeof(int), 1);
		PHYSFS_write(fp, &Num_robot_centers, sizeof(int), 1);
		PHYSFS_write(fp, RobotCenters, sizeof(matcen_info), Num_robot_centers);
		PHYSFS_write(fp, &ControlCenterTriggers, sizeof(control_center_triggers), 1);
		PHYSFS_write(fp, &Num_fuelcenters, sizeof(int), 1);
		PHYSFS_write(fp, Station, sizeof(FuelCenter), Num_fuelcenters);
	
	// Save the control cen info
		PHYSFS_write(fp, &Control_center_been_hit, sizeof(int), 1);
		PHYSFS_write(fp, &Control_center_player_been_seen, sizeof(int), 1);
		PHYSFS_write(fp, &Control_center_next_fire_time, sizeof(int), 1);
		PHYSFS_write(fp, &Control_center_present, sizeof(int), 1);
		PHYSFS_write(fp, &Dead_controlcen_object_num, sizeof(int), 1);
	
	// Save the AI state
		ai_save_state( fp );
	
	// Save the automap visited info
		PHYSFS_write(fp, Automap_visited, sizeof(ubyte), MAX_SEGMENTS);

	}
	PHYSFS_write(fp, &state_game_id, sizeof(uint), 1);
	PHYSFS_write(fp, &Laser_rapid_fire, sizeof(int), 1);
	PHYSFS_write(fp, &Lunacy, sizeof(int), 1);  //  Yes, writing this twice.  Removed the Ugly robot system, but didn't want to change savegame format.
	PHYSFS_write(fp, &Lunacy, sizeof(int), 1);

	// Save automap marker info

	PHYSFS_write(fp, MarkerObject, sizeof(MarkerObject) ,1);
	PHYSFS_write(fp, MarkerOwner, sizeof(MarkerOwner), 1);
	PHYSFS_write(fp, MarkerMessage, sizeof(MarkerMessage), 1);

	PHYSFS_write(fp, &Afterburner_charge, sizeof(fix), 1);

	//save last was super information
	PHYSFS_write(fp, &Primary_last_was_super, sizeof(Primary_last_was_super), 1);
	PHYSFS_write(fp, &Secondary_last_was_super, sizeof(Secondary_last_was_super), 1);

	//	Save flash effect stuff
	PHYSFS_write(fp, &Flash_effect, sizeof(int), 1);
	PHYSFS_write(fp, &Time_flash_last_played, sizeof(int), 1);
	PHYSFS_write(fp, &PaletteRedAdd, sizeof(int), 1);
	PHYSFS_write(fp, &PaletteGreenAdd, sizeof(int), 1);
	PHYSFS_write(fp, &PaletteBlueAdd, sizeof(int), 1);

	PHYSFS_write(fp, Light_subtracted, sizeof(Light_subtracted[0]), MAX_SEGMENTS);

	PHYSFS_write(fp, &First_secret_visit, sizeof(First_secret_visit), 1);

	if (PHYSFS_write(fp, &Omega_charge, sizeof(Omega_charge), 1) < 1)
	{
		if ( !(Game_mode & GM_MULTI) ) {
			nm_messagebox(NULL, 1, TXT_OK, "Error writing savegame.\nPossibly out of disk\nspace.");
			PHYSFS_close(fp);
			PHYSFS_delete(filename);
		}
	} else  {
		PHYSFS_close(fp);

		#ifdef MACINTOSH		// set the type and creator of the saved game file
		{
			FInfo finfo;
			OSErr err;
			Str255 pfilename;
	
			strcpy(pfilename, filename);
			c2pstr(pfilename);
			err = HGetFInfo(0, 0, pfilename, &finfo);
			finfo.fdType = 'SVGM';
			finfo.fdCreator = 'DCT2';
			err = HSetFInfo(0, 0, pfilename, &finfo);
		}
		#endif
	}
	
	start_time();

	return 1;
}