Beispiel #1
0
void update_dynamics_at_keysite (void)
{

	unsigned int
		model_damage,
		damage_count,
		this_damage;

	if ((!get_keysite_currently_landed_at ()) || (!get_gunship_entity ()))
	{

		return;
	}

	//
	// Refuel, only set if inside keysite
	//

	#if !DEMO_VERSION

	if (current_flight_dynamics->refuelling)
	{
		entity
			*keysite;

		float
			max_fuel;

		if (!(current_flight_dynamics->dynamics_damage & DYNAMICS_DAMAGE_FUEL_LEAK))
		{

			//#if DYNAMICS_DEBUG

			debug_log ("DYNAMICS: refuelling, fuel = %f (max = %f)", current_flight_dynamics->fuel_weight.value, current_flight_dynamics->fuel_weight.max);

			//#endif

			max_fuel = current_flight_dynamics->fuel_weight.max;

			keysite = get_keysite_currently_landed_at ();

			if (keysite)
			{

				if (get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL) <= 0.0)
				{

					if (!get_connection_list_head ())
					{

						max_fuel *= 0.25;
					}
				}
			}

			if (current_flight_dynamics->fuel_weight.value >= max_fuel)
			{

				current_flight_dynamics->refuelling = FALSE;
			}
			else
			{

				current_flight_dynamics->fuel_weight.value += REFUELLING_RATE * get_delta_time ();
			}

			current_flight_dynamics->fuel_weight.value = bound (current_flight_dynamics->fuel_weight.value,
																				current_flight_dynamics->fuel_weight.min,
																				current_flight_dynamics->fuel_weight.max);
		}
		else
		{

			debug_log ("DYNAMICS: can't refuel till leak is fixed");
		}
	}

	#endif

	//
	// Repair, only set if inside keysite
	//

	if (current_flight_dynamics->repairing)
	{

		if (current_flight_dynamics->dynamics_damage != DYNAMICS_DAMAGE_NONE)
		{

			current_flight_dynamics->damage_repair_time -= get_delta_time ();

			current_flight_dynamics->damage_repair_time = max (current_flight_dynamics->damage_repair_time, 0.0);

			#if DYNAMICS_DEBUG

			debug_log ("DYNAMICS: repairing %d, repair time %f seconds", current_flight_dynamics->damage_repair_time, current_flight_dynamics->damage_repair_time);

			#endif

			//
			// set repair timer to time to repair each part in turn
			//

			if (current_flight_dynamics->damage_repair_time <= 0.0)
			{

				// clear repaired damage
				if ((current_flight_dynamics->repairing_damage != DYNAMICS_DAMAGE_NONE) &&
					(current_flight_dynamics->dynamics_damage & current_flight_dynamics->repairing_damage))
				{

					repair_damage_model (current_flight_dynamics->repairing_damage);
				}

				current_flight_dynamics->repairing_damage = DYNAMICS_DAMAGE_NONE;

				// start repairing next
				this_damage = DYNAMICS_DAMAGE_NONE;

				damage_count = 0;

				model_damage = current_flight_dynamics->dynamics_damage;

				while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES)
				{

					if ((model_damage & this_damage) && (dynamics_damage_database [damage_count].repairable))
					{

						current_flight_dynamics->damage_repair_time = dynamics_damage_database [damage_count].repair_time;

						current_flight_dynamics->repairing_damage = this_damage;

						#if DEBUG_MODULE

						debug_log ("DYNAMICS: repairing %s, repair time %f seconds", dynamics_damage_database [damage_count].name, current_flight_dynamics->damage_repair_time);

						#endif

						break;
					}

					damage_count ++;

					this_damage = this_damage << 1;
				}

				if (current_flight_dynamics->repairing_damage == DYNAMICS_DAMAGE_NONE)
				{

					#if DEBUG_MODULE

					debug_log ("DYNAMICS: model fully repaired");

					#endif

					restore_helicopter_entity (get_gunship_entity (), NULL, get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE));

					set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_DAMAGE_LEVEL, get_local_entity_int_value (get_gunship_entity (), INT_TYPE_INITIAL_DAMAGE_LEVEL));

					transmit_entity_comms_message (ENTITY_COMMS_RESTORE_ENTITY, get_gunship_entity (), get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION), get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE));
				}
			}
		}
	}
}
Beispiel #2
0
/* x is between 0 and 1. 1 becomes 0dB and 0 becomes dBFloor (-ve) */
double linear2dB(double x, double dbFloor) {
    return (x > 0.0) ? bound((log10(x) * 20.0), dbFloor, 0.0) : dbFloor;
}
Beispiel #3
0
double dB2Normalised(double x, double theCeiling, double theFloor) {
    return bound(1.0 + ((x-theCeiling) / (theCeiling-theFloor)), 0.0, 1.0);
}
Beispiel #4
0
void Host_Main(void)
{
	double time1 = 0;
	double time2 = 0;
	double time3 = 0;
	double cl_timer = 0, sv_timer = 0;
	double clframetime, deltacleantime, olddirtytime, dirtytime;
	double wait;
	int pass1, pass2, pass3, i;
	char vabuf[1024];
	qboolean playing;

	Host_Init();

	realtime = 0;
	host_dirtytime = Sys_DirtyTime();
	for (;;)
	{
		if (setjmp(host_abortframe))
		{
			SCR_ClearLoadingScreen(false);
			continue;			// something bad happened, or the server disconnected
		}

		olddirtytime = host_dirtytime;
		dirtytime = Sys_DirtyTime();
		deltacleantime = dirtytime - olddirtytime;
		if (deltacleantime < 0)
		{
			// warn if it's significant
			if (deltacleantime < -0.01)
				Con_Printf("Host_Mingled: time stepped backwards (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
			deltacleantime = 0;
		}
		else if (deltacleantime >= 1800)
		{
			Con_Printf("Host_Mingled: time stepped forward (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
			deltacleantime = 0;
		}
		realtime += deltacleantime;
		host_dirtytime = dirtytime;

		cl_timer += deltacleantime;
		sv_timer += deltacleantime;

		if (!svs.threaded)
		{
			svs.perf_acc_realtime += deltacleantime;

			// Look for clients who have spawned
			playing = false;
			for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
				if(host_client->begun)
					if(host_client->netconnection)
						playing = true;
			if(sv.time < 10)
			{
				// don't accumulate time for the first 10 seconds of a match
				// so things can settle
				svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
			}
			else if(svs.perf_acc_realtime > 5)
			{
				svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime;
				svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime;
				if(svs.perf_acc_offset_samples > 0)
				{
					svs.perf_offset_max = svs.perf_acc_offset_max;
					svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples;
					svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
				}
				if(svs.perf_lost > 0 && developer_extra.integer)
					if(playing) // only complain if anyone is looking
						Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
				svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
			}
		}

		if (slowmo.value < 0.00001 && slowmo.value != 0)
			Cvar_SetValue("slowmo", 0);
		if (host_framerate.value < 0.00001 && host_framerate.value != 0)
			Cvar_SetValue("host_framerate", 0);

		// keep the random time dependent, but not when playing demos/benchmarking
		if(!*sv_random_seed.string && !cls.demoplayback)
			rand();

		// get new key events
		Key_EventQueue_Unblock();
		SndSys_SendKeyEvents();
		Sys_SendKeyEvents();

		NetConn_UpdateSockets();

		Log_DestBuffer_Flush();

		// receive packets on each main loop iteration, as the main loop may
		// be undersleeping due to select() detecting a new packet
		if (sv.active && !svs.threaded)
			NetConn_ServerFrame();

		Curl_Run();

		// check for commands typed to the host
		Host_GetConsoleCommands();

		// when a server is running we only execute console commands on server frames
		// (this mainly allows frikbot .way config files to work properly by staying in sync with the server qc)
		// otherwise we execute them on client frames
		if (sv.active ? sv_timer > 0 : cl_timer > 0)
		{
			// process console commands
//			R_TimeReport("preconsole");
			CL_VM_PreventInformationLeaks();
			Cbuf_Frame();
//			R_TimeReport("console");
		}

		//Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0);

		// if the accumulators haven't become positive yet, wait a while
		if (cls.state == ca_dedicated)
			wait = sv_timer * -1000000.0;
		else if (!sv.active || svs.threaded)
			wait = cl_timer * -1000000.0;
		else
			wait = max(cl_timer, sv_timer) * -1000000.0;

		if (!cls.timedemo && wait >= 1)
		{
			double time0, delta;

			if(host_maxwait.value <= 0)
				wait = min(wait, 1000000.0);
			else
				wait = min(wait, host_maxwait.value * 1000.0);
			if(wait < 1)
				wait = 1; // because we cast to int

			time0 = Sys_DirtyTime();
			if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) {
				NetConn_SleepMicroseconds((int)wait);
				if (cls.state != ca_dedicated)
					NetConn_ClientFrame(); // helps server browser get good ping values
				// TODO can we do the same for ServerFrame? Probably not.
			}
			else
				Sys_Sleep((int)wait);
			delta = Sys_DirtyTime() - time0;
			if (delta < 0 || delta >= 1800) delta = 0;
			if (!svs.threaded)
				svs.perf_acc_sleeptime += delta;
//			R_TimeReport("sleep");
			continue;
		}

		// limit the frametime steps to no more than 100ms each
		if (cl_timer > 0.1)
			cl_timer = 0.1;
		if (sv_timer > 0.1)
		{
			if (!svs.threaded)
				svs.perf_acc_lost += (sv_timer - 0.1);
			sv_timer = 0.1;
		}

		R_TimeReport("---");

	//-------------------
	//
	// server operations
	//
	//-------------------

		// limit the frametime steps to no more than 100ms each
		if (sv.active && sv_timer > 0 && !svs.threaded)
		{
			// execute one or more server frames, with an upper limit on how much
			// execution time to spend on server frames to avoid freezing the game if
			// the server is overloaded, this execution time limit means the game will
			// slow down if the server is taking too long.
			int framecount, framelimit = 1;
			double advancetime, aborttime = 0;
			float offset;
			prvm_prog_t *prog = SVVM_prog;

			// run the world state
			// don't allow simulation to run too fast or too slow or logic glitches can occur

			// stop running server frames if the wall time reaches this value
			if (sys_ticrate.value <= 0)
				advancetime = sv_timer;
			else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
			{
				// synchronize to the client frametime, but no less than 10ms and no more than 100ms
				advancetime = bound(0.01, cl_timer, 0.1);
			}
			else
			{
				advancetime = sys_ticrate.value;
				// listen servers can run multiple server frames per client frame
				framelimit = cl_maxphysicsframesperserverframe.integer;
				aborttime = Sys_DirtyTime() + 0.1;
			}
			if(slowmo.value > 0 && slowmo.value < 1)
				advancetime = min(advancetime, 0.1 / slowmo.value);
			else
				advancetime = min(advancetime, 0.1);

			if(advancetime > 0)
			{
				offset = Sys_DirtyTime() - dirtytime;if (offset < 0 || offset >= 1800) offset = 0;
				offset += sv_timer;
				++svs.perf_acc_offset_samples;
				svs.perf_acc_offset += offset;
				svs.perf_acc_offset_squared += offset * offset;
				if(svs.perf_acc_offset_max < offset)
					svs.perf_acc_offset_max = offset;
			}

			// only advance time if not paused
			// the game also pauses in singleplayer when menu or console is used
			sv.frametime = advancetime * slowmo.value;
			if (host_framerate.value)
				sv.frametime = host_framerate.value;
			if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
				sv.frametime = 0;

			for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
			{
				sv_timer -= advancetime;

				// move things around and think unless paused
				if (sv.frametime)
					SV_Physics();

				// if this server frame took too long, break out of the loop
				if (framelimit > 1 && Sys_DirtyTime() >= aborttime)
					break;
			}
			R_TimeReport("serverphysics");

			// send all messages to the clients
			SV_SendClientMessages();

			if (sv.paused == 1 && realtime > sv.pausedstart && sv.pausedstart > 0) {
				prog->globals.fp[OFS_PARM0] = realtime - sv.pausedstart;
				PRVM_serverglobalfloat(time) = sv.time;
				prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
			}

			// send an heartbeat if enough time has passed since the last one
			NetConn_Heartbeat(0);
			R_TimeReport("servernetwork");
		}
		else if (!svs.threaded)
		{
			// don't let r_speeds display jump around
			R_TimeReport("serverphysics");
			R_TimeReport("servernetwork");
		}

	//-------------------
	//
	// client operations
	//
	//-------------------

		if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1)))
		{
			R_TimeReport("---");
			Collision_Cache_NewFrame();
			R_TimeReport("photoncache");
			// decide the simulation time
			if (cls.capturevideo.active)
			{
				//***
				if (cls.capturevideo.realtime)
					clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate);
				else
				{
					clframetime = 1.0 / cls.capturevideo.framerate;
					cl.realframetime = max(cl_timer, clframetime);
				}
			}
			else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo)
			{
				clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value);
				// when running slow, we need to sleep to keep input responsive
				wait = bound(0, cl_maxfps_alwayssleep.value * 1000, 100000);
				if (wait > 0)
					Sys_Sleep((int)wait);
			}
			else if (!vid_activewindow && cl_maxidlefps.value >= 1 && !cls.timedemo)
				clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxidlefps.value);
			else
				clframetime = cl.realframetime = cl_timer;

			// apply slowmo scaling
			clframetime *= cl.movevars_timescale;
			// scale playback speed of demos by slowmo cvar
			if (cls.demoplayback)
			{
				clframetime *= slowmo.value;
				// if demo playback is paused, don't advance time at all
				if (cls.demopaused)
					clframetime = 0;
			}
			else
			{
				// host_framerate overrides all else
				if (host_framerate.value)
					clframetime = host_framerate.value;

				if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
					clframetime = 0;
			}

			if (cls.timedemo)
				clframetime = cl.realframetime = cl_timer;

			// deduct the frame time from the accumulator
			cl_timer -= cl.realframetime;

			cl.oldtime = cl.time;
			cl.time += clframetime;

			// update video
			if (host_speeds.integer)
				time1 = Sys_DirtyTime();
			R_TimeReport("pre-input");

			// Collect input into cmd
			CL_Input();

			R_TimeReport("input");

			// check for new packets
			NetConn_ClientFrame();

			// read a new frame from a demo if needed
			CL_ReadDemoMessage();
			R_TimeReport("clientnetwork");

			// now that packets have been read, send input to server
			CL_SendMove();
			R_TimeReport("sendmove");

			// update client world (interpolate entities, create trails, etc)
			CL_UpdateWorld();
			R_TimeReport("lerpworld");

			CL_Video_Frame();

			R_TimeReport("client");

			CL_UpdateScreen();
			CL_MeshEntities_Reset();
			R_TimeReport("render");

			if (host_speeds.integer)
				time2 = Sys_DirtyTime();

			// update audio
			if(cl.csqc_usecsqclistener)
			{
				S_Update(&cl.csqc_listenermatrix);
				cl.csqc_usecsqclistener = false;
			}
			else
				S_Update(&r_refdef.view.matrix);

			CDAudio_Update();
			R_TimeReport("audio");

			// reset gathering of mouse input
			in_mouse_x = in_mouse_y = 0;

			if (host_speeds.integer)
			{
				pass1 = (int)((time1 - time3)*1000000);
				time3 = Sys_DirtyTime();
				pass2 = (int)((time2 - time1)*1000000);
				pass3 = (int)((time3 - time2)*1000000);
				Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n",
							pass1+pass2+pass3, pass1, pass2, pass3);
			}
		}

#if MEMPARANOIA
		Mem_CheckSentinelsGlobal();
#else
		if (developer_memorydebug.integer)
			Mem_CheckSentinelsGlobal();
#endif

		// if there is some time remaining from this frame, reset the timers
		if (cl_timer >= 0)
			cl_timer = 0;
		if (sv_timer >= 0)
		{
			if (!svs.threaded)
				svs.perf_acc_lost += sv_timer;
			sv_timer = 0;
		}

		host_framecount++;
	}
}
int main(int argc, char **argv)
{
	key_data key;

	int inc = 10;
	int num_trials = 1;

	// Initialize the microblaze platform...
	init_platform();
	
	// Set up the attack incremement
	if (inc > 0) 
	{
		inc = 1 << inc;
	}
	printf("\nStudy increment: %d", inc);

	// Display the algorithm.
	printf("\nUsing algorithm \"%s\"", alg_name());
	printf("\nAttacking key \"%s\"", argv[1]);

	// Display the number of trials...
	if (num_trials != 1)
	{
		printf("\nNumber of trials: %d", num_trials);
	}

	/*
	else if (out_file)
		printf("\nOutputting to file: %s", out_file);
	else if (in_file)
		printf("\nReading from file: %s", in_file);
	*/

#ifdef NONE_AES
	printf("\nAttacking NONE_AES_CORE implementation");
#elif defined(SMALL_AES)
	printf("\nAttacking SMALL_AES_CORE implementation");
#else
	printf("\nAttacking traditional AES_CORE implementation");
#endif

#ifdef DECRYPT_MODE
	printf("\nDECRYPT MODE");
#else
	printf("\nENCRYPT MODE");
#endif

	cache_evict_init();

	int * results = malloc(num_trials * sizeof(int));

	timing_pair * buffer = malloc(BUF_SIZE * sizeof(timing_pair));
	timing_data * data = malloc(sizeof(timing_data));

	if (data == 0x0)
	{
		printf("Data couldn't allocate.\n");
		return;
	}
	if (buffer == 0x0)
	{
		printf("Buffer couldn't allocate.\n");
		return;
	}

	FILE * in;
	//if (!USE_RANDOM_KEY)
	{
		printf("Initializing random key...\n");
		re_key(&key, argv[1]);
	}

	fflush(stdout);

	/*
	if (out_file)
	{
		output_timings(out_file, buffer, inc, &key);
		return 1;
	}

	if (in_file)
	{
		char open_type = 'r';
		in = fopen(in_file, &open_type);

		if (in == NULL)
		{
			printf("\nCould not open file: %s", in_file);
			return -1;
		}
	}
	*/

	int round, i;
	for (round = 1; round <= num_trials; round++)
	{
		printf("\nBeginning Attack #%d\n", round);

		init_data(data);

		//if (USE_RANDOM_KEY)
		// reseed with a random key
		re_key(&key, "/dev/random");

		long long num_studies = 0;

		double clip_time = 0;

		int success = 0;

		long long max = MAX_STUDY;

		while (num_studies < max && !success)
		{
			printf("num_studies = %d\n", num_studies);

			int offset = num_studies % BUF_SIZE;
			if (inc > BUF_SIZE)
			{
				int read = 0;
				int num_read = BUF_SIZE;
				while (read < inc)
				{
					//printf("read = %d\n", read);
					generate_samples(buffer, &key);
					printf("buffer address %x:\n", buffer);
					printf("data address = %x\n", data);
					clip_time = calculate_clip_time(buffer, num_read);

					for (i = 0; i < BUF_SIZE && read < inc; i++)
					{
						//printf("i = %d\n", i);
						if (buffer[offset + i].time < clip_time)
							record_timing(data, &buffer[offset + i]);

						read++;
					}
				}
			}
			else
			{
				printf("inc <= BUF_SIZE\n");
				if (offset == 0)
				{

					int num_read = BUF_SIZE;

					//if (!in_file)
					generate_samples(buffer, &key);
					printf("generate_samples done\n");
					/*else
					{
						num_read = fread(buffer, sizeof(timing_pair), BUF_SIZE,
								in);
						if (num_read < BUF_SIZE)
							max = num_studies + num_read;

						printf("\nRead in %d samples ", num_read);
					}*/
					clip_time = calculate_clip_time(buffer, num_read);
					printf("clip_time done\n");
				}

				for (i = 0; i < inc; i++)
					printf("i (inc) = %d\n", i);
					if (buffer[offset + i].time < clip_time)
						record_timing(data, &buffer[offset + i]);
			}
			num_studies += inc;

			printf("\nchecking data!\n");
			if (check_data(data, &key))
			{
				printf(
						"\nKey recovered after studying %lld samples (< 2^%d)\n",
						num_studies, bound(num_studies));

				success = 1;
			}
			else
				printf("\nNo success after studying %d samples", num_studies);
		}
		if (!success)
			printf("Attack failed after %d encryptions", num_studies);

		else
		{

			int j = round - 1;

			while (j > 0 && results[j - 1] > num_studies)
			{
				results[j] = results[j - 1];
				j--;
			}

			results[j] = num_studies;

			printf("\nResults: ");

			int total = 0;

			for (j = 0; j < round; j++)
			{
				printf("  %d ", results[j]);
				total += results[j];
			}

			printf("\nMin: %d", results[0]);
			printf("\nMax: %d", results[round - 1]);

			printf("\nMed: %d", results[round / 2]);
			printf("\nMean: %.2f", ((double) total) / round);

		}
	}

	// Clean up and terminate...
	cleanup_platform();
}
Beispiel #6
0
static unsigned int DI_BufSize(void)
{
	return bound(16, in_di_bufsize.integer, 256);
}
Beispiel #7
0
//================
//CG_DrawMiniMap
//================
void CG_DrawMiniMap( int x, int y, int iw, int ih, qboolean draw_playernames, qboolean draw_itemnames, int align, vec4_t color )
{
	int i, entnum;
	centity_t *cent;
	vec3_t coords;
	vec4_t tmp_col, tmp_white_alpha, tmp_yellow_alpha;		// background color of the map
	vec3_t mins, maxs, extend;
	int map_w, map_h, map_z;
	int x_lefttop, y_lefttop, z_lefttop;	// the negative y coordinate (bottom of the map)
	float map_div_w, map_div_h;
	qboolean isSelf;

	if( !cg_showminimap->integer )
		return;

	// if inside a team
	if( cg.predictedPlayerState.stats[STAT_REALTEAM] >= TEAM_PLAYERS && cg.predictedPlayerState.stats[STAT_REALTEAM] < GS_MAX_TEAMS )
	{
		if( !GS_CanShowMinimap() || !( cg_showminimap->integer & 1 ) )
			return;
	}
	else if( !( cg_showminimap->integer & 2 ) )
	{
		// allow only when chasing a player and the player is allowed to see it
		if( !GS_CanShowMinimap() || !( cg_showminimap->integer & 1 ) ||
			cg.predictedPlayerState.stats[STAT_REALTEAM] == cg.predictedPlayerState.stats[STAT_TEAM] )
			return;
	}

	if( !cgs.shaderMiniMap )
		return;

	x = CG_HorizontalAlignForWidth( x, align, iw );
	y = CG_VerticalAlignForHeight( y, align, ih );

	Vector4Copy( color, tmp_col );
	Vector4Copy( colorWhite, tmp_white_alpha );
	Vector4Copy( colorYellow, tmp_yellow_alpha );
	tmp_white_alpha[3] = color[3];
	tmp_yellow_alpha[3] = color[3];

	// Get Worldmodel bounds...
	trap_R_ModelBounds( NULL, mins, maxs ); // NULL for world model...

	// make it a square bounding box
	VectorSubtract( maxs, mins, extend );
	if( extend[1] > extend[0] )
	{
		mins[0] -= ( extend[1] - extend[0] ) * 0.5;
		maxs[0] += ( extend[1] - extend[0] ) * 0.5;
	}
	else
	{
		mins[1] -= ( extend[0] - extend[1] ) * 0.5;
		maxs[1] += ( extend[0] - extend[1] ) * 0.5;
	}

	map_w = maxs[0] - mins[0];      // map width (in game units)
	map_h = maxs[1] - mins[1];
	map_z = maxs[2] - mins[2];
	x_lefttop = -mins[0];   // the negative x coordinate ( left of the map )
	y_lefttop = -mins[1];   // the negative y coordinate (bottom of the map)
	z_lefttop = -mins[2];   // the negative y coordinate (bottom of the map)

	map_div_w = (float)map_w / (float)iw;
	map_div_h = (float)map_h / (float)ih;

	CG_DrawHUDRect( x, y, ALIGN_LEFT_TOP, iw, ih, 1, 1, tmp_col, cgs.shaderMiniMap );

	//alignment test, to display green dot at 0,0
	//CG_DrawHUDRect( x + x_lefttop/map_div_w -1, y + y_lefttop/map_div_h -1,ALIGN_LEFT_TOP,3,3,1,1, colorGreen, CG_MediaShader( cgs.media.shaderMiniMap ) );

	for( i = 0; i < cg.frame.numEntities; i++ )
	{
		entnum = cg.frame.parsedEntities[i&( MAX_PARSE_ENTITIES-1 )].number;

		// filter invalid ents
		if( entnum < 1 || entnum >= MAX_EDICTS )
			continue;

		// retrieve the centity_t
		cent = &cg_entities[entnum];
		isSelf = ( (unsigned)entnum == cg.predictedPlayerState.POVnum );

		if( ( cent->current.type != ET_PLAYER ) 
			&& ( cent->current.type != ET_MINIMAP_ICON )
			&& !( cent->item ) )
			continue;

		if( isSelf )
			VectorCopy( cg.predictedPlayerState.pmove.origin, coords );
		else
			VectorCopy( cent->current.origin, coords );

		coords[0] = ( coords[0] + x_lefttop ) / map_div_w;
		coords[1] = ih - ( coords[1] + y_lefttop ) / map_div_h;
		coords[2] = ( coords[2] + (float)z_lefttop ) / (float)map_z;

		// is it a player?
		if( ( cent->current.type == ET_PLAYER ) )
		{
			int box_size = (int)( 3.0 + coords[2] * 10.0 );

			// check if we're allowed to see team members only (coaches, CA)
			if( cg.predictedPlayerState.stats[STAT_LAYOUTS] & STAT_LAYOUT_SPECTEAMONLY ||
				(cg.predictedPlayerState.stats[STAT_REALTEAM] != TEAM_SPECTATOR && GS_TeamOnlyMinimap()) )
			{
				if( cg.predictedPlayerState.stats[STAT_REALTEAM] != cent->current.team )
					continue;
			}

			if( cent->current.team == TEAM_SPECTATOR )
			{
				if( entnum != cg.view.POVent )
					continue;
				VectorSet( tmp_col, 1, 1, 1 );
			}
			else
			{
				CG_TeamColor( cent->current.team, tmp_col );
			}

			// get color
			tmp_col[3] = bound( 0, color[3] + 0.3f, 1 );
			CG_DrawHUDRect( x + (int)coords[0] -box_size/2, y + (int)coords[1] -box_size/2,
				ALIGN_LEFT_TOP, box_size, box_size, box_size, box_size, tmp_col, NULL );

			// differentiate ourselves with an arrow
			if( isSelf )
			{
				int thisX, thisY, thisSize;

				thisSize = max( box_size, 8 );
				thisX = CG_VerticalAlignForHeight( x + (int)coords[0], ALIGN_CENTER_MIDDLE, thisSize );
				thisY = CG_VerticalAlignForHeight( y + (int)coords[1] - thisSize, ALIGN_CENTER_MIDDLE, thisSize );
				trap_R_DrawStretchPic( thisX, thisY, thisSize, thisSize, 0, 0, 1, 1, tmp_yellow_alpha, CG_MediaShader( cgs.media.shaderDownArrow ) );
			}

			// do we want names too?
			if( draw_playernames == qtrue )
				trap_SCR_DrawString( x + (int)coords[0] + 8,
				y + (int)coords[1] - 4,	ALIGN_LEFT_TOP,	COM_RemoveColorTokensExt( cgs.clientInfo[cent->current.number-1].name, qtrue ),
				cgs.fontSystemSmall, tmp_yellow_alpha );
		}
		else if( cent->current.type == ET_MINIMAP_ICON )
		{
			if( cent->ent.customShader )
			{
				vec4_t tmp_this_color;
				int thisX, thisY, thisSize;

				thisSize = (float)cent->prev.frame + (float)( cent->current.frame - cent->prev.frame ) * cg.lerpfrac;
				if( thisSize <= 0 )
					thisSize = 18;

				tmp_this_color[0] = (float)cent->ent.shaderRGBA[0] / 255.0f;
				tmp_this_color[1] = (float)cent->ent.shaderRGBA[1] / 255.0f;
				tmp_this_color[2] = (float)cent->ent.shaderRGBA[2] / 255.0f;
				tmp_this_color[3] = 1.0f;

				thisX = CG_VerticalAlignForHeight( x + coords[0], ALIGN_CENTER_MIDDLE, thisSize );
				thisY = CG_VerticalAlignForHeight( y + coords[1], ALIGN_CENTER_MIDDLE, thisSize );
				trap_R_DrawStretchPic( thisX, thisY, thisSize, thisSize, 0, 0, 1, 1, tmp_this_color, cent->ent.customShader );
			}
		}
		else if( cent->item && cent->item->icon )
		{
			// if ALIGN_CENTER_MIDDLE or something is used, images are f****d
			// so thats why they are set manually at the correct pos with -n
			CG_DrawHUDRect( x+(int)coords[0]-8, y+(int)coords[1]-8, ALIGN_LEFT_TOP, 15, 15, 1, 1, tmp_white_alpha, trap_R_RegisterPic( cent->item->icon ) );
			if( draw_itemnames == qtrue )
				trap_SCR_DrawString( x + (int)coords[0] + 16, y + (int)coords[1] - 8, ALIGN_LEFT_TOP, cent->item->shortname, cgs.fontSystemSmall, tmp_yellow_alpha );
		}
	}
}
Beispiel #8
0
void CameraClimbMode::Initialize() {
	angle = bound(Robot::cameraTilt->getAngle(), C_MIN, C_MAX);
}
Beispiel #9
0
void SCR_CaptureVideo_Ogg_BeginVideo(void)
{
	char vabuf[1024];
	cls.capturevideo.format = CAPTUREVIDEOFORMAT_OGG_VORBIS_THEORA;
	cls.capturevideo.formatextension = "ogv";
	cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
	cls.capturevideo.endvideo = SCR_CaptureVideo_Ogg_EndVideo;
	cls.capturevideo.videoframes = SCR_CaptureVideo_Ogg_VideoFrames;
	cls.capturevideo.soundframe = SCR_CaptureVideo_Ogg_SoundFrame;
	cls.capturevideo.formatspecific = Mem_Alloc(tempmempool, sizeof(capturevideostate_ogg_formatspecific_t));
	{
		LOAD_FORMATSPECIFIC_OGG();
		int num, denom, i;
		ogg_page pg;
		ogg_packet pt, pt2, pt3;
		theora_comment tc;
		vorbis_comment vc;
		theora_info ti;
		int vp3compat;

		format->serial1 = xrand();
		qogg_stream_init(&format->to, format->serial1);

		if(cls.capturevideo.soundrate)
		{
			do
			{
				format->serial2 = xrand();
			}
			while(format->serial1 == format->serial2);
			qogg_stream_init(&format->vo, format->serial2);
		}

		format->videopage.len = format->audiopage.len = 0;

		qtheora_info_init(&ti);
		ti.frame_width = cls.capturevideo.width;
		ti.frame_height = cls.capturevideo.height;
		ti.width = (ti.frame_width + 15) & ~15;
		ti.height = (ti.frame_height + 15) & ~15;
		//ti.offset_x = ((ti.width - ti.frame_width) / 2) & ~1;
		//ti.offset_y = ((ti.height - ti.frame_height) / 2) & ~1;

		for(i = 0; i < 2; ++i)
		{
			format->yuv[i].y_width = ti.width;
			format->yuv[i].y_height = ti.height;
			format->yuv[i].y_stride = ti.width;
			format->yuv[i].uv_width = ti.width / 2;
			format->yuv[i].uv_height = ti.height / 2;
			format->yuv[i].uv_stride = ti.width / 2;
			format->yuv[i].y = (unsigned char *) Mem_Alloc(tempmempool, format->yuv[i].y_stride * format->yuv[i].y_height);
			format->yuv[i].u = (unsigned char *) Mem_Alloc(tempmempool, format->yuv[i].uv_stride * format->yuv[i].uv_height);
			format->yuv[i].v = (unsigned char *) Mem_Alloc(tempmempool, format->yuv[i].uv_stride * format->yuv[i].uv_height);
		}
		format->yuvi = -1; // -1: no frame valid yet, write into 0

		FindFraction(cls.capturevideo.framerate / cls.capturevideo.framestep, &num, &denom, 1001);
		ti.fps_numerator = num;
		ti.fps_denominator = denom;

		FindFraction(1 / vid_pixelheight.value, &num, &denom, 1000);
		ti.aspect_numerator = num;
		ti.aspect_denominator = denom;

		ti.colorspace = OC_CS_UNSPECIFIED;
		ti.pixelformat = OC_PF_420;

		ti.quick_p = true; // http://mlblog.osdir.com/multimedia.ogg.theora.general/2004-07/index.shtml
		ti.dropframes_p = false;

		ti.target_bitrate = cl_capturevideo_ogg_theora_bitrate.integer * 1000;
		ti.quality = cl_capturevideo_ogg_theora_quality.integer;

		if(ti.target_bitrate <= 0)
		{
			ti.target_bitrate = -1;
			ti.keyframe_data_target_bitrate = (unsigned int)-1;
		}
		else
		{
			ti.keyframe_data_target_bitrate = (int) (ti.target_bitrate * max(1, cl_capturevideo_ogg_theora_keyframe_bitrate_multiplier.value));

			if(ti.target_bitrate < 45000 || ti.target_bitrate > 2000000)
				Con_DPrintf("WARNING: requesting an odd bitrate for theora (sensible values range from 45 to 2000 kbps)\n");
		}

		if(ti.quality < 0 || ti.quality > 63)
		{
			ti.quality = 63;
			if(ti.target_bitrate <= 0)
			{
				ti.target_bitrate = 0x7FFFFFFF;
				ti.keyframe_data_target_bitrate = 0x7FFFFFFF;
			}
		}

		// this -1 magic is because ti.keyframe_frequency and ti.keyframe_mindistance use different metrics
		ti.keyframe_frequency = bound(1, cl_capturevideo_ogg_theora_keyframe_maxinterval.integer, 1000);
		ti.keyframe_mindistance = bound(1, cl_capturevideo_ogg_theora_keyframe_mininterval.integer, (int) ti.keyframe_frequency) - 1;
		ti.noise_sensitivity = bound(0, cl_capturevideo_ogg_theora_noise_sensitivity.integer, 6);
		ti.sharpness = bound(0, cl_capturevideo_ogg_theora_sharpness.integer, 2);
		ti.keyframe_auto_threshold = bound(0, cl_capturevideo_ogg_theora_keyframe_auto_threshold.integer, 100);

		ti.keyframe_frequency_force = ti.keyframe_frequency;
		ti.keyframe_auto_p = (ti.keyframe_frequency != ti.keyframe_mindistance + 1);

		qtheora_encode_init(&format->ts, &ti);
		qtheora_info_clear(&ti);

		if(cl_capturevideo_ogg_theora_vp3compat.integer)
		{
			vp3compat = 1;
			qtheora_control(&format->ts, TH_ENCCTL_SET_VP3_COMPATIBLE, &vp3compat, sizeof(vp3compat));
			if(!vp3compat)
				Con_DPrintf("Warning: theora stream is not fully VP3 compatible\n");
		}

		// vorbis?
		if(cls.capturevideo.soundrate)
		{
			qvorbis_info_init(&format->vi);
			qvorbis_encode_init_vbr(&format->vi, cls.capturevideo.soundchannels, cls.capturevideo.soundrate, bound(-1, cl_capturevideo_ogg_vorbis_quality.value, 10) * 0.099);
			qvorbis_comment_init(&vc);
			qvorbis_analysis_init(&format->vd, &format->vi);
			qvorbis_block_init(&format->vd, &format->vb);
		}

		qtheora_comment_init(&tc);

		/* create the remaining theora headers */
		qtheora_encode_header(&format->ts, &pt);
		qogg_stream_packetin(&format->to, &pt);
		if (qogg_stream_pageout (&format->to, &pg) != 1)
			fprintf (stderr, "Internal Ogg library error.\n");
		FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
		FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);

		qtheora_encode_comment(&tc, &pt);
		qogg_stream_packetin(&format->to, &pt);
		qtheora_encode_tables(&format->ts, &pt);
		qogg_stream_packetin (&format->to, &pt);

		qtheora_comment_clear(&tc);

		if(cls.capturevideo.soundrate)
		{
			qvorbis_analysis_headerout(&format->vd, &vc, &pt, &pt2, &pt3);
			qogg_stream_packetin(&format->vo, &pt);
			if (qogg_stream_pageout (&format->vo, &pg) != 1)
				fprintf (stderr, "Internal Ogg library error.\n");
			FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
			FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);

			qogg_stream_packetin(&format->vo, &pt2);
			qogg_stream_packetin(&format->vo, &pt3);

			qvorbis_comment_clear(&vc);
		}

		for(;;)
		{
			int result = qogg_stream_flush (&format->to, &pg);
			if (result < 0)
				fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
			if (result <= 0)
				break;
			FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
			FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
		}

		if(cls.capturevideo.soundrate)
		for(;;)
		{
			int result = qogg_stream_flush (&format->vo, &pg);
			if (result < 0)
				fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
			if (result <= 0)
				break;
			FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
			FS_Write(cls.capturevideo.videofile, pg.body, pg.body_len);
		}
	}
}
Beispiel #10
0
int
SolveStep::solve(double timestep,
                 double time,
                 std::string name,
                 std::string method,
                 std::string dimension)
{
   /* Solves given system with given parametres using
    * given method
    * timestep: size of timestep
    * time: total simulation time
    * name: name of files where the position of the
    *       particles are saved at some timesteps
    * method: verlet or RK4
    * dimension: ly or AU
    *
    * Ditterent timers have not been used at the
    * same time.*/

   clock_t start, finish;
   Distance d;

   //declaration and intialisation
   omp_set_num_threads(8); //parallelisation
   double limit = 60; //definition of bound system
   arma::Col<double> center(3), position(3);
   center.zeros();
   double t = 0.;
   System newsystem = mysolarsystem_;
   int n = time/timestep;

   //file to store energy of the system
   std::ofstream energy("energy.m");
   energy << "A = [";
   //file to store energy of the bound system
   std::ofstream bound("BoundEnergy.m");
   bound << "A = [";


   //update the objects initial acceleration
   for (int i = 0 ; i < size() ; ++i)
   {
      Object &mainbody = newsystem.objectlist[i];
      newsystem.acceleration(mainbody, i, 0.0,dimension);
   }

//   start = clock(); //start timer

   //start simulation
   for (int k = 0 ; k < n ; ++k)
   {
      t += timestep;

      //file to store position of particles
      name.append("t");
      std::string filename = name;
      filename.append(".m");
      std::ofstream fout(filename.c_str());
      fout << "t = " << t << "\n A = [";

      //variable needed for calculating intermediate steps
      double addtime = 0.0;

      //simulate all particles for one timestep
#pragma omp parallel for private(i)
      for (int i = 0 ; i < size() ; ++i)
      {
         Object &mainbody = newsystem.objectlist[i];
         System tempSystem = mysolarsystem_;
         double dt = timestep;
         int j = 0;

         double maxTimestep;

         //chose the smallest timestep
         if (mainbody.maxTimestep() < tempSystem.maxTimestep(i))
         {
            maxTimestep = mainbody.maxTimestep();
         }
         else
         {
            maxTimestep = tempSystem.maxTimestep(i);
         }

         //make sure to use small endough timesteps
         while(dt > maxTimestep)
         {
               dt = dt/2.0;

               j += 1;
         }

         //simulate timesteps
         for (int kk = 0 ; kk < std::pow(2,j); ++kk)
         {
            if (method == "rk4")
            {
               start = clock(); //start timer
               rk4Step(dt, i, mainbody, tempSystem, addtime, dimension);
               finish = clock(); //stop timer
               std::cout << "time one rk4 step: " <<
                            static_cast<double>(finish - start)/
                            static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl;
//               mainbody.addToFile(name);
               addtime += dt;
            }
            else if(method == "verlet")
            {
               start = clock(); //start timer
               verlet(dt, i, mainbody, tempSystem, addtime, dimension);
               finish = clock(); //stop timer
               std::cout << "time one verlet step: " <<
                            static_cast<double>(finish - start)/
                            static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl;
//               mainbody.addToFile(name);
               addtime += dt;
            }
            else
            {
               std::cout << "method must be 'verlet' or 'rk4'" << std::endl;
            }

      }

      mysolarsystem_ = newsystem;

      //save position to file
      for (int i = 0 ; i < size() ; ++i)
      {
         Object &mainbody = mysolarsystem_.objectlist[i];
         position = mainbody.getPosition();
         double dist = d.twoObjects(position,center) ;
         if(dist < limit)
         {
            fout << mainbody.getPosition()(0) << "\t\t" << mainbody.getPosition()(1)
                 << "\t\t" << mainbody.getPosition()(2) << "\n";
         }
//         else
//         {
//            mysolarsystem_.removeObject(i);
//            i-=1;
//         }
      }
      fout << "]; \n";
      fout << "plot3(A(:,1), A(:,2),A(:,3), 'o')\n";
      fout << "t = " << t ;
      fout.close();
      }

         //write energy of the system to file
         bound << t << "\t\t" << mysolarsystem_.boundPotentialEnergy(limit) << "\t\t"
               << mysolarsystem_.boundKineticEnergi(limit) << "\n";

         energy << t << "\t\t" <<  mysolarsystem_.potentialEnergy() << "\t\t"
                << mysolarsystem_.kineticEnergi() << "\n";
         if (k % 100 == 0)
         {
            std::cout << t << std::endl;
         }

   }
//   finish = clock(); //stop timer
//   std::cout << "time: " <<
//                static_cast<double>(finish - start)/
//                static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl;


   energy << "]; \n";
   energy.close();

   bound << "]; \n";
   bound.close();
   for (int i = 0 ; i < size() ; ++i)
   {
      Object &mainbody = mysolarsystem_.objectlist[i];
      mysolarsystem_.acceleration(mainbody, i, 0.0,dimension);
   }


   //write final postition to file
   std::ofstream fout("end.m");
   fout << "A = [";
   for (int i = 0 ; i < size() ; ++i)
   {
      Object &mainbody = mysolarsystem_.objectlist[i];

      fout << mainbody.getPosition()(0) << "\t\t" << mainbody.getPosition()(1)
           << "\t\t" << mainbody.getPosition()(2) << "\n";
   }
   fout << "] \n";
   fout.close();

   return 0;
}
Beispiel #11
0
void CameraShootMode::Initialize() {
	angle = bound(Robot::cameraTilt->getAngle(), S_MIN, S_MAX);
}
Beispiel #12
0
bool CTrack::Move(int x, int y)
{
	if (m_bDisabled)
		return false;

	if (!m_iHandleGrabbed)
		return false;

	// Prevent any accidental moves on the first click
	if (m_iHandleGrabbed == H_MOVE && !m_bMoved)
	{
		#define CLOSENESS 10 // pixels
		int dx = m_iLastDownX - x;
		int dy = m_iLastDownY - y;
		if (dx >= -CLOSENESS && dx <= CLOSENESS && dy >= -CLOSENESS && dy <= CLOSENESS)
			return false;
	}

	if (m_bShear)
		ConstrainXY(&x, &y, true/*bButtonDown*/, false/*bInit*/, m_bShear/*bActive*/);

	x = bound(x, m_BoundRectScreen.left, m_BoundRectScreen.right);
	y = bound(y, m_BoundRectScreen.top, m_BoundRectScreen.bottom);

	CPoint pt(x, y);
	m_ViewToDeviceMatrix.Inverse().Transform(pt);
	x = pt.x;
	y = pt.y;

	if (x == m_iLastX && y == m_iLastY)
		return false;

	m_bMoved = true;
	Draw(false/*bOn*/);

	switch (m_iHandleGrabbed)
	{
		case H_UL:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			if (m_bShear)
				Shear(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.top, m_bConstrainX, m_bConstrainY);
			else
				Scale(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.top, m_Distort.Rect.right, m_Distort.Rect.bottom, m_bConstrainAspect ^ CONTROL);
			break;
		}

		case H_UR:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			if (m_bShear)
				Shear(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.top, m_bConstrainX, m_bConstrainY);
			else
				Scale(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.top, m_Distort.Rect.left, m_Distort.Rect.bottom, m_bConstrainAspect ^ CONTROL);
			break;
		}

		case H_LR:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			if (m_bShear)
				Shear(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.bottom, m_bConstrainX, m_bConstrainY);
			else
				Scale(pt.x, pt.y, m_Distort.Rect.right, m_Distort.Rect.bottom, m_Distort.Rect.left, m_Distort.Rect.top, m_bConstrainAspect ^ CONTROL);
			break;
		}

		case H_LL:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			if (m_bShear)
				Shear(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.bottom, m_bConstrainX, m_bConstrainY);
			else
				Scale(pt.x, pt.y, m_Distort.Rect.left, m_Distort.Rect.bottom, m_Distort.Rect.right, m_Distort.Rect.top, m_bConstrainAspect ^ CONTROL);
			break;
		}

		case H_TOP:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			int midx = (m_Distort.Rect.left + m_Distort.Rect.right)/2;

			if (m_bShear)
				Shear(pt.x, pt.y, midx, m_Distort.Rect.top, m_bConstrainX, m_bConstrainY);
			else
			{
				CPoint ptMid(midx, m_Distort.Rect.top);
				long dummy;
				m_Matrix.Transform(ptMid, pt.x, dummy);
				Scale(pt.x, pt.y, midx, m_Distort.Rect.top, midx, m_Distort.Rect.bottom, false/*bConstrainAspect*/);
			}
			break;
		}

		case H_RIGHT:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			int midy = (m_Distort.Rect.top + m_Distort.Rect.bottom)/2;

			if (m_bShear)
				Shear(pt.x, pt.y, m_Distort.Rect.right, midy, m_bConstrainX, m_bConstrainY);
			else
			{
				CPoint ptMid(m_Distort.Rect.right, midy);
				long dummy;
				m_Matrix.Transform(ptMid, dummy, pt.y);
				Scale(pt.x, pt.y, m_Distort.Rect.right, midy, m_Distort.Rect.left, midy, false/*bConstrainAspect*/);
			}
			break;
		}

		case H_BOTTOM:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			int midx = (m_Distort.Rect.left + m_Distort.Rect.right)/2;

			if (m_bShear)
				Shear(pt.x, pt.y, midx, m_Distort.Rect.bottom, m_bConstrainX, m_bConstrainY);
			else
			{
				CPoint ptMid(midx, m_Distort.Rect.bottom);
				long dummy;
				m_Matrix.Transform(ptMid, pt.x, dummy);
				Scale(pt.x, pt.y, midx, m_Distort.Rect.bottom, midx, m_Distort.Rect.top, false/*bConstrainAspect*/);
			}
			break;
		}

		case H_LEFT:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			int midy = (m_Distort.Rect.top + m_Distort.Rect.bottom)/2;

			if (m_bShear)
				Shear(pt.x, pt.y, m_Distort.Rect.left, midy, m_bConstrainX, m_bConstrainY);
			else
			{
				CPoint ptMid(m_Distort.Rect.left, midy);
				long dummy;
				m_Matrix.Transform(ptMid, dummy, pt.y);
				Scale(pt.x, pt.y, m_Distort.Rect.left, midy, m_Distort.Rect.right, midy, false/*bConstrainAspect*/);
			}
			break;
		}

		case H_CENTER:
		{
			// transform points to transformed position
			m_Matrix.Transform(m_ptCenter);
			m_Matrix.Transform(m_ptRotate);
			int dx = pt.x - m_ptCenter.x;
			int dy = pt.y - m_ptCenter.y;
			m_ptRotate.x += dx;
			m_ptRotate.y += dy;
			m_ptCenter = pt;
			// transform points back to untransformed position
			m_Matrix.Inverse().Transform(m_ptCenter);
			m_Matrix.Inverse().Transform(m_ptRotate);
			break;
		}

		case H_CORNER_UL:
		case H_CORNER_UR:
		case H_CORNER_LR:
		case H_CORNER_LL:
		{
			m_Grid.Snap(pt);
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_ROTATE))
				Mode(m_iWhatCanDo & ~TR_ROTATE, false/*fDisplay*/);

			// transform the new point back to its untransformed position
			CPoint ptTemp = pt;
			m_Matrix.Inverse().Transform(ptTemp);
			int i = m_iHandleGrabbed - H_CORNER_UL;
			m_Distort.p[i] = ptTemp;

			// Update the m_Distort.Rect rectangle
			m_Distort.Rect.left   = min(min(min(m_Distort.p[0].x, m_Distort.p[1].x), m_Distort.p[2].x), m_Distort.p[3].x);
			m_Distort.Rect.right  = max(max(max(m_Distort.p[0].x, m_Distort.p[1].x), m_Distort.p[2].x), m_Distort.p[3].x);
			m_Distort.Rect.top    = min(min(min(m_Distort.p[0].y, m_Distort.p[1].y), m_Distort.p[2].y), m_Distort.p[3].y);
			m_Distort.Rect.bottom = max(max(max(m_Distort.p[0].y, m_Distort.p[1].y), m_Distort.p[2].y), m_Distort.p[3].y);
			break;
		}

		case H_ROTATE:
		{
			m_bMoveOnly = false;
			if (m_bExclusive && (m_iWhatCanDo & TR_SIZE))
				Mode(m_iWhatCanDo & ~TR_SIZE, false/*fDisplay*/);

			// transform points to transformed position
			Rotate(pt.x, pt.y, m_iStartRotateX, m_iStartRotateY);
			m_ptRotate = pt;
			// transform points back to untransformed position
			m_Matrix.Inverse().Transform(m_ptRotate);
			break;
		}

		case H_MOVE:
		{
			// Calculate how far we SHOULD move
			CPoint delta1(pt.x - m_iLastX, pt.y - m_iLastY);

			// Calculate where we are right now
			CRect rect = m_Distort.Rect;
			m_Matrix.Transform(rect);

			// Calculate the new top-left point
			CPoint ptNewTL(rect.left + delta1.x, rect.top + delta1.y);

			// Snap it to the grid
			m_Grid.Snap(ptNewTL);

			if (m_iWhatCanDo & TR_BOUNDTOSYMBOL)
			{
				int delta;
				delta = ptNewTL.x - m_BoundRect.left;
				if (delta < 0)
					ptNewTL.x -= delta;
				delta = ptNewTL.y - m_BoundRect.top;
				if (delta < 0)
					ptNewTL.y -= delta;
				delta = (ptNewTL.x + rect.Width()) - m_BoundRect.right;
				if (delta > 0)
					ptNewTL.x -= delta;
				delta = (ptNewTL.y + rect.Height()) - m_BoundRect.bottom;
				if (delta > 0)
					ptNewTL.y -= delta;
			}

			// Calculate how far we WILL move
			CPoint delta2(ptNewTL.x - rect.left, ptNewTL.y - rect.top);

			// Adjust the point for the next time around
			x -= (delta1.x - delta2.x);
			y -= (delta1.y - delta2.y);

			m_Matrix.Translate(delta2.x, delta2.y);
			break;
		}

		default:
			return false;
		}

	if (m_pDrawProc && m_pAGDC)
	{
		HDC hDC = m_pAGDC->GetHDC();
		m_pDrawProc(hDC, false/*bOn*/, TOOLCODE_UPDATE, m_pData);
	}

	Draw(true/*bOn*/);
	m_iLastX = x;
	m_iLastY = y;

	return true;
}
Beispiel #13
0
void S_MixToBuffer(void *stream, unsigned int bufferframes)
{
	int channelindex;
	channel_t *ch;
	int totalmixframes;
	unsigned char *outbytes = (unsigned char *) stream;
	sfx_t *sfx;
	portable_sampleframe_t *paint;
	int wantframes;
	int i;
	int count;
	int fetched;
	int fetch;
	int istartframe;
	int iendframe;
	int ilengthframes;
	int totallength;
	int loopstart;
	int indexfrac;
	int indexfracstep;
#define S_FETCHBUFFERSIZE 4096
	float fetchsampleframes[S_FETCHBUFFERSIZE*2];
	const float *fetchsampleframe;
	float vol[SND_LISTENERS];
	float lerp[2];
	float sample[3];
	double posd;
	double speedd;
	float maxvol;
	qboolean looping;
	qboolean silent;

	// mix as many times as needed to fill the requested buffer
	while (bufferframes)
	{
		// limit to the size of the paint buffer
		totalmixframes = min(bufferframes, PAINTBUFFER_SIZE);

		// clear the paint buffer
		memset(paintbuffer, 0, totalmixframes * sizeof(paintbuffer[0]));

		// paint in the channels.
		// channels with zero volumes still advance in time but don't paint.
		ch = channels; // cppcheck complains here but it is wrong, channels is a channel_t[MAX_CHANNELS] and not an int
		for (channelindex = 0;channelindex < (int)total_channels;channelindex++, ch++)
		{
			sfx = ch->sfx;
			if (sfx == NULL)
				continue;
			if (!S_LoadSound (sfx, true))
				continue;
			if (ch->flags & CHANNELFLAG_PAUSED)
				continue;
			if (!sfx->total_length)
				continue;

			// copy the channel information to the stack for reference, otherwise the
			// values might change during a mix if the spatializer is updating them
			// (note: this still may get some old and some new values!)
			posd = ch->position;
			speedd = ch->mixspeed * sfx->format.speed / snd_renderbuffer->format.speed;
			for (i = 0;i < SND_LISTENERS;i++)
				vol[i] = ch->volume[i];

			// check total volume level, because we can skip some code on silent sounds but other code must still run (position updates mainly)
			maxvol = 0;
			for (i = 0;i < SND_LISTENERS;i++)
				if(vol[i] > maxvol)
					maxvol = vol[i];
			switch(snd_renderbuffer->format.width)
			{
				case 1: // 8bpp
					silent = maxvol < (1.0f / (256.0f));
					// so silent it has zero effect
					break;
				case 2: // 16bpp
					silent = maxvol < (1.0f / (65536.0f));
					// so silent it has zero effect
					break;
				default: // floating point
					silent = maxvol < 1.0e-13f;
					// 130 dB is difference between hearing
					// threshold and a jackhammer from
					// working distance.
					// therefore, anyone who turns up
					// volume so much they notice this
					// cutoff, likely already has their
					// ear-drums blown out anyway.
					break;
			}

			// when doing prologic mixing, some channels invert one side
			if (ch->prologic_invert == -1)
				vol[1] *= -1.0f;

			// get some sfx info in a consistent form
			totallength = sfx->total_length;
			loopstart = (int)sfx->loopstart < totallength ? (int)sfx->loopstart : ((ch->flags & CHANNELFLAG_FORCELOOP) ? 0 : totallength);
			looping = loopstart < totallength;

			// do the actual paint now (may skip work if silent)
			paint = paintbuffer;
			istartframe = 0;
			for (wantframes = totalmixframes;wantframes > 0;posd += count * speedd, wantframes -= count)
			{
				// check if this is a delayed sound
				if (posd < 0)
				{
					// for a delayed sound we have to eat into the delay first
					count = (int)floor(-posd / speedd) + 1;
					count = bound(1, count, wantframes);
					// let the for loop iterator apply the skip
					continue;
				}

				// compute a fetch size that won't overflow our buffer
				count = wantframes;
				for (;;)
				{
					istartframe = (int)floor(posd);
					iendframe = (int)floor(posd + (count-1) * speedd);
					ilengthframes = count > 1 ? (iendframe - istartframe + 2) : 2;
					if (ilengthframes <= S_FETCHBUFFERSIZE)
						break;
					// reduce count by 25% and try again
					count -= count >> 2;
				}

				// zero whole fetch buffer for safety
				// (floating point noise from uninitialized memory = HORRIBLE)
				// otherwise we would only need to clear the excess
				if (!silent)
					memset(fetchsampleframes, 0, ilengthframes*sfx->format.channels*sizeof(fetchsampleframes[0]));

				// if looping, do multiple fetches
				fetched = 0;
				for (;;)
				{
					fetch = min(ilengthframes - fetched, totallength - istartframe);
					if (fetch > 0)
					{
						if (!silent)
							sfx->fetcher->getsamplesfloat(ch, sfx, istartframe, fetch, fetchsampleframes + fetched*sfx->format.channels);
						istartframe += fetch;
						fetched += fetch;
					}
					if (istartframe == totallength && looping && fetched < ilengthframes)
					{
						// loop and fetch some more
						posd += loopstart - totallength;
						istartframe = loopstart;
					}
					else
					{
						break;
					}
				}

				// set up our fixedpoint resampling variables (float to int conversions are expensive so do not do one per sampleframe)
				fetchsampleframe = fetchsampleframes;
				indexfrac = (int)floor((posd - floor(posd)) * 65536.0);
				indexfracstep = (int)floor(speedd * 65536.0);
				if (!silent)
				{
					if (sfx->format.channels == 2)
					{
						// music is stereo
#if SND_LISTENERS != 8
#error the following code only supports up to 8 channels, update it
#endif
						if (snd_speakerlayout.channels > 2)
						{
							// surround mixing
							for (i = 0;i < count;i++, paint++)
							{
								lerp[1] = indexfrac * (1.0f / 65536.0f);
								lerp[0] = 1.0f - lerp[1];
								sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
								sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
								sample[2] = (sample[0] + sample[1]) * 0.5f;
								paint->sample[0] += sample[0] * vol[0];
								paint->sample[1] += sample[1] * vol[1];
								paint->sample[2] += sample[0] * vol[2];
								paint->sample[3] += sample[1] * vol[3];
								paint->sample[4] += sample[2] * vol[4];
								paint->sample[5] += sample[2] * vol[5];
								paint->sample[6] += sample[0] * vol[6];
								paint->sample[7] += sample[1] * vol[7];
								indexfrac += indexfracstep;
								fetchsampleframe += 2 * (indexfrac >> 16);
								indexfrac &= 0xFFFF;
							}
						}
						else
						{
							// stereo mixing
							for (i = 0;i < count;i++, paint++)
							{
								lerp[1] = indexfrac * (1.0f / 65536.0f);
								lerp[0] = 1.0f - lerp[1];
								sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
								sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
								paint->sample[0] += sample[0] * vol[0];
								paint->sample[1] += sample[1] * vol[1];
								indexfrac += indexfracstep;
								fetchsampleframe += 2 * (indexfrac >> 16);
								indexfrac &= 0xFFFF;
							}
						}
					}
					else if (sfx->format.channels == 1)
					{
						// most sounds are mono
#if SND_LISTENERS != 8
#error the following code only supports up to 8 channels, update it
#endif
						if (snd_speakerlayout.channels > 2)
						{
							// surround mixing
							for (i = 0;i < count;i++, paint++)
							{
								lerp[1] = indexfrac * (1.0f / 65536.0f);
								lerp[0] = 1.0f - lerp[1];
								sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
								paint->sample[0] += sample[0] * vol[0];
								paint->sample[1] += sample[0] * vol[1];
								paint->sample[2] += sample[0] * vol[2];
								paint->sample[3] += sample[0] * vol[3];
								paint->sample[4] += sample[0] * vol[4];
								paint->sample[5] += sample[0] * vol[5];
								paint->sample[6] += sample[0] * vol[6];
								paint->sample[7] += sample[0] * vol[7];
								indexfrac += indexfracstep;
								fetchsampleframe += (indexfrac >> 16);
								indexfrac &= 0xFFFF;
							}
						}
						else
						{
							// stereo mixing
							for (i = 0;i < count;i++, paint++)
							{
								lerp[1] = indexfrac * (1.0f / 65536.0f);
								lerp[0] = 1.0f - lerp[1];
								sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
								paint->sample[0] += sample[0] * vol[0];
								paint->sample[1] += sample[0] * vol[1];
								indexfrac += indexfracstep;
								fetchsampleframe += (indexfrac >> 16);
								indexfrac &= 0xFFFF;
							}
						}
					}
				}
			}
Beispiel #14
0
static void S_ConvertPaintBuffer(portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int channels)
{
	int i, val;

	// FIXME: add 24bit and 32bit float formats
	// FIXME: optimize with SSE intrinsics?
	if (width == 2)  // 16bit
	{
		short *snd_out = (short*)rb_ptr;
		if (channels == 8)  // 7.1 surround
		{
			for (i = 0;i < nbframes;i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[6] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[7] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
			}
		}
		else if (channels == 6)  // 5.1 surround
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
			}
		}
		else if (channels == 4)  // 4.0 surround
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
			}
		}
		else if (channels == 2)  // 2.0 stereo
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
				val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
			}
		}
		else if (channels == 1)  // 1.0 mono
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 16384.0f);*snd_out++ = bound(-32768, val, 32767);
			}
		}

		// noise is really really annoying
		if (cls.timedemo)
			memset(rb_ptr, 0, nbframes * channels * width);
	}
	else  // 8bit
	{
		unsigned char *snd_out = (unsigned char*)rb_ptr;
		if (channels == 8)  // 7.1 surround
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[6] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[7] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
			}
		}
		else if (channels == 6)  // 5.1 surround
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
			}
		}
		else if (channels == 4)  // 4.0 surround
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
			}
		}
		else if (channels == 2)  // 2.0 stereo
		{
			for (i = 0; i < nbframes; i++, painted_ptr++)
			{
				val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
				val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
			}
		}
		else if (channels == 1)  // 1.0 mono
		{
			for (i = 0;i < nbframes;i++, painted_ptr++)
			{
				val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 64.0f) + 128; *snd_out++ = bound(0, val, 255);
			}
		}

		// noise is really really annoying
		if (cls.timedemo)
			memset(rb_ptr, 128, nbframes * channels);
	}
}
Beispiel #15
0
/*
==================
CL_ParseServerData
==================
*/
void CL_ParseServerData( sizebuf_t *msg )
{
	string	gamefolder;
	qboolean	background;
	int	i;

	MsgDev( D_NOTE, "Serverdata packet received.\n" );

	cls.demowaiting = false;	// server is changed
	clgame.load_sequence++;	// now all hud sprites are invalid

	// wipe the client_t struct
	if( !cls.changelevel && !cls.changedemo )
		CL_ClearState ();
	cls.state = ca_connected;

	// parse protocol version number
	i = BF_ReadLong( msg );
	cls.serverProtocol = i;

	if( i != PROTOCOL_VERSION )
		Host_Error( "Server uses invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );

	cl.servercount = BF_ReadLong( msg );
	cl.checksum = BF_ReadLong( msg );
	cl.playernum = BF_ReadByte( msg );
	cl.maxclients = BF_ReadByte( msg );
	clgame.maxEntities = BF_ReadWord( msg );
	clgame.maxEntities = bound( 600, clgame.maxEntities, 4096 );
	Q_strncpy( clgame.mapname, BF_ReadString( msg ), MAX_STRING );
	Q_strncpy( clgame.maptitle, BF_ReadString( msg ), MAX_STRING );
	background = BF_ReadOneBit( msg );
	Q_strncpy( gamefolder, BF_ReadString( msg ), MAX_STRING );
	host.features = (uint)BF_ReadLong( msg );

	if( cl.maxclients > 1 && host.developer < 1 )
		host.developer++;

	// set the background state
	if( cls.demoplayback && ( cls.demonum != -1 ))
	{
		// re-init mouse
		host.mouse_visible = false;
		cl.background = true;
	}
	else cl.background = background;

	if( cl.background )	// tell the game parts about background state
		Cvar_FullSet( "cl_background", "1", CVAR_READ_ONLY );
	else Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY );

	if( !cls.changelevel ) 
	{
		// continue playing if we are changing level
		S_StopBackgroundTrack ();
	}
#if 0
	// NOTE: this is not tested as well. Use with precaution
	CL_ChangeGame( gamefolder, false );
#endif
	if( !cls.changedemo )
		UI_SetActiveMenu( cl.background );

	cl.refdef.viewentity = cl.playernum + 1; // always keep viewent an actual

	menu.globals->maxClients = cl.maxclients;
	Q_strncpy( menu.globals->maptitle, clgame.maptitle, sizeof( menu.globals->maptitle ));

	if( cl.maxclients > 1 && r_decals->value > mp_decals->value )
		Cvar_SetFloat( "r_decals", mp_decals->value );

	if( !cls.changelevel && !cls.changedemo )
		CL_InitEdicts (); // re-arrange edicts

	// get splash name
	if( cls.demoplayback && ( cls.demonum != -1 ))
		Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, glState.wideScreen ? "16x9" : "4x3" ));
	else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" ));
	Cvar_SetFloat( "scr_loading", 0.0f ); // reset progress bar

	if(( cl_allow_levelshots->integer && !cls.changelevel ) || cl.background )
	{
		if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true )) 
			Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
		cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
	}

	if( scr_dark->integer )
	{
		screenfade_t		*sf = &clgame.fade;
		client_textmessage_t	*title;

		title = CL_TextMessageGet( "GAMETITLE" );

		if( title )
		{
			// get settings from titles.txt
			sf->fadeEnd = title->holdtime + title->fadeout;
			sf->fadeReset = title->fadeout;
		}
		else sf->fadeEnd = sf->fadeReset = 4.0f;
	
		sf->fadeFlags = FFADE_IN;
		sf->fader = sf->fadeg = sf->fadeb = 0;
		sf->fadealpha = 255;
		sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset;
		sf->fadeReset += cl.time;
		sf->fadeEnd += sf->fadeReset;
		
		Cvar_SetFloat( "v_dark", 0.0f );
	}

	// need to prep refresh at next oportunity
	cl.video_prepped = false;
	cl.audio_prepped = false;

	Q_memset( &clgame.movevars, 0, sizeof( clgame.movevars ));
	Q_memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
}
Beispiel #16
0
/*
===============
R_ComputeFxBlend
===============
*/
int R_ComputeFxBlend( cl_entity_t *e )
{
	int		blend = 0, renderAmt;
	float		offset, dist;
	vec3_t		tmp;

	offset = ((int)e->index ) * 363.0f; // Use ent index to de-sync these fx
	renderAmt = e->curstate.renderamt;

	switch( e->curstate.renderfx ) 
	{
	case kRenderFxPulseSlowWide:
		blend = renderAmt + 0x40 * sin( RI.refdef.time * 2 + offset );	
		break;
	case kRenderFxPulseFastWide:
		blend = renderAmt + 0x40 * sin( RI.refdef.time * 8 + offset );
		break;
	case kRenderFxPulseSlow:
		blend = renderAmt + 0x10 * sin( RI.refdef.time * 2 + offset );
		break;
	case kRenderFxPulseFast:
		blend = renderAmt + 0x10 * sin( RI.refdef.time * 8 + offset );
		break;
	// JAY: HACK for now -- not time based
	case kRenderFxFadeSlow:			
		if( renderAmt > 0 ) 
			renderAmt -= 1;
		else renderAmt = 0;
		blend = renderAmt;
		break;
	case kRenderFxFadeFast:
		if( renderAmt > 3 ) 
			renderAmt -= 4;
		else renderAmt = 0;
		blend = renderAmt;
		break;
	case kRenderFxSolidSlow:
		if( renderAmt < 255 ) 
			renderAmt += 1;
		else renderAmt = 255;
		blend = renderAmt;
		break;
	case kRenderFxSolidFast:
		if( renderAmt < 252 ) 
			renderAmt += 4;
		else renderAmt = 255;
		blend = renderAmt;
		break;
	case kRenderFxStrobeSlow:
		blend = 20 * sin( RI.refdef.time * 4 + offset );
		if( blend < 0 ) blend = 0;
		else blend = renderAmt;
		break;
	case kRenderFxStrobeFast:
		blend = 20 * sin( RI.refdef.time * 16 + offset );
		if( blend < 0 ) blend = 0;
		else blend = renderAmt;
		break;
	case kRenderFxStrobeFaster:
		blend = 20 * sin( RI.refdef.time * 36 + offset );
		if( blend < 0 ) blend = 0;
		else blend = renderAmt;
		break;
	case kRenderFxFlickerSlow:
		blend = 20 * (sin( RI.refdef.time * 2 ) + sin( RI.refdef.time * 17 + offset ));
		if( blend < 0 ) blend = 0;
		else blend = renderAmt;
		break;
	case kRenderFxFlickerFast:
		blend = 20 * (sin( RI.refdef.time * 16 ) + sin( RI.refdef.time * 23 + offset ));
		if( blend < 0 ) blend = 0;
		else blend = renderAmt;
		break;
	case kRenderFxHologram:
	case kRenderFxDistort:
		VectorCopy( e->origin, tmp );
		VectorSubtract( tmp, RI.refdef.vieworg, tmp );
		dist = DotProduct( tmp, RI.refdef.forward );
			
		// Turn off distance fade
		if( e->curstate.renderfx == kRenderFxDistort )
			dist = 1;

		if( dist <= 0 )
		{
			blend = 0;
		}
		else 
		{
			renderAmt = 180;
			if( dist <= 100 ) blend = renderAmt;
			else blend = (int) ((1.0f - ( dist - 100 ) * ( 1.0f / 400.0f )) * renderAmt );
			blend += Com_RandomLong( -32, 31 );
		}
		break;
	case kRenderFxGlowShell:	// safe current renderamt because it's shell scale!
	case kRenderFxDeadPlayer:	// safe current renderamt because it's player index!
		blend = renderAmt;
		break;
	case kRenderFxNone:
	case kRenderFxClampMinScale:
	default:
		if( e->curstate.rendermode == kRenderNormal )
			blend = 255;
		else blend = renderAmt;
		break;	
	}

	if( e->model && e->model->type != mod_brush )
	{
		// NOTE: never pass sprites with rendercolor '0 0 0' it's a stupid Valve Hammer Editor bug
		if( !e->curstate.rendercolor.r && !e->curstate.rendercolor.g && !e->curstate.rendercolor.b )
			e->curstate.rendercolor.r = e->curstate.rendercolor.g = e->curstate.rendercolor.b = 255;

		// apply scale to studiomodels and sprites only
		if( !e->curstate.scale )
			e->curstate.scale = 1.0f;
	}

	blend = bound( 0, blend, 255 );

	return blend;
}
Beispiel #17
0
/*
* CG_AddParticles
*/
void CG_AddParticles( void ) {
	int i, j, k;
	float alpha;
	float time, time2;
	vec3_t org;
	vec3_t corner;
	byte_vec4_t color;
	int maxparticle, activeparticles;
	float alphaValues[MAX_PARTICLES];
	cparticle_t *p, *free_particles[MAX_PARTICLES];

	if( !cg_numparticles ) {
		return;
	}

	j = 0;
	maxparticle = -1;
	activeparticles = 0;

	for( i = 0, p = particles; i < cg_numparticles; i++, p++ ) {
		time = ( cg.time - p->time ) * 0.001f;
		alpha = alphaValues[i] = p->alpha + time * p->alphavel;

		if( alpha <= 0 ) { // faded out
			free_particles[j++] = p;
			continue;
		}

		maxparticle = i;
		activeparticles++;

		time2 = time * time * 0.5f;

		org[0] = p->org[0] + p->vel[0] * time + p->accel[0] * time2;
		org[1] = p->org[1] + p->vel[1] * time + p->accel[1] * time2;
		org[2] = p->org[2] + p->vel[2] * time + p->accel[2] * time2;

		color[0] = (uint8_t)( bound( 0, p->color[0], 1.0f ) * 255 );
		color[1] = (uint8_t)( bound( 0, p->color[1], 1.0f ) * 255 );
		color[2] = (uint8_t)( bound( 0, p->color[2], 1.0f ) * 255 );
		color[3] = (uint8_t)( bound( 0, alpha, 1.0f ) * 255 );

		corner[0] = org[0];
		corner[1] = org[1] - 0.5f * p->scale;
		corner[2] = org[2] - 0.5f * p->scale;

		Vector4Set( p->pVerts[0], corner[0], corner[1] + p->scale, corner[2] + p->scale, 1 );
		Vector4Set( p->pVerts[1], corner[0], corner[1], corner[2] + p->scale, 1 );
		Vector4Set( p->pVerts[2], corner[0], corner[1], corner[2], 1 );
		Vector4Set( p->pVerts[3], corner[0], corner[1] + p->scale, corner[2], 1 );
		for( k = 0; k < 4; k++ ) {
			Vector4Copy( color, p->pColor[k] );
		}

		p->poly.numverts = 4;
		p->poly.verts = p->pVerts;
		p->poly.stcoords = p->pStcoords;
		p->poly.colors = p->pColor;
		p->poly.fognum = p->fog ? 0 : -1;
		p->poly.shader = ( p->shader == NULL ) ? CG_MediaShader( cgs.media.shaderParticle ) : p->shader;

		trap_R_AddPolyToScene( &p->poly );
	}

	i = 0;
	while( maxparticle >= activeparticles ) {
		*free_particles[i++] = particles[maxparticle--];

		while( maxparticle >= activeparticles ) {
			if( alphaValues[maxparticle] <= 0 ) {
				maxparticle--;
			} else {
				break;
			}
		}
	}

	cg_numparticles = activeparticles;
}
Beispiel #18
0
void QRangeControl::directSetValue(int value)
{
    prevVal = val;
    val = bound( value );
}
Beispiel #19
0
static gboolean
process(PseudoTcpSocket *self, Segment *seg)
{
  PseudoTcpSocketPrivate *priv = self->priv;
  guint32 now;
  SendFlags sflags = sfNone;
  gboolean bIgnoreData;
  gboolean bNewData;
  gboolean bConnect = FALSE;

  /* If this is the wrong conversation, send a reset!?!
     (with the correct conversation?) */
  if (seg->conv != priv->conv) {
    //if ((seg->flags & FLAG_RST) == 0) {
    //  packet(sock, tcb, seg->ack, 0, FLAG_RST, 0, 0);
    //}
    DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "wrong conversation");
    return FALSE;
  }

  now = get_current_time();
  priv->last_traffic = priv->lastrecv = now;
  priv->bOutgoing = FALSE;

  if (priv->state == TCP_CLOSED) {
    // !?! send reset?
    DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "closed");
    return FALSE;
  }

  // Check if this is a reset segment
  if (seg->flags & FLAG_RST) {
    closedown(self, ECONNRESET);
    return FALSE;
  }

  // Check for control data
  bConnect = FALSE;
  if (seg->flags & FLAG_CTL) {
    if (seg->len == 0) {
      DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Missing control code");
      return FALSE;
    } else if (seg->data[0] == CTL_CONNECT) {
      bConnect = TRUE;
      if (priv->state == TCP_LISTEN) {
        char buffer[1];
        priv->state = TCP_SYN_RECEIVED;
        buffer[0] = CTL_CONNECT;
        queue(self, buffer, 1, TRUE);
      } else if (priv->state == TCP_SYN_SENT) {
        priv->state = TCP_ESTABLISHED;
        DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "State: TCP_ESTABLISHED");
        adjustMTU(self);
        if (priv->callbacks.PseudoTcpOpened)
          priv->callbacks.PseudoTcpOpened(self, priv->callbacks.user_data);

      }
    } else {
      DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Unknown control code: %d", seg->data[0]);
      return FALSE;
    }
  }

  // Update timestamp
  if ((seg->seq <= priv->ts_lastack) &&
      (priv->ts_lastack < seg->seq + seg->len)) {
    priv->ts_recent = seg->tsval;
  }

  // Check if this is a valuable ack
  if ((seg->ack > priv->snd_una) && (seg->ack <= priv->snd_nxt)) {
    guint32 nAcked;
    guint32 nFree;
    guint32 kIdealRefillSize;

    // Calculate round-trip time
    if (seg->tsecr) {
      long rtt = time_diff(now, seg->tsecr);
      if (rtt >= 0) {
        if (priv->rx_srtt == 0) {
          priv->rx_srtt = rtt;
          priv->rx_rttvar = rtt / 2;
        } else {
          priv->rx_rttvar = (3 * priv->rx_rttvar +
              abs((long)(rtt - priv->rx_srtt))) / 4;
          priv->rx_srtt = (7 * priv->rx_srtt + rtt) / 8;
        }
        priv->rx_rto = bound(MIN_RTO,
            priv->rx_srtt + max(1LU, 4 * priv->rx_rttvar), MAX_RTO);

        DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "rtt: %ld   srtt: %d  rto: %d",
                rtt, priv->rx_srtt, priv->rx_rto);
      } else {
        g_assert_not_reached ();
      }
    }

    priv->snd_wnd = seg->wnd;

    nAcked = seg->ack - priv->snd_una;
    priv->snd_una = seg->ack;

    priv->rto_base = (priv->snd_una == priv->snd_nxt) ? 0 : now;

    priv->slen -= nAcked;
    memmove(priv->sbuf, priv->sbuf + nAcked, priv->slen);
    //LOG(LS_INFO) << "PseudoTcp::process - priv->slen = " << priv->slen;

    for (nFree = nAcked; nFree > 0; ) {
      SSegment *data = (SSegment *) (g_list_first (priv->slist)->data);
      g_assert(g_list_length (priv->slist) > 0);
      if (nFree < data->len) {
        data->len -= nFree;
        nFree = 0;
      } else {
        if (data->len > priv->largest) {
          priv->largest = data->len;
        }
        nFree -= data->len;
        g_slice_free (SSegment, priv->slist->data);
        priv->slist = g_list_delete_link (priv->slist, priv->slist);
      }
    }

    if (priv->dup_acks >= 3) {
      if (priv->snd_una >= priv->recover) { // NewReno
        guint32 nInFlight = priv->snd_nxt - priv->snd_una;
        // (Fast Retransmit)
        priv->cwnd = min(priv->ssthresh, nInFlight + priv->mss);
        DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "exit recovery");
        priv->dup_acks = 0;
      } else {
        DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "recovery retransmit");
        if (!transmit(self, priv->slist, now)) {
          closedown(self, ECONNABORTED);
          return FALSE;
        }
        priv->cwnd += priv->mss - min(nAcked, priv->cwnd);
      }
    } else {
      priv->dup_acks = 0;
      // Slow start, congestion avoidance
      if (priv->cwnd < priv->ssthresh) {
        priv->cwnd += priv->mss;
      } else {
        priv->cwnd += max(1LU, priv->mss * priv->mss / priv->cwnd);
      }
    }

    // !?! A bit hacky
    if ((priv->state == TCP_SYN_RECEIVED) && !bConnect) {
      priv->state = TCP_ESTABLISHED;
      DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "State: TCP_ESTABLISHED");
      adjustMTU(self);
      if (priv->callbacks.PseudoTcpOpened)
        priv->callbacks.PseudoTcpOpened(self, priv->callbacks.user_data);
    }

    // If we make room in the send queue, notify the user
    // The goal it to make sure we always have at least enough data to fill the
    // window.  We'd like to notify the app when we are halfway to that point.
    kIdealRefillSize = (sizeof(priv->sbuf) + sizeof(priv->rbuf)) / 2;
    if (priv->bWriteEnable && (priv->slen < kIdealRefillSize)) {
      priv->bWriteEnable = FALSE;
      if (priv->callbacks.PseudoTcpWritable)
        priv->callbacks.PseudoTcpWritable(self, priv->callbacks.user_data);
    }
  } else if (seg->ack == priv->snd_una) {
    /* !?! Note, tcp says don't do this... but otherwise how does a
       closed window become open? */
    priv->snd_wnd = seg->wnd;

    // Check duplicate acks
    if (seg->len > 0) {
      // it's a dup ack, but with a data payload, so don't modify priv->dup_acks
    } else if (priv->snd_una != priv->snd_nxt) {
      guint32 nInFlight;

      priv->dup_acks += 1;
      if (priv->dup_acks == 3) { // (Fast Retransmit)
        DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "enter recovery");
        DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "recovery retransmit");
        if (!transmit(self, priv->slist, now)) {
          closedown(self, ECONNABORTED);
          return FALSE;
        }
        priv->recover = priv->snd_nxt;
        nInFlight = priv->snd_nxt - priv->snd_una;
        priv->ssthresh = max(nInFlight / 2, 2 * priv->mss);
        //LOG(LS_INFO) << "priv->ssthresh: " << priv->ssthresh << "  nInFlight: " << nInFlight << "  priv->mss: " << priv->mss;
        priv->cwnd = priv->ssthresh + 3 * priv->mss;
      } else if (priv->dup_acks > 3) {
        priv->cwnd += priv->mss;
      }
    } else {
      priv->dup_acks = 0;
    }
  }

  /* Conditions where acks must be sent:
   * 1) Segment is too old (they missed an ACK) (immediately)
   * 2) Segment is too new (we missed a segment) (immediately)
   * 3) Segment has data (so we need to ACK!) (delayed)
   * ... so the only time we don't need to ACK, is an empty segment
   * that points to rcv_nxt!
   */

  if (seg->seq != priv->rcv_nxt) {
    sflags = sfImmediateAck; // (Fast Recovery)
  } else if (seg->len != 0) {
    sflags = sfDelayedAck;
  }
  if (sflags == sfImmediateAck) {
    if (seg->seq > priv->rcv_nxt) {
      DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "too new");
    } else if (seg->seq + seg->len <= priv->rcv_nxt) {
      DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "too old");
    }
  }

  // Adjust the incoming segment to fit our receive buffer
  if (seg->seq < priv->rcv_nxt) {
    guint32 nAdjust = priv->rcv_nxt - seg->seq;
    if (nAdjust < seg->len) {
      seg->seq += nAdjust;
      seg->data += nAdjust;
      seg->len -= nAdjust;
    } else {
      seg->len = 0;
    }
  }
  if ((seg->seq + seg->len - priv->rcv_nxt) >
      (sizeof(priv->rbuf) - priv->rlen)) {
    guint32 nAdjust = seg->seq + seg->len - priv->rcv_nxt -
        (sizeof(priv->rbuf) - priv->rlen);
    if (nAdjust < seg->len) {
      seg->len -= nAdjust;
    } else {
      seg->len = 0;
    }
  }

  bIgnoreData = (seg->flags & FLAG_CTL) || (priv->shutdown != SD_NONE);
  bNewData = FALSE;

  if (seg->len > 0) {
    if (bIgnoreData) {
      if (seg->seq == priv->rcv_nxt) {
        priv->rcv_nxt += seg->len;
      }
    } else {
      guint32 nOffset = seg->seq - priv->rcv_nxt;
      memcpy(priv->rbuf + priv->rlen + nOffset, seg->data, seg->len);
      if (seg->seq == priv->rcv_nxt) {
        GList *iter = NULL;

        priv->rlen += seg->len;
        priv->rcv_nxt += seg->len;
        priv->rcv_wnd -= seg->len;
        bNewData = TRUE;

        iter = priv->rlist;
        while (iter && (((RSegment *)iter->data)->seq <= priv->rcv_nxt)) {
          RSegment *data = (RSegment *)(iter->data);
          if (data->seq + data->len > priv->rcv_nxt) {
            guint32 nAdjust = (data->seq + data->len) - priv->rcv_nxt;
            sflags = sfImmediateAck; // (Fast Recovery)
            DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Recovered %d bytes (%d -> %d)",
                nAdjust, priv->rcv_nxt, priv->rcv_nxt + nAdjust);
            priv->rlen += nAdjust;
            priv->rcv_nxt += nAdjust;
            priv->rcv_wnd -= nAdjust;
          }
          g_slice_free (RSegment, priv->rlist->data);
          priv->rlist = g_list_delete_link (priv->rlist, priv->rlist);
          iter = priv->rlist;
        }
      } else {
        GList *iter = NULL;
        RSegment *rseg = g_slice_new0 (RSegment);

		DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Saving %d bytes (%d -> %d)",
            seg->len, seg->seq, seg->seq + seg->len);

        rseg->seq = seg->seq;
        rseg->len = seg->len;
        iter = priv->rlist;
        while (iter && (((RSegment*)iter->data)->seq < rseg->seq)) {
          iter = g_list_next (iter);
        }
        priv->rlist = g_list_insert_before(priv->rlist, iter, rseg);
      }
    }
  }

  attempt_send(self, sflags);

  // If we have new data, notify the user
  if (bNewData && priv->bReadEnable) {
    priv->bReadEnable = FALSE;
    if (priv->callbacks.PseudoTcpReadable)
      priv->callbacks.PseudoTcpReadable(self, priv->callbacks.user_data);
  }

  return TRUE;
}
Beispiel #20
0
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
#endif
{
	float maxfrac, maxrealfrac;
	int n;
	entity_render_t *ent;
	float tracemins[3], tracemaxs[3];
	trace_t trace;
	float tempnormal[3], starttransformed[3], endtransformed[3];
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
	vec3_t end;
	vec_t len = 0;

	if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
	{
		// TRICK: make the trace 1 qu longer!
		VectorSubtract(pEnd, start, end);
		len = VectorNormalizeLength(end);
		VectorMA(pEnd, collision_endposnudge.value, end, end);
	}
	else
		VectorCopy(pEnd, end);
#endif

	memset (&trace, 0 , sizeof(trace_t));
	trace.fraction = 1;
	trace.realfraction = 1;
	VectorCopy (end, trace.endpos);

	if (hitent)
		*hitent = 0;
	if (cl.worldmodel && cl.worldmodel->TraceLine)
		cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, start, end, SUPERCONTENTS_SOLID);

	if (normal)
		VectorCopy(trace.plane.normal, normal);
	maxfrac = trace.fraction;
	maxrealfrac = trace.realfraction;

	tracemins[0] = min(start[0], end[0]);
	tracemaxs[0] = max(start[0], end[0]);
	tracemins[1] = min(start[1], end[1]);
	tracemaxs[1] = max(start[1], end[1]);
	tracemins[2] = min(start[2], end[2]);
	tracemaxs[2] = max(start[2], end[2]);

	// look for embedded bmodels
	for (n = 0;n < cl.num_entities;n++)
	{
		if (!cl.entities_active[n])
			continue;
		ent = &cl.entities[n].render;
		if (!BoxesOverlap(ent->mins, ent->maxs, tracemins, tracemaxs))
			continue;
		if (!ent->model || !ent->model->TraceLine)
			continue;
		if ((ent->flags & RENDER_EXTERIORMODEL) && !chase_active.integer)
			continue;
		// if transparent and not selectable, skip entity
		if (!(cl.entities[n].state_current.effects & EF_SELECTABLE) && (ent->alpha < 1 || (ent->effects & (EF_ADDITIVE | EF_NODEPTHTEST))))
			continue;
		if (ent == ignoreent)
			continue;
		Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
		Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
		Collision_ClipTrace_Box(&trace, ent->model->normalmins, ent->model->normalmaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID, SUPERCONTENTS_SOLID, 0, NULL);
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
		if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
			Collision_ShortenTrace(&trace, len / (len + collision_endposnudge.value), pEnd);
#endif
		if (maxrealfrac < trace.realfraction)
			continue;

		ent->model->TraceLine(ent->model, ent->frameblend, ent->skeleton, &trace, starttransformed, endtransformed, SUPERCONTENTS_SOLID);

		if (maxrealfrac > trace.realfraction)
		{
			if (hitent)
				*hitent = n;
			maxfrac = trace.fraction;
			maxrealfrac = trace.realfraction;
			if (normal)
			{
				VectorCopy(trace.plane.normal, tempnormal);
				Matrix4x4_Transform3x3(&ent->matrix, tempnormal, normal);
			}
		}
	}
	maxfrac = bound(0, maxfrac, 1);
	maxrealfrac = bound(0, maxrealfrac, 1);
	//if (maxfrac < 0 || maxfrac > 1) Con_Printf("fraction out of bounds %f %s:%d\n", maxfrac, __FILE__, __LINE__);
	if (impact)
		VectorLerp(start, maxfrac, end, impact);
	return maxfrac;
}
Beispiel #21
0
void CMomentaryRotButton :: SetPositionMoveDone( void )
{
	float flCurPos = GetPos( GetLocalAngles( ));

	if((( flCurPos >= pev->ideal_yaw ) && ( m_direction == 1 )) || (( flCurPos <= pev->ideal_yaw ) && ( m_direction == -1 )))
	{
		// g-cont. we need auto return after direct set position?
		if( FBitSet( pev->spawnflags, SF_MOMENTARY_ROT_BUTTON_AUTO_RETURN ) && m_returnSpeed > 0 )
		{
			SetMoveDone( &CMomentaryRotButton::ReturnMoveDone );
			m_direction = -1;

			if( flCurPos >= 1.0f )
			{
				// disable use until button is waiting
				SetUse( NULL );

				// delay before autoreturn.
				SetMoveDoneTime( m_flDelay + 0.1f );
			}
			else SetMoveDoneTime( 0.1f );
		}
		else
		{
			m_iState = STATE_OFF;

			// we reached or surpassed our movement goal.
			SetLocalAvelocity( g_vecZero );

			// BUGBUG: Won't this get the player stuck?
			SetLocalAngles( m_start + pev->movedir * ( pev->ideal_yaw * m_flMoveDistance ));
			SetNextThink( -1 );
			SetMoveDoneTime( -1 );
			UpdateTarget( pev->ideal_yaw );
		}

		m_lastUsed = 0;
		return;
	}

	// set right state
	if( flCurPos >= pev->ideal_yaw )
		m_iState = STATE_TURN_OFF;

	if( flCurPos <= pev->ideal_yaw )
		m_iState = STATE_TURN_ON;

	Vector vecNewAngles = m_start + pev->movedir * ( pev->ideal_yaw * m_flMoveDistance );
	float flAngleDelta = fabs( AxisDelta( pev->spawnflags, vecNewAngles, GetLocalAngles( )));
	float dt = flAngleDelta / pev->speed;

	if( dt < gpGlobals->frametime )
	{
		dt = gpGlobals->frametime;
		float speed = flAngleDelta / gpGlobals->frametime;
		SetLocalAvelocity( speed * pev->movedir * m_direction );
	}

	dt = bound( gpGlobals->frametime, dt, gpGlobals->frametime * 6 );

	SetMoveDoneTime( dt );
}
Beispiel #22
0
static void update_weapon_loading_gunship_page (ui_object *obj, void *arg)
{
	entity
		*en;

	gunship_types
		gunship;

	weapon_loading_hardpoint_types
		hardpoint;

	int
		count,
		fixed,
		auw,
		weapon_type;

	float
		mass;

	ui_object
		*button_object;

	rgb_colour
		*col;

	ASSERT (obj);

	en = get_local_entity_safe_ptr (get_ui_object_item_number (obj));

	ASSERT (en);

	gunship = get_local_entity_int_value (en, INT_TYPE_GUNSHIP_TYPE);

	ASSERT (gunship < NUM_GUNSHIP_TYPES);

	if (get_helicopter_allowed_to_rearm (en))
	{
		fixed = FALSE;
	}
	else
	{
		fixed = TRUE;
	}

	//
	// Set button text
	//

	for (hardpoint = 0; hardpoint < NUM_WEAPON_LOADING_HARDPOINT_TYPES; hardpoint ++)
	{
		if (weapon_loading_button_list [gunship][hardpoint].valid)
		{
			button_object = weapon_loading_button_list [gunship][hardpoint].button_ptr;

			weapon_type = weapon_loading_get_current_hardpoint_weapon (gunship, hardpoint);

			//
			// Set Text
			//

			if (weapon_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON)
			{
				count = get_weapon_loading_hardpoint_weapon_count (en, hardpoint, weapon_type);

				sprintf (buffer, "%dx %s", count, weapon_database [weapon_type].weapon_loading_list_name);
			}
			else
			{
				sprintf (buffer, "%s", weapon_database [weapon_type].weapon_loading_list_name);
			}

			set_ui_object_text (button_object, buffer);

			//
			// Set Button Attributes
			//

			if ((fixed) || (weapon_loading_get_valid_weapon_count (en, hardpoint) < 2))
			{
				set_ui_object_notify_on (button_object, NOTIFY_TYPE_NONE);

				set_ui_object_highlightable (button_object, FALSE);

				col = &ui_ingame_dead_text_colour;

				set_ui_object_font_colour (button_object, col->r, col->g, col->b, col->a);
			}
			else
			{
				set_ui_object_notify_on (button_object, NOTIFY_TYPE_BUTTON_DOWN);

				set_ingame_ui_object_mouse_over_properties (button_object);
			}
		}
	}

	//
	// All-Up-Weight (player only)
	//

	if (en == get_gunship_entity ())
	{
		mass = set_flight_dynamics_mass ();

		convert_float_to_int (mass, &auw);

		sprintf (buffer, "%s: %dkg", get_trans ("All Up Weight"), auw);

		set_ui_object_text (page_auw_text, buffer);
	}
	else
	{
		set_ui_object_text (page_auw_text, "");
	}

	//
	// Fuel Page (player only)
	//

	if (en == get_gunship_entity ())
	{
		sprintf (buffer, " %.0fkg", get_current_flight_dynamics_fuel_weight ());

		set_ui_object_text (page_fuel_gauge, buffer);

		set_ui_object_drawable (page_fuel_text, TRUE);

		set_ui_object_drawable (page_fuel_gauge, TRUE);

		draw_weapon_loading_gauge (page_fuel_gauge, get_dynamics_normalised_fuel_value ());
	}
	else
	{
		set_ui_object_drawable (page_fuel_text, FALSE);

		set_ui_object_drawable (page_fuel_gauge, FALSE);
	}

	//
	// Damage Page (player only)
	//

	set_ui_object_drawable (page_repairing_text, FALSE);

	set_ui_object_drawable (page_repairing_gauge, FALSE);

	if (en == get_gunship_entity ())
	{
		int
			repair_index;

		float
			level,
			repair_time;

		if (current_flight_dynamics->repairing_damage != DYNAMICS_DAMAGE_NONE)
		{
			repair_index = get_dynamics_damage_currently_repairing_type ();

			repair_time = dynamics_damage_database [repair_index].repair_time;

			if (repair_time == 0.0)
			{
				level = 1.0;
			}
			else
			{
				level = 1.0 - (current_flight_dynamics->damage_repair_time / repair_time);

				level = bound (level, 0.0, 1.0);
			}

			sprintf (buffer, " %s", get_trans (dynamics_damage_database [repair_index].name));

			set_ui_object_text (page_repairing_gauge, buffer);

			set_ui_object_drawable (page_repairing_text, TRUE);

			set_ui_object_drawable (page_repairing_gauge, TRUE);

			draw_weapon_loading_gauge (page_repairing_gauge, level);
		}
	}
}
Beispiel #23
0
/*
================
CL_UpdateParticle

update particle color, position etc
================
*/
void CL_UpdateParticle( particle_t *p, float ft )
{
	float	time3 = 15.0 * ft;
	float	time2 = 10.0 * ft;
	float	time1 = 5.0 * ft;
	float	dvel = 4 * ft;
	float	grav = ft * clgame.movevars.gravity * 0.05f;
	float	size = 1.5f;
	int	i, iRamp, alpha = 255;
	vec3_t	right, up;
	rgb_t	color;

	r_stats.c_particle_count++;

	switch( p->type )
	{
	case pt_static:
		break;
	case pt_tracer:
	case pt_clientcustom:
		if( p->callback )
		{
			p->callback( p, ft );
		}
		if( p->type == pt_tracer )
			return; // already drawed
		break;
	case pt_fire:
		p->ramp += time1;
		if( p->ramp >= 6 ) p->die = -1;
		else p->color = ramp3[(int)p->ramp];
		p->vel[2] += grav;
		break;
	case pt_explode:
		p->ramp += time2;
		if( p->ramp >= 8 ) p->die = -1;
		else p->color = ramp1[(int)p->ramp];
		for( i = 0; i < 3; i++ )
			p->vel[i] += p->vel[i] * dvel;
		p->vel[2] -= grav;
		break;
	case pt_explode2:
		p->ramp += time3;
		if( p->ramp >= 8 ) p->die = -1;
		else p->color = ramp2[(int)p->ramp];
		for( i = 0; i < 3; i++ )
			p->vel[i] -= p->vel[i] * ft;
		p->vel[2] -= grav;
		break;
	case pt_blob:
	case pt_blob2:
		p->ramp += time2;
		iRamp = (int)p->ramp >> SIMSHIFT;

		if( iRamp >= SPARK_COLORCOUNT )
		{
			p->ramp = 0.0f;
			iRamp = 0;
		}
		
		p->color = CL_LookupColor( gSparkRamp[iRamp][0], gSparkRamp[iRamp][1], gSparkRamp[iRamp][2] );

		for( i = 0; i < 2; i++ )		
			p->vel[i] -= p->vel[i] * 0.5f * ft;
		p->vel[2] -= grav * 5.0f;

		if( Com_RandomLong( 0, 3 ))
		{
			p->type = pt_blob;
			alpha = 0;
		}
		else
		{
			p->type = pt_blob2;
			alpha = 255;
		}
		break;
	case pt_grav:
		p->vel[2] -= grav * 20;
		break;
	case pt_slowgrav:
		p->vel[2] -= grav;
		break;
	case pt_vox_grav:
		p->vel[2] -= grav * 8;
		break;
	case pt_vox_slowgrav:
		p->vel[2] -= grav * 4;
		break;
	}

#if 0
	// HACKHACK a scale up to keep particles from disappearing
	size += (p->org[0] - RI.vieworg[0]) * RI.vforward[0];
	size += (p->org[1] - RI.vieworg[1]) * RI.vforward[1];
	size += (p->org[2] - RI.vieworg[2]) * RI.vforward[2];

	if( size < 20.0f ) size = 1.0f;
	else size = 1.0f + size * 0.004f;
#endif
 	// scale the axes by radius
	VectorScale( RI.vright, size, right );
	VectorScale( RI.vup, size, up );

	p->color = bound( 0, p->color, 255 );
	VectorSet( color, clgame.palette[p->color][0], clgame.palette[p->color][1], clgame.palette[p->color][2] );

	GL_SetRenderMode( kRenderTransTexture );
	pglColor4ub( color[0], color[1], color[2], alpha );

	if( r_oldparticles->integer == 1 )
		GL_Bind( XASH_TEXTURE0, cls.oldParticleImage );
	else
		GL_Bind( XASH_TEXTURE0, cls.particleImage );

	// add the 4 corner vertices.
	pglBegin( GL_QUADS );

	pglTexCoord2f( 0.0f, 1.0f );
	pglVertex3f( p->org[0] - right[0] + up[0], p->org[1] - right[1] + up[1], p->org[2] - right[2] + up[2] );
	pglTexCoord2f( 0.0f, 0.0f );
	pglVertex3f( p->org[0] + right[0] + up[0], p->org[1] + right[1] + up[1], p->org[2] + right[2] + up[2] );
	pglTexCoord2f( 1.0f, 0.0f );
	pglVertex3f( p->org[0] + right[0] - up[0], p->org[1] + right[1] - up[1], p->org[2] + right[2] - up[2] );
	pglTexCoord2f( 1.0f, 1.0f );
	pglVertex3f( p->org[0] - right[0] - up[0], p->org[1] - right[1] - up[1], p->org[2] - right[2] - up[2] );

	pglEnd();

	if( p->type != pt_clientcustom )
	{
		// update position.
		VectorMA( p->org, ft, p->vel, p->org );
	}
}
Beispiel #24
0
void animate_routed_vehicle_wheels (entity *en)
{
	routed_vehicle
		*raw;

	object_3d_instance
		*inst3d;

	float
		speed,
		delta_pitch;

	int
		blurred_flag;

	ASSERT (en);

	if (get_local_entity_int_value (en, INT_TYPE_OBJECT_DRAWN_ONCE_THIS_FRAME))
	{
		return;
	}

   if (get_time_acceleration () == TIME_ACCELERATION_PAUSE)
	{
		return;
	}

	if (!get_local_entity_int_value (en, INT_TYPE_MOBILE_MOVING))
	{
		return;
	}

	raw = (routed_vehicle *) get_local_entity_data (en);

	inst3d = raw->vh.inst3d;

	if ( ( in_flight_articulation_test ) && ( get_external_view_entity() == en ) )
	{
		//
		// debug articulation test
		//

		test_speed += ( test_speed_inc * get_delta_time() );

		if ( test_speed > TEST_SPEED_MAX )
		{
			test_speed_inc = -TEST_SPEED_INC;
		}
		else if ( test_speed <= 0.0 )
		{
			test_speed_inc = TEST_SPEED_INC;
		}

		test_speed = bound( test_speed, 0.0, TEST_SPEED_MAX );

		speed = test_speed;
	}
	else
	{
		//
		// normal operation
		//

		speed = get_local_entity_float_value( en, FLOAT_TYPE_VELOCITY );
	}

	blurred_flag = ( speed > BLURRED_WHEEL_THRESHOLD );

	if ( blurred_flag )
	{
		delta_pitch = PI / 20.0;
	}
	else
	{
		delta_pitch = 2 * speed * get_delta_time ();
	}

	//
	// rotate wheel objects
	//
	// if a blurred wheel type exists on the vehicle then set the correct wheel type visible status, and rotate it
	// otherwise just rotate the standard wheel type
	//

	// fixed
	if ( activate_and_modify_sub_object_type_heading_pitch_and_roll
					(
						inst3d,
						OBJECT_3D_SUB_OBJECT_FIXED_WHEEL_MOVING,
						blurred_flag,
						0.0, delta_pitch, 0.0
					) )
	{
		activate_and_modify_sub_object_type_heading_pitch_and_roll
					(
						inst3d,
						OBJECT_3D_SUB_OBJECT_FIXED_WHEEL,
						!blurred_flag,
						0.0, delta_pitch, 0.0
					);
	}
	else
	{
		activate_and_modify_sub_object_type_heading_pitch_and_roll
					(
						inst3d,
						OBJECT_3D_SUB_OBJECT_FIXED_WHEEL,
						TRUE,
						0.0, delta_pitch, 0.0
					);
	}

	// steerable
	if ( activate_and_modify_sub_object_type_heading_pitch_and_roll
					(
						inst3d,
						OBJECT_3D_SUB_OBJECT_STEERABLE_WHEEL_MOVING,
						blurred_flag,
						0.0, delta_pitch, 0.0
					) )
	{
		activate_and_modify_sub_object_type_heading_pitch_and_roll
					(
						inst3d,
						OBJECT_3D_SUB_OBJECT_STEERABLE_WHEEL,
						!blurred_flag,
						0.0, delta_pitch, 0.0
					);
	}
	else
	{
		activate_and_modify_sub_object_type_heading_pitch_and_roll
					(
						inst3d,
						OBJECT_3D_SUB_OBJECT_STEERABLE_WHEEL,
						TRUE,
						0.0, delta_pitch, 0.0
					);
	}

	//
	// animate track textures
	//

	if ( speed > 0.0 )
	{
		//
		// debug articulation test
		//

		advance_texture_animation_frame_on_object( inst3d, TEXTURE_ANIMATION_INDEX_TRAK0 );
	}
}
Beispiel #25
0
/*
================
R_EmitEdge
================
*/
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) {
	edge_t *edge, *pcheck;
	int u_check, v, v2, ceilv0, side;
	float u, u_step, *world, scale, lzi0, u0, v0;
	vec3_t local, transformed;

	if (r_lastvertvalid) {
		u0 = r_u1;
		v0 = r_v1;
		lzi0 = r_lzi1;
		ceilv0 = r_ceilv1;
	} else {
		world = &pv0->position[0];
	
		// transform and project
		VectorSubtract (world, modelorg, local);
		TransformVector (local, transformed);
	
		if (transformed[2] < NEAR_CLIP)
			transformed[2] = NEAR_CLIP;
	
		lzi0 = 1.0 / transformed[2];
	
		// FIXME: build x/yscale into transform?
		scale = xscale * lzi0;
		u0 = (xcenter + scale * transformed[0]);
		u0 = bound(r_refdef.fvrectx_adj, u0, r_refdef.fvrectright_adj);
	
		scale = yscale * lzi0;
		v0 = (ycenter - scale * transformed[1]);
		v0 = bound(r_refdef.fvrecty_adj, v0, r_refdef.fvrectbottom_adj);
	
		ceilv0 = (int) ceil(v0);
	}

	world = &pv1->position[0];

	// transform and project
	VectorSubtract (world, modelorg, local);
	TransformVector (local, transformed);

	if (transformed[2] < NEAR_CLIP)
		transformed[2] = NEAR_CLIP;

	r_lzi1 = 1.0 / transformed[2];

	scale = xscale * r_lzi1;
	r_u1 = (xcenter + scale * transformed[0]);
	r_u1 = bound(r_refdef.fvrectx_adj, r_u1, r_refdef.fvrectright_adj);

	scale = yscale * r_lzi1;
	r_v1 = (ycenter - scale * transformed[1]);
	r_v1 = bound(r_refdef.fvrecty_adj, r_v1, r_refdef.fvrectbottom_adj);

	if (r_lzi1 > lzi0)
		lzi0 = r_lzi1;

	if (lzi0 > r_nearzi)	// for mipmap finding
		r_nearzi = lzi0;

	// for right edges, all we want is the effect on 1/z
	if (r_nearzionly)
		return;

	r_emitted = 1;

	r_ceilv1 = (int) ceil(r_v1);


	// create the edge
	if (ceilv0 == r_ceilv1) {
		// we cache unclipped horizontal edges as fully clipped
		if (cacheoffset != 0x7FFFFFFF)
			cacheoffset = FULLY_CLIPPED_CACHED |(r_framecount & FRAMECOUNT_MASK);
		return;		// horizontal edge
	}

	side = ceilv0 > r_ceilv1;

	edge = edge_p++;

	edge->owner = r_pedge;

	edge->nearzi = lzi0;

	if (side == 0) {
		// trailing edge (go from p1 to p2)
		v = ceilv0;
		v2 = r_ceilv1 - 1;

		edge->surfs[0] = surface_p - surfaces;
		edge->surfs[1] = 0;

		u_step = ((r_u1 - u0) / (r_v1 - v0));
		u = u0 + ((float)v - v0) * u_step;
	} else {
		// leading edge (go from p2 to p1)
		v2 = ceilv0 - 1;
		v = r_ceilv1;

		edge->surfs[0] = 0;
		edge->surfs[1] = surface_p - surfaces;

		u_step = ((u0 - r_u1) / (v0 - r_v1));
		u = r_u1 + ((float)v - r_v1) * u_step;
	}

	edge->u_step = u_step*0x100000;
	edge->u = u*0x100000 + 0xFFFFF;

	// we need to do this to avoid stepping off the edges if a very nearly horizontal edge is less
	// than epsilon above a scan, and numeric error causes it to incorrectly extend to the scan,
	// and the extension of the line goes off the edge of the screen
	// FIXME: is this actually needed?
	if (edge->u < r_refdef.vrect_x_adj_shift20)
		edge->u = r_refdef.vrect_x_adj_shift20;
	if (edge->u > r_refdef.vrectright_adj_shift20)
		edge->u = r_refdef.vrectright_adj_shift20;

	// sort the edge in normally
	u_check = edge->u;
	if (edge->surfs[0])
		u_check++;	// sort trailers after leaders

	if (!newedges[v] || newedges[v]->u >= u_check) {
		edge->next = newedges[v];
		newedges[v] = edge;
	} else {
		pcheck = newedges[v];
		while (pcheck->next && pcheck->next->u < u_check)
			pcheck = pcheck->next;
		edge->next = pcheck->next;
		pcheck->next = edge;
	}

	edge->nextremove = removeedges[v2];
	removeedges[v2] = edge;
}
Beispiel #26
0
Datei: trace.c Projekt: jogi1/jsv
int Trace_RecursiveHullTrace(struct trace_local *tl, int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2)
{
	struct plane *plane;
	float t1, t2, frac, midf;
	struct clipnode *node;
	int i, nearside, check, oldcheck;
	vec3_t mid;

	struct hull *hull = tl->hull;
	struct trace *trace = tl->trace;

	while (1)
	{
		if (num < 0)
		{
			tl->leafs_count++;
			if (num == CONTENTS_SOLID)
			{
				if (tl->leafs_count == 1)
					trace->startsolid = true;
				return TR_SOLID;
			}
			else
			{
				if (num == CONTENTS_EMPTY)
					trace->inopen = true;
				else
					trace->inwater = true;
				return TR_EMPTY;
			}
		}

		node = hull->clipnodes + num;

		plane = hull->planes + node->planenum;

		//printf("t_rht: %p %p %i %i %f ", node, plane, node->planenum, plane->type, plane->dist);
		//PRINT_VEC(plane->normal);

		if (plane->type < 3)
		{
			t1 = p1[plane->type] - plane->dist;
			t2 = p2[plane->type] - plane->dist;
			//printf("t_rht 1: t1, t2, plane->dist %f %f %f\n", t1, t2, plane->dist);
		}
		else
		{
			t1 = Vector_DotProduct(plane->normal, p1) - plane->dist;
			t2 = Vector_DotProduct(plane->normal, p2) - plane->dist;
			//printf("t_rht 2: t1, t2, plane->dist %f %f %f\n", t1, t2, plane->dist);
		}

		if (t1 >= 0 && t2 >= 0)
		{
			num = node->children[0];
			continue;
		}

		if (t1 < 0 && t2 < 0)
		{
			num = node->children[1];
			continue;
		}

		frac = t1 / (t1 - t2);
		frac = bound(0, frac, 1);
		midf = p1f + (p2f - p1f) * frac;

		for (i=0; i<3; i++)
			mid[i] = p1[i] + frac * (p2[i] - p1[i]);

		nearside = (t1 < t2) ? 1 : 0;
		//printf("doing trace 1 %f %f\n", frac, midf);
		check = Trace_RecursiveHullTrace(tl, node->children[nearside], p1f, midf, p1, mid);
		if (check == TR_BLOCKED)
		{
			return check;
		}

		if (check == TR_SOLID && (trace->inopen  || trace->inwater))
		{
			return check;
		}
		oldcheck = check;

		//printf("doing trace 2\n");
		check = Trace_RecursiveHullTrace(tl, node->children[1 - nearside], midf, p2f, mid, p2);
		if (check == TR_EMPTY || check == TR_BLOCKED)
		{
			return check;
		}

		if (oldcheck != TR_EMPTY)
		{
			return check;
		}

		if (!nearside)
		{
			Vector_Copy(trace->plane.normal, plane->normal);
			trace->plane.dist = plane->dist;
		}
		else
		{
			Vector_Negate(trace->plane.normal, plane->normal);
			trace->plane.dist = -plane->dist;
		}

		if (t1 < t2)
			frac = (t1 + DIST_EPSILON) / (t1 - t2);
		else
			frac = (t1 - DIST_EPSILON) / (t1 - t2);

		frac = bound(0, frac, 1);

		midf = p1f + (p2f - p1f) * frac;

		for (i=0; i<3; i++)
			mid[i] = p1[i] + frac * (p2[i] - p1[i]);

		trace->fraction = midf;

		//printf("fraction: %f\n", midf);

		Vector_Copy(trace->endpos, mid);

		return TR_BLOCKED;
	}
#warning maybe return smth else here
	return TR_BLOCKED;
}
Beispiel #27
0
double dB2Normalised(double x, double dbFloor) {
    return bound(1.0 - (x / dbFloor), 0.0, 1.0);
}
Beispiel #28
0
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage( sizebuf_t *msg )
{
	char	*s;
	int	i, j, cmd;
	int	param1, param2;
	int	bufStart;

	cls_message_debug.parsing = true;		// begin parsing
	starting_count = BF_GetNumBytesRead( msg );	// updates each frame
	
	// parse the message
	while( 1 )
	{
		if( BF_CheckOverflow( msg ))
		{
			Host_Error( "CL_ParseServerMessage: overflow!\n" );
			return;
		}

		// mark start position
		bufStart = BF_GetNumBytesRead( msg );

		// end of message
		if( BF_GetNumBitsLeft( msg ) < 8 )
			break;		

		cmd = BF_ReadByte( msg );

		// record command for debugging spew on parse problem
		CL_Parse_RecordCommand( cmd, bufStart );

		// other commands
		switch( cmd )
		{
		case svc_bad:
			Host_Error( "svc_bad\n" );
			break;
		case svc_nop:
			// this does nothing
			break;
		case svc_disconnect:
			MsgDev( D_INFO, "Disconnected from server\n" );
			CL_Drop ();
			Host_AbortCurrentFrame ();
			break;
		case svc_changing:
			if( BF_ReadOneBit( msg ))
			{
				cls.changelevel = true;
				S_StopAllSounds();

				if( cls.demoplayback )
				{
					SCR_BeginLoadingPlaque( cl.background );
					cls.changedemo = true;
				}
			}
			else MsgDev( D_INFO, "Server disconnected, reconnecting\n" );

			CL_ClearState ();
			CL_InitEdicts (); // re-arrange edicts

			if( cls.demoplayback )
			{
				cl.background = (cls.demonum != -1) ? true : false;
				cls.state = ca_connected;
			}
			else cls.state = ca_connecting;
			cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
			break;
		case svc_setview:
			cl.refdef.viewentity = BF_ReadWord( msg );
			break;
		case svc_sound:
			CL_ParseSoundPacket( msg, false );
			break;
		case svc_time:
			// shuffle timestamps
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = BF_ReadFloat( msg );			
			break;
		case svc_print:
			i = BF_ReadByte( msg );
			MsgDev( D_INFO, "^6%s", BF_ReadString( msg ));
			if( i == PRINT_CHAT ) S_StartLocalSound( "common/menu2.wav", VOL_NORM, false );
			break;
		case svc_stufftext:
			CL_ParseStuffText( msg );
			break;
		case svc_lightstyle:
			CL_ParseLightStyle( msg );
			break;
		case svc_setangle:
			CL_ParseSetAngle( msg );
			break;
		case svc_serverdata:
			Cbuf_Execute(); // make sure any stuffed commands are done
			CL_ParseServerData( msg );
			break;
		case svc_addangle:
			CL_ParseAddAngle( msg );
			break;
		case svc_clientdata:
			CL_ParseClientData( msg );
			break;
		case svc_packetentities:
			CL_ParsePacketEntities( msg, false );
			break;
		case svc_deltapacketentities:
			CL_ParsePacketEntities( msg, true );
			break;
		case svc_updatepings:
			CL_UpdateUserPings( msg );
			break;
		case svc_usermessage:
			CL_RegisterUserMessage( msg );
			break;
		case svc_particle:
			CL_ParseParticles( msg );
			break;
		case svc_restoresound:
			CL_ParseRestoreSoundPacket( msg );
			break;
		case svc_spawnstatic:
			CL_ParseStaticEntity( msg );
			break;
		case svc_ambientsound:
			CL_ParseSoundPacket( msg, true );
			break;
		case svc_crosshairangle:
			CL_ParseCrosshairAngle( msg );
			break;
		case svc_spawnbaseline:
			CL_ParseBaseline( msg );
			break;
		case svc_temp_entity:
			CL_ParseTempEntity( msg );
			break;
		case svc_setpause:
			cl.refdef.paused = ( BF_ReadOneBit( msg ) != 0 );
			break;
		case svc_deltamovevars:
			CL_ParseMovevars( msg );
			break;
		case svc_customization:
			CL_ParseCustomization( msg );
			break;
		case svc_centerprint:
			CL_CenterPrint( BF_ReadString( msg ), 0.25f );
			break;
		case svc_event:
			CL_ParseEvent( msg );
			break;
		case svc_event_reliable:
			CL_ParseReliableEvent( msg );
			break;
		case svc_updateuserinfo:
			CL_UpdateUserinfo( msg );
			break;
		case svc_intermission:
			cl.refdef.intermission = true;
			break;
		case svc_modelindex:
			CL_PrecacheModel( msg );
			break;
		case svc_soundindex:
			CL_PrecacheSound( msg );
			break;
		case svc_soundfade:
			CL_ParseSoundFade( msg );
			break;
		case svc_cdtrack:
			param1 = BF_ReadByte( msg );
			param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
			param2 = BF_ReadByte( msg );
			param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
			S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0 );
			break;
		case svc_serverinfo:
			CL_ServerInfo( msg );
			break;
		case svc_eventindex:
			CL_PrecacheEvent( msg );
			break;
		case svc_deltatable:
			Delta_ParseTableField( msg );
			break;
		case svc_weaponanim:
			param1 = BF_ReadByte( msg );	// iAnim
			param2 = BF_ReadByte( msg );	// body
			CL_WeaponAnim( param1, param2 );
			break;
		case svc_bspdecal:
			CL_ParseStaticDecal( msg );
			break;
		case svc_roomtype:
			param1 = BF_ReadShort( msg );
			Cvar_SetFloat( "room_type", param1 );
			break;
		case svc_chokecount:
			i = BF_ReadByte( msg );
			j = cls.netchan.incoming_acknowledged - 1;
			for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
			{
				if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
				{
					cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
					i--;
				}
			}
			break;
		case svc_resourcelist:
			CL_ParseResourceList( msg );
			break;
		case svc_director:
			CL_ParseDirector( msg );
			break;
		case svc_studiodecal:
			CL_ParseStudioDecal( msg );
			break;
		case svc_querycvarvalue:
			CL_ParseCvarValue( msg );
			break;
		case svc_querycvarvalue2:
			CL_ParseCvarValue2( msg );
			break;
		default:
			CL_ParseUserMessage( msg, cmd );
			break;
		}
	}

	cls_message_debug.parsing = false;	// done

	// we don't know if it is ok to save a demo message until
	// after we have parsed the frame
	if( !cls.demoplayback )
	{
		if( cls.demorecording && !cls.demowaiting )
		{
			CL_WriteDemoMessage( false, starting_count, msg );
		}
		else if( cls.state != ca_active )
		{
			CL_WriteDemoMessage( true, starting_count, msg );
		}
	}
}
Beispiel #29
0
/*
=================
CL_UpdateTEnts
=================
*/
void CL_UpdateTEnts (void)
{
	int			i;
	beam_t		*b;
	vec3_t		dist, org, beamstart;
	float		d;
	entity_t	*ent;
	float		yaw, pitch;
	float		forward;

	int			j;
	vec3_t		beamend;
//	qboolean	sparks = false;

	num_temp_entities = 0;

// update lightning
	for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
	{
		if (!b->model || b->endtime < cl.time)
			continue;

		// if coming from the player, update the start position
		if (b->entity == cl.viewentity)
		{
			VectorCopy (cl_entities[cl.viewentity].origin, b->start);

			b->start[2] += cl.crouch + bound(-7, scr_ofsy.value, 4);
			b->start[2] += bound(0, cl_lightning_zadjust.value, 20);//progs.dat aims from 20 for traceline

			if (cl_truelightning.value)
			{
				vec3_t	forward, v, org, ang;
				float	f, delta;
				trace_t	trace;

				f = fmax(0, fmin(1, cl_truelightning.value));

				VectorSubtract (playerbeam_end, cl_entities[cl.viewentity].origin, v);
				//v[2] -= 22;		// adjust for view height
				v[2] -= cl.crouch; //
				v[2] -= bound(0, cl_lightning_zadjust.value, 20);

				vectoangles (v, ang);

				// lerp pitch
				ang[0] = -ang[0];
				if (ang[0] < -180)
					ang[0] += 360;
				ang[0] += (cl.viewangles[0] - ang[0]) * f;

				// lerp yaw
				delta = cl.viewangles[1] - ang[1];
				if (delta > 180)
					delta -= 360;
				if (delta < -180)
					delta += 360;
				ang[1] += delta * f;
				ang[2] = 0;

				AngleVectors (ang, forward, NULLVEC, NULLVEC);
				VectorScale(forward, 600, forward);
				VectorCopy(cl_entities[cl.viewentity].origin, org);
				org[2] += bound(0, cl_lightning_zadjust.value, 20);//progs.dat aims from 20 for teaceline
				VectorAdd(org, forward, b->end);

				memset (&trace, 0, sizeof(trace_t));
				if (!SV_RecursiveHullCheck(cl.worldmodel->hulls, 0, 0, 1, org, b->end, &trace))
					VectorCopy(trace.endpos, b->end);
			}
		}

/*
	// if coming from the player, update the start position
		if (b->entity == cl.viewentity)
		{
			VectorCopy (cl_entities[cl.viewentity].origin, b->start);
		}
*/
	// calculate pitch and yaw
		VectorSubtract (b->end, b->start, dist);

		if (dist[1] == 0 && dist[0] == 0)
		{
			yaw = 0;
			if (dist[2] > 0)
				pitch = 90;
			else
				pitch = 270;
		}
		else
		{
			yaw = (int) (atan2f(dist[1], dist[0]) * 180 / M_PI);
			if (yaw < 0)
				yaw += 360;
	
			forward = sqrtf (dist[0]*dist[0] + dist[1]*dist[1]);
			pitch = (int) (atan2f(dist[2], forward) * 180 / M_PI);
			if (pitch < 0)
				pitch += 360;
		}
        // add new entities for the lightning
		VectorCopy(b->start, org);
		VectorCopy(b->start, beamstart);
		d = VectorNormalize (dist);
		VectorScale (dist, 30, dist);

		if (key_dest == key_game)
		{
			for ( ; d > 0 ; d -= 30)
			{
				if ((qmb_initialized && r_part_lightning.value) && (!cl.paused))
				{
					VectorAdd(org, dist, beamend);
					for (j=0 ; j<3 ; j++)
						beamend[j] += ((rand()%10)-5);
					QMB_LightningBeam (beamstart, beamend);
					//if ((r_glowlg.value) && (r_dynamic.value))
					//	CL_NewDlight (i, beamstart, 100, 0.1, lt_blue);
					VectorCopy(beamend, beamstart);
				}
				else
				{
					if (!(ent = CL_NewTempEntity()))
						return;
					VectorCopy(org, ent->origin);
					ent->model = b->model;
					ent->angles[0] = pitch;
					ent->angles[1] = yaw;
					ent->angles[2] = rand() % 360;
				}
				VectorAdd(org, dist, org);
			}
		}
/*
	// add new entities for the lightning
		VectorCopy (b->start, org);
		d = VectorNormalize(dist);
     	while (d > 0)
		{
			ent = CL_NewTempEntity ();
			if (!ent)
				return;
			VectorCopy (org, ent->origin);
			ent->model = b->model;
			ent->angles[0] = pitch;
			ent->angles[1] = yaw;
			ent->angles[2] = rand()%360;

			for (i=0 ; i<3 ; i++)
				org[i] += dist[i]*30;
			d -= 30;
		}
*/
	}
	
}
Beispiel #30
0
void damage_entity_to_flight_model (entity *en)
{

	float
		damage_level;

	unsigned int
		this_damage;

	if (!current_flight_dynamics)
	{

		return;
	}

	this_damage = DYNAMICS_DAMAGE_NONE;

	damage_level = 0.0;

	while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES)
	{

		if (current_flight_dynamics->dynamics_damage & this_damage)
		{

			switch (this_damage)
			{

				case DYNAMICS_DAMAGE_NONE:
				{

					break;
				}
				case DYNAMICS_DAMAGE_MAIN_ROTOR:
				{

					damage_level += 0.6;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: main rotor damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_TAIL_ROTOR:
				{

					damage_level += 0.8;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: tail rotor damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LEFT_ENGINE:
				{

					damage_level += 0.4;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: left engine damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_RIGHT_ENGINE:
				{

					damage_level += 0.4;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: right engine damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE:
				{

					damage_level += 0.2;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: left engine fire damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE:
				{

					damage_level += 0.2;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: right engine fire damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LOW_HYDRAULICS:
				{

					damage_level += 0.2;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: LOW HYDRAULICS damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_STABILISER:
				{

					damage_level += 0.2;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: STABILISER damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_FUEL_LEAK:
				{

					damage_level += 0.1;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: FUEL_LEAK damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_LOW_OIL_PRESSURE:
				{

					damage_level += 0.1;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: LOW_OIL_PRESSURE damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE:
				{

					damage_level += 0.1;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: HIGH_OIL_PRESSURE damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_AVIONICS:
				{

					damage_level += 0.1;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: AVIONICS damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_FIRE_EXTINGUISHER:
				{

					damage_level += 0.0;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: FIRE_EXTINGUISHER damaged");

					#endif

					break;
				}
				case DYNAMICS_DAMAGE_UNDERCARRIAGE:
				{

					damage_level += 0.1;

					#if DYNAMICS_DEBUG

					debug_log ("DYNAMICS: UNDERCARRIAGE damaged");

					#endif

					break;
				}
				default:
				{

					debug_fatal ("DYNAMICS: unknown damage %d", this_damage);
				}
			}
		}

		this_damage = this_damage << 1;
	}

	damage_level = bound (damage_level, 0.0, 0.9);

	damage_level = 1.0 - damage_level;

	damage_level *= get_local_entity_int_value (en, INT_TYPE_INITIAL_DAMAGE_LEVEL);

	set_client_server_entity_int_value (en, INT_TYPE_DAMAGE_LEVEL, damage_level);
}