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)); } } } } }
/* 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; }
double dB2Normalised(double x, double theCeiling, double theFloor) { return bound(1.0 + ((x-theCeiling) / (theCeiling-theFloor)), 0.0, 1.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(); }
static unsigned int DI_BufSize(void) { return bound(16, in_di_bufsize.integer, 256); }
//================ //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 ); } } }
void CameraClimbMode::Initialize() { angle = bound(Robot::cameraTilt->getAngle(), C_MIN, C_MAX); }
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); } } }
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; }
void CameraShootMode::Initialize() { angle = bound(Robot::cameraTilt->getAngle(), S_MIN, S_MAX); }
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; }
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; } } } } }
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); } }
/* ================== 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 )); }
/* =============== 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; }
/* * 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; }
void QRangeControl::directSetValue(int value) { prevVal = val; val = bound( value ); }
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; }
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; }
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 ); }
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); } } }
/* ================ 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 ); } }
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 ); } }
/* ================ 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; }
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; }
double dB2Normalised(double x, double dbFloor) { return bound(1.0 - (x / dbFloor), 0.0, 1.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 ); } } }
/* ================= 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; } */ } }
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); }