// kPlus_Mode static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); return SkPackARGB32(a, r, g, b); }
static void handle_profiler_signal (int signal) { if (EQ (backtrace_top_function (), Qautomatic_gc)) /* Special case the time-count inside GC because the hash-table code is not prepared to be used while the GC is running. More specifically it uses ASIZE at many places where it does not expect the ARRAY_MARK_FLAG to be set. We could try and harden the hash-table code, but it doesn't seem worth the effort. */ cpu_gc_count = saturated_add (cpu_gc_count, 1); else { EMACS_INT count = 1; #ifdef HAVE_ITIMERSPEC if (profiler_timer_ok) { int overruns = timer_getoverrun (profiler_timer); eassert (overruns >= 0); count += overruns; } #endif eassert (HASH_TABLE_P (cpu_log)); record_backtrace (XHASH_TABLE (cpu_log), count); } }
static void record_backtrace (log_t *log, EMACS_INT count) { Lisp_Object backtrace; ptrdiff_t index; if (!INTEGERP (log->next_free)) /* FIXME: transfer the evicted counts to a special entry rather than dropping them on the floor. */ evict_lower_half (log); index = XINT (log->next_free); /* Get a "working memory" vector. */ backtrace = HASH_KEY (log, index); get_backtrace (backtrace); { /* We basically do a `gethash+puthash' here, except that we have to be careful to avoid memory allocation since we're in a signal handler, and we optimize the code to try and avoid computing the hash+lookup twice. See fns.c:Fputhash for reference. */ EMACS_UINT hash; ptrdiff_t j = hash_lookup (log, backtrace, &hash); if (j >= 0) { EMACS_INT old_val = XINT (HASH_VALUE (log, j)); EMACS_INT new_val = saturated_add (old_val, count); set_hash_value_slot (log, j, make_number (new_val)); } else { /* BEWARE! hash_put in general can allocate memory. But currently it only does that if log->next_free is nil. */ int j; eassert (!NILP (log->next_free)); j = hash_put (log, backtrace, make_number (count), hash); /* Let's make sure we've put `backtrace' right where it already was to start with. */ eassert (index == j); /* FIXME: If the hash-table is almost full, we should set some global flag so that some Elisp code can offload its data elsewhere, so as to avoid the eviction code. There are 2 ways to do that, AFAICT: - Set a flag checked in QUIT, such that QUIT can then call Fprofiler_cpu_log and stash the full log for later use. - Set a flag check in post-gc-hook, so that Elisp code can call profiler-cpu-log. That gives us more flexibility since that Elisp code can then do all kinds of fun stuff like write the log to disk. Or turn it right away into a call tree. Of course, using Elisp is generally preferable, but it may take longer until we get a chance to run the Elisp code, so there's more risk that the table will get full before we get there. */ } } }
void CHARACTER_CORE::tick(bool use_input) { float phys_size = 28.0f; triggered_events = 0; // get ground state bool grounded = false; if(col_check_point(pos.x+phys_size/2, pos.y+phys_size/2+5)) grounded = true; if(col_check_point(pos.x-phys_size/2, pos.y+phys_size/2+5)) grounded = true; //platte if(col_check_platte(pos.x+phys_size/2, pos.y+phys_size/2+5)) grounded = true; if(col_check_platte(pos.x-phys_size/2, pos.y+phys_size/2+5)) grounded = true; vec2 target_direction = normalize(vec2(input.target_x, input.target_y)); vel.y += world->tuning.gravity; float max_speed = grounded ? world->tuning.ground_control_speed : world->tuning.air_control_speed; float accel = grounded ? world->tuning.ground_control_accel : world->tuning.air_control_accel; float friction = grounded ? world->tuning.ground_friction : world->tuning.air_friction; // handle input if(use_input) { direction = input.direction; // setup angle float a = 0; if(input.target_x == 0) a = atan((float)input.target_y); else a = atan((float)input.target_y/(float)input.target_x); if(input.target_x < 0) a = a+pi; angle = (int)(a*256.0f); // handle jump if(input.jump) { if(!(jumped&1)) { if(grounded) { triggered_events |= COREEVENT_GROUND_JUMP; vel.y = -world->tuning.ground_jump_impulse; jumped |= 1; } else if(!(jumped&2)) { triggered_events |= COREEVENT_AIR_JUMP; vel.y = -world->tuning.air_jump_impulse; jumped |= 3; } } } else jumped &= ~1; // handle hook if(input.hook) { if(hook_state == HOOK_IDLE) { hook_state = HOOK_FLYING; hook_pos = pos+target_direction*phys_size*1.5f; hook_dir = target_direction; hooked_player = -1; hook_tick = 0; triggered_events |= COREEVENT_HOOK_LAUNCH; } } else { hooked_player = -1; hook_state = HOOK_IDLE; hook_pos = pos; } } // add the speed modification according to players wanted direction if(direction < 0) vel.x = saturated_add(-max_speed, max_speed, vel.x, -accel); if(direction > 0) vel.x = saturated_add(-max_speed, max_speed, vel.x, accel); if(direction == 0) vel.x *= friction; // handle jumping // 1 bit = to keep track if a jump has been made on this input // 2 bit = to keep track if a air-jump has been made if(grounded) jumped &= ~2; // do hook if(hook_state == HOOK_IDLE) { hooked_player = -1; hook_state = HOOK_IDLE; hook_pos = pos; } else if(hook_state >= HOOK_RETRACT_START && hook_state < HOOK_RETRACT_END) { hook_state++; } else if(hook_state == HOOK_RETRACT_END) { hook_state = HOOK_RETRACTED; triggered_events |= COREEVENT_HOOK_RETRACT; hook_state = HOOK_RETRACTED; } else if(hook_state == HOOK_FLYING) { vec2 new_pos = hook_pos+hook_dir*world->tuning.hook_fire_speed; if(distance(pos, new_pos) > world->tuning.hook_length) { hook_state = HOOK_RETRACT_START; new_pos = pos + normalize(new_pos-pos) * world->tuning.hook_length; } // make sure that the hook doesn't go though the ground bool going_to_hit_ground = false; bool going_to_retract = false; int hit = col_intersect_line(hook_pos, new_pos, &new_pos, 0); if(hit) { if(hit&COLFLAG_NOHOOK) going_to_retract = true; else going_to_hit_ground = true; } // Check against other players first if(world && world->tuning.player_hooking) { float dist = 0.0f; for(int i = 0; i < MAX_CLIENTS; i++) { CHARACTER_CORE *p = world->characters[i]; if(!p || p == this) continue; vec2 closest_point = closest_point_on_line(hook_pos, new_pos, p->pos); if(distance(p->pos, closest_point) < phys_size+2.0f) { if (hooked_player == -1 || distance (hook_pos, p->pos) < dist) { triggered_events |= COREEVENT_HOOK_ATTACH_PLAYER; hook_state = HOOK_GRABBED; hooked_player = i; dist = distance (hook_pos, p->pos); } } } } if(hook_state == HOOK_FLYING) { // check against ground if(going_to_hit_ground) { triggered_events |= COREEVENT_HOOK_ATTACH_GROUND; hook_state = HOOK_GRABBED; } else if(going_to_retract) { triggered_events |= COREEVENT_HOOK_HIT_NOHOOK; hook_state = HOOK_RETRACT_START; } hook_pos = new_pos; } } if(hook_state == HOOK_GRABBED) { if(hooked_player != -1) { CHARACTER_CORE *p = world->characters[hooked_player]; if(p) hook_pos = p->pos; else { // release hook hooked_player = -1; hook_state = HOOK_RETRACTED; hook_pos = pos; } // keep players hooked for a max of 1.5sec //if(server_tick() > hook_tick+(server_tickspeed()*3)/2) //release_hooked(); } // don't do this hook rutine when we are hook to a player if(hooked_player == -1 && distance(hook_pos, pos) > 46.0f) { vec2 hookvel = normalize(hook_pos-pos)*world->tuning.hook_drag_accel; // the hook as more power to drag you up then down. // this makes it easier to get on top of an platform if(hookvel.y > 0) hookvel.y *= 0.3f; // the hook will boost it's power if the player wants to move // in that direction. otherwise it will dampen everything abit if((hookvel.x < 0 && direction < 0) || (hookvel.x > 0 && direction > 0)) hookvel.x *= 0.95f; else hookvel.x *= 0.75f; vec2 new_vel = vel+hookvel; // check if we are under the legal limit for the hook if(length(new_vel) < world->tuning.hook_drag_speed || length(new_vel) < length(vel)) vel = new_vel; // no problem. apply } // release hook (max hook time is 1.25 hook_tick++; if(hooked_player != -1 && (hook_tick > SERVER_TICK_SPEED+SERVER_TICK_SPEED/5 || !world->characters[hooked_player])) { hooked_player = -1; hook_state = HOOK_RETRACTED; hook_pos = pos; } } if(world && world->tuning.player_collision) { for(int i = 0; i < MAX_CLIENTS; i++) { CHARACTER_CORE *p = world->characters[i]; if(!p) continue; //player *p = (player*)ent; if(p == this) // || !(p->flags&FLAG_ALIVE) continue; // make sure that we don't nudge our self // handle player <-> player collision float d = distance(pos, p->pos); vec2 dir = normalize(pos - p->pos); if(d < phys_size*1.25f && d > 1.0f) { float a = (phys_size*1.45f - d); // make sure that we don't add excess force by checking the // direction against the current velocity vec2 veldir = normalize(vel); float v = 1-(dot(veldir, dir)+1)/2; vel = vel + dir*a*(v*0.75f); vel = vel * 0.85f; } // handle hook influence if(hooked_player == i) { if(d > phys_size*1.50f) // TODO: fix tweakable variable { float accel = world->tuning.hook_drag_accel * (d/world->tuning.hook_length); float drag_speed = world->tuning.hook_drag_speed; // add force to the hooked player p->vel.x = saturated_add(-drag_speed, drag_speed, p->vel.x, accel*dir.x*1.5f); p->vel.y = saturated_add(-drag_speed, drag_speed, p->vel.y, accel*dir.y*1.5f); // add a little bit force to the guy who has the grip vel.x = saturated_add(-drag_speed, drag_speed, vel.x, -accel*dir.x*0.25f); vel.y = saturated_add(-drag_speed, drag_speed, vel.y, -accel*dir.y*0.25f); } } } } // clamp the velocity to something sane if(length(vel) > 6000) vel = normalize(vel) * 6000; }