/** * Get information about a key: length of its value and index within the page. * * @return TRUE if key was found, value length via *length, index via *idx, * and whether value is stored in a .dat file via *big. */ bool infopair(DBM *db, char *pag, datum key, size_t *length, int *idx, bool *big) { int i; unsigned n; size_t dsize; const unsigned short *ino = (const unsigned short *) pag; if ((n = ino[0]) == 0) return FALSE; if ((i = seepair(db, pag, n, key.dptr, key.dsize)) == 0) return FALSE; dsize = offset(ino[i]) - offset(ino[i + 1]); #ifdef BIGDATA if (is_big(ino[i + 1])) { g_assert(dsize >= sizeof(uint32)); dsize = big_length(pag + offset(ino[i + 1])); } #endif if (length != NULL) *length = dsize; if (idx != NULL) *idx = i; if (big != NULL) *big = is_big(ino[i + 1]); return TRUE; /* Key exists */ }
int pagestat(char *pag, unsigned *ksize, unsigned *vsize, int *large_keys, int *large_values) { register unsigned n; register int pfree; register unsigned short *ino = (unsigned short *) pag; int lk = 0, lv = 0; int keysize = 0, valsize = 0; if (!(n = ino[0])) printf("no entries.\n"); else { unsigned i; unsigned off = DBM_PBLKSIZ; for (i = 1; i < n; i+= 2) { unsigned short koff = offset(ino[i]); unsigned short voff = offset(ino[i+1]); keysize += off - koff; valsize += koff - voff; off = voff; if (is_big(ino[i])) lk++; if (is_big(ino[i+1])) lv++; } pfree = offset(ino[n]) - (n + 1) * sizeof(short); printf("%3d entries, %2d%% used, keys %3d, values %3d, free %3d%s", n / 2, ((DBM_PBLKSIZ - pfree) * 100) / DBM_PBLKSIZ, keysize, valsize, pfree, (DBM_PBLKSIZ - pfree) / (n/2) * (1+n/2) > DBM_PBLKSIZ ? " (LOW)" : ""); if (lk != 0) printf(" (LKEY %d)", lk); if (lv != 0) printf(" (LVAL %d)", lv); putc('\n', stdout); } if (large_keys) *large_keys = lk; if (large_values) *large_values = lv; if (ksize) *ksize = keysize; if (vsize) *vsize = valsize; return n / 2; }
datum getpair(DBM *db, char *pag, datum key) { int i; unsigned n; datum val; const unsigned short *ino = (const unsigned short *) pag; if ((n = ino[0]) == 0) return nullitem; if ((i = seepair(db, pag, n, key.dptr, key.dsize)) == 0) return nullitem; val.dptr = pag + offset(ino[i + 1]); val.dsize = offset(ino[i]) - offset(ino[i + 1]); #ifdef BIGDATA if (is_big(ino[i + 1])) { size_t dsize = big_length(val.dptr); val.dptr = bigval_get(db, val.dptr, val.dsize); val.dsize = (NULL == val.dptr) ? 0 : dsize; } #endif return val; }
void Player::handle_vertical_input() { // Press jump key if(controller->pressed(Controller::JUMP) && (can_jump)) { if (duck) { // when running, only jump a little bit; else do a backflip if (physic.get_velocity_x() != 0) do_jump(-300); else do_backflip(); } else { // jump a bit higher if we are running; else do a normal jump if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520); } } // Let go of jump key else if(!controller->hold(Controller::JUMP)) { if (!backflipping && jumping && physic.get_velocity_y() < 0) { jumping = false; physic.set_velocity_y(0); } } /* In case the player has pressed Down while in a certain range of air, enable butt jump action */ if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && jumping) { butt_jump = true; } /* When Down is not held anymore, disable butt jump */ if(butt_jump && !controller->hold(Controller::DOWN)) butt_jump = false; }
void Player::init() { if(is_big()) set_size(31.8, 62.8); else set_size(31.8, 30.8); dir = RIGHT; old_dir = dir; duck = false; dead = false; dying = false; last_ground_y = 0; fall_mode = ON_GROUND; jumping = false; can_jump = true; butt_jump = false; deactivated = false; backflipping = false; backflip_direction = 0; visible = true; on_ground_flag = false; grabbed_object = NULL; physic.reset(); }
HitResponse BicyclePlatformChild::collision(GameObject& other, const CollisionHit& ) { const float gravity = Sector::get().get_gravity(); // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this: auto mo = dynamic_cast<MovingObject*>(&other); if (!mo) return FORCE_MOVE; if ((mo->get_bbox().get_bottom()) > (m_col.m_bbox.get_top() + 2)) return FORCE_MOVE; auto pl = dynamic_cast<Player*>(mo); if (pl) { if (pl->is_big()) m_momentum += m_parent.m_momentum_change_rate * gravity; auto po = pl->get_grabbed_object(); auto pomo = dynamic_cast<MovingObject*>(po); if (m_contacts.insert(pomo).second) { m_momentum += m_parent.m_momentum_change_rate * gravity; } } if (m_contacts.insert(&other).second) { m_momentum += m_parent.m_momentum_change_rate * Sector::get().get_gravity(); } return FORCE_MOVE; }
/** * Get value for the num-th key in the page. */ datum getnval(DBM *db, char *pag, int num) { int i; int n; datum val; const unsigned short *ino = (const unsigned short *) pag; g_assert(num > 0); i = num * 2 - 1; if ((n = ino[0]) == 0 || i >= n) return nullitem; val.dptr = pag + offset(ino[i + 1]); val.dsize = offset(ino[i]) - offset(ino[i + 1]); #ifdef BIGDATA if (is_big(ino[i + 1])) { size_t dsize = big_length(val.dptr); val.dptr = bigval_get(db, val.dptr, val.dsize); val.dsize = (NULL == val.dptr) ? 0 : dsize; } #else (void) db; #endif return val; }
datum getnkey(DBM *db, char *pag, int num) { datum key; int i; int off; const unsigned short *ino = (const unsigned short *) pag; g_assert(num > 0); i = num * 2 - 1; if (ino[0] == 0 || i > ino[0]) return nullitem; off = (i > 1) ? offset(ino[i - 1]) : DBM_PBLKSIZ; key.dptr = pag + offset(ino[i]); key.dsize = off - offset(ino[i]); #ifdef BIGDATA if (is_big(ino[i])) { size_t dsize = big_length(key.dptr); key.dptr = bigkey_get(db, key.dptr, key.dsize); key.dsize = (NULL == key.dptr) ? 0 : dsize; } #else (void) db; #endif return key; }
/** * Write new value in-place for the pair at index ``i'' on the page. * * @return 0 if OK, -1 on error with errno set. */ int replpair(DBM *db, char *pag, int i, datum val) { unsigned koff; unsigned voff; unsigned short *ino = (unsigned short *) pag; g_assert(UNSIGNED(i) + 1 <= ino[0]); voff = offset(ino[i + 1]); #ifdef BIGDATA if (is_big(ino[i + 1])) return big_replace(db, pag + voff, val.dptr, val.dsize); #else (void) db; /* Parameter unused if no BIGDATA */ #endif koff = offset(ino[i]); g_assert(koff - voff == val.dsize); memcpy(pag + voff, val.dptr, val.dsize); return 0; }
static Eterm math_call_1(Process* p, double (*func)(double), Eterm arg1) { FloatDef a1; Eterm res; Eterm* hp; ERTS_FP_CHECK_INIT(p); if (is_float(arg1)) { GET_DOUBLE(arg1, a1); } else if (is_small(arg1)) { a1.fd = signed_val(arg1); } else if (is_big(arg1)) { if (big_to_double(arg1, &a1.fd) < 0) { badarith: p->freason = BADARITH; return THE_NON_VALUE; } } else { p->freason = BADARG; return THE_NON_VALUE; } a1.fd = (*func)(a1.fd); ERTS_FP_ERROR_THOROUGH(p, a1.fd, goto badarith); hp = HAlloc(p, FLOAT_SIZE_OBJECT); res = make_float(hp); PUT_DOUBLE(a1, hp); return res; }
void Player::handle_vertical_input() { // Press jump key if(controller->pressed(Controller::JUMP)) jump_button_timer.start(JUMP_GRACE_TIME); if (((controller->hold(Controller::JUMP) && jump_button_timer.started()) || jump_helper_jump) && can_jump) { jump_button_timer.stop(); if (duck) { // when running, only jump a little bit; else do a backflip if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) { do_jump(-300); } else { do_backflip(); } } else { // jump a bit higher if we are running; else do a normal jump if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520); } } // Let go of jump key else if(!(controller->hold(Controller::JUMP) || jump_helper_jump)) { if (!backflipping && jumping && physic.get_velocity_y() < 0) { jumping = false; early_jump_apex(); } } if(jump_early_apex && physic.get_velocity_y() >= 0) { do_jump_apex(); } /* In case the player has pressed Down while in a certain range of air, enable butt jump action */ if (controller->hold(Controller::DOWN) && !duck && is_big() && !on_ground()) { wants_buttjump = true; if (physic.get_velocity_y() >= BUTTJUMP_MIN_VELOCITY_Y) does_buttjump = true; } /* When Down is not held anymore, disable butt jump */ if(!controller->hold(Controller::DOWN)) { wants_buttjump = false; does_buttjump = false; } // swimming physic.set_acceleration_y(0); #ifdef SWIMMING if (swimming) { if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP)) physic.set_acceleration_y(-2000); physic.set_velocity_y(physic.get_velocity_y() * 0.94); } #endif }
BIF_RETTYPE abs_1(BIF_ALIST_1) { Eterm res; Sint i0, i; Eterm* hp; /* integer arguments */ if (is_small(BIF_ARG_1)) { i0 = signed_val(BIF_ARG_1); i = ERTS_SMALL_ABS(i0); if (i0 == MIN_SMALL) { hp = HAlloc(BIF_P, BIG_UINT_HEAP_SIZE); BIF_RET(uint_to_big(i, hp)); } else { BIF_RET(make_small(i)); } } else if (is_big(BIF_ARG_1)) { if (!big_sign(BIF_ARG_1)) { BIF_RET(BIF_ARG_1); } else { int sz = big_arity(BIF_ARG_1) + 1; Uint* x; hp = HAlloc(BIF_P, sz); /* See note at beginning of file */ sz--; res = make_big(hp); x = big_val(BIF_ARG_1); *hp++ = make_pos_bignum_header(sz); x++; /* skip thing */ while(sz--) *hp++ = *x++; BIF_RET(res); } } else if (is_float(BIF_ARG_1)) { FloatDef f; GET_DOUBLE(BIF_ARG_1, f); if (f.fd < 0.0) { hp = HAlloc(BIF_P, FLOAT_SIZE_OBJECT); f.fd = fabs(f.fd); res = make_float(hp); PUT_DOUBLE(f, hp); BIF_RET(res); } else BIF_RET(BIF_ARG_1); } BIF_ERROR(BIF_P, BADARG); }
void Player::do_duck() { if (duck) return; if (!is_big()) return; if (physic.get_velocity_y() != 0) return; if (!on_ground()) return; if (adjust_height(31.8)) { duck = true; unduck_hurt_timer.stop(); } else { // FIXME: what now? } }
void Player::move(const Vector& vector) { set_pos(vector); // TODO: do we need the following? Seems irrelevant to moving the player if(is_big()) set_size(31.8, 63.8); else set_size(31.8, 31.8); duck = false; last_ground_y = vector.y; physic.reset(); }
/* Kill Player! */ void Player::kill(bool completely) { if(dying || deactivated) return; if(!completely && safe_timer.started() || invincible_timer.started()) return; sound_manager->play("sounds/hurt.wav"); physic.set_velocity_x(0); if(!completely && is_big()) { if(player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS) { safe_timer.start(TUX_SAFE_TIME); set_bonus(GROWUP_BONUS, true); } else { //growing_timer.start(GROWING_TIME); safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */); adjust_height(30.8); duck = false; set_bonus(NO_BONUS, true); } } else { for (int i = 0; (i < 5) && (i < player_status->coins); i++) { // the numbers: starting x, starting y, velocity y Sector::current()->add_object(new FallingCoin(get_pos() + Vector(systemRandom.rand(5), systemRandom.rand(-32,18)), systemRandom.rand(-100,100))); } physic.enable_gravity(true); physic.set_acceleration(0, 0); physic.set_velocity(0, -700); player_status->coins -= 25; set_bonus(NO_BONUS, true); dying = true; dying_timer.start(3.0); set_group(COLGROUP_DISABLED); DisplayEffect* effect = new DisplayEffect(); effect->fade_out(3.0); Sector::current()->add_object(effect); sound_manager->stop_music(3.0); } }
void Player::init() { if(is_big()) set_size(TUX_WIDTH, BIG_TUX_HEIGHT); else set_size(TUX_WIDTH, SMALL_TUX_HEIGHT); dir = RIGHT; old_dir = dir; duck = false; dead = false; dying = false; winning = false; peekingX = AUTO; peekingY = AUTO; last_ground_y = 0; fall_mode = ON_GROUND; jumping = false; jump_early_apex = false; can_jump = true; wants_buttjump = false; does_buttjump = false; growing = false; deactivated = false; backflipping = false; backflip_direction = 0; sprite->set_angle(0.0f); visible = true; swimming = false; on_ice = false; ice_this_frame = false; speedlimit = 0; //no special limit on_ground_flag = false; grabbed_object = NULL; climbing = 0; jump_helper = false; jump_helper_draw = false; jump_helper_jump = false; jump_helper_move_left = false; jump_helper_move_right = false; physic.reset(); }
void Player::do_jump(float yspeed) { if (!on_ground()) return; physic.set_velocity_y(yspeed); //bbox.move(Vector(0, -1)); jumping = true; on_ground_flag = false; can_jump = false; // play sound if (is_big()) { sound_manager->play("sounds/bigjump.wav"); } else { sound_manager->play("sounds/jump.wav"); } }
void Player::move(const Vector& vector) { set_pos(vector); // Reset size to get correct hitbox if Tux was eg. ducked before moving if(is_big()) set_size(TUX_WIDTH, BIG_TUX_HEIGHT); else set_size(TUX_WIDTH, SMALL_TUX_HEIGHT); duck = false; backflipping = false; sprite->set_angle(0.0f); last_ground_y = vector.y; if (climbing) stop_climbing(*climbing); physic.reset(); }
void Player::do_standup() { if (!duck) return; if (!is_big()) return; if (backflipping) return; if (adjust_height(63.8)) { duck = false; unduck_hurt_timer.stop(); } else { // if timer is not already running, start it. if (unduck_hurt_timer.get_period() == 0) { unduck_hurt_timer.start(UNDUCK_HURT_TIME); } else if (unduck_hurt_timer.check()) { kill(false); } } }
static void insert_node_referrer(ReferredNode *referred_node, int type, Eterm id) { NodeReferrer *nrp; for(nrp = referred_node->referrers; nrp; nrp = nrp->next) if(EQ(id, nrp->id)) break; if(!nrp) { nrp = (NodeReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP, sizeof(NodeReferrer)); nrp->next = referred_node->referrers; referred_node->referrers = nrp; if(IS_CONST(id)) nrp->id = id; else { Uint *hp = &nrp->id_heap[0]; ASSERT(is_big(id) || is_tuple(id)); nrp->id = copy_struct(id, size_object(id), &hp, NULL); } nrp->heap_ref = 0; nrp->link_ref = 0; nrp->monitor_ref = 0; nrp->ets_ref = 0; nrp->bin_ref = 0; nrp->timer_ref = 0; nrp->system_ref = 0; } switch (type) { case HEAP_REF: nrp->heap_ref++; break; case LINK_REF: nrp->link_ref++; break; case ETS_REF: nrp->ets_ref++; break; case BIN_REF: nrp->bin_ref++; break; case MONITOR_REF: nrp->monitor_ref++; break; case TIMER_REF: nrp->timer_ref++; break; case SYSTEM_REF: nrp->system_ref++; break; default: ASSERT(0); } }
HitResponse BicyclePlatform::collision(GameObject& other, const CollisionHit& ) { // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this: auto mo = dynamic_cast<MovingObject*>(&other); if (!mo) return FORCE_MOVE; if ((mo->get_bbox().p2.y) > (bbox.p1.y + 2)) return FORCE_MOVE; auto pl = dynamic_cast<Player*>(mo); if (pl) { if (pl->is_big()) momentum += momentum_change_rate * Sector::get().get_gravity(); auto po = pl->get_grabbed_object(); auto pomo = dynamic_cast<MovingObject*>(po); if (contacts.insert(pomo).second) momentum += momentum_change_rate * Sector::get().get_gravity(); } if (contacts.insert(&other).second) momentum += momentum_change_rate * Sector::get().get_gravity(); return FORCE_MOVE; }
void Player::do_duck() { if (duck) return; if (!is_big()) return; if (physic.get_velocity_y() != 0) return; if (!on_ground()) return; if (does_buttjump) return; if (adjust_height(DUCKED_TUX_HEIGHT)) { duck = true; growing = false; unduck_hurt_timer.stop(); } else { // FIXME: what now? } }
Eterm erl_is_function(Process* p, Eterm arg1, Eterm arg2) { Sint arity; /* * Verify argument 2 (arity); arity must be >= 0. */ if (is_small(arg2)) { arity = signed_val(arg2); if (arity < 0) { error: BIF_ERROR(p, BADARG); } } else if (is_big(arg2) && !bignum_header_is_neg(*big_val(arg2))) { /* A positive bignum is OK, but can't possibly match. */ arity = -1; } else { /* Everything else (including negative bignum) is an error. */ goto error; } if (is_fun(arg1)) { ErlFunThing* funp = (ErlFunThing *) fun_val(arg1); if (funp->arity == (Uint) arity) { BIF_RET(am_true); } } else if (is_export(arg1)) { Export* exp = (Export *) (export_val(arg1)[1]); if (exp->info.mfa.arity == (Uint) arity) { BIF_RET(am_true); } } BIF_RET(am_false); }
void Player::draw(DrawingContext& context) { if(!visible) return; TuxBodyParts* tux_body; if (player_status->bonus == GROWUP_BONUS) tux_body = big_tux; else if (player_status->bonus == FIRE_BONUS) tux_body = fire_tux; else if (player_status->bonus == ICE_BONUS) tux_body = ice_tux; else tux_body = small_tux; int layer = LAYER_OBJECTS + 1; /* Set Tux sprite action */ if (backflipping) { if(dir == LEFT) tux_body->set_action("backflip-left"); else // dir == RIGHT tux_body->set_action("backflip-right"); } else if (duck && is_big()) { if(dir == LEFT) tux_body->set_action("duck-left"); else // dir == RIGHT tux_body->set_action("duck-right"); } else if (skidding_timer.started() && !skidding_timer.check()) { if(dir == LEFT) tux_body->set_action("skid-left"); else // dir == RIGHT tux_body->set_action("skid-right"); } else if (kick_timer.started() && !kick_timer.check()) { if(dir == LEFT) tux_body->set_action("kick-left"); else // dir == RIGHT tux_body->set_action("kick-right"); } else if (butt_jump && is_big()) { if(dir == LEFT) tux_body->set_action("buttjump-left"); else // dir == RIGHT tux_body->set_action("buttjump-right"); } else if (!on_ground()) { if(dir == LEFT) tux_body->set_action("jump-left"); else // dir == RIGHT tux_body->set_action("jump-right"); } else { if (fabsf(physic.get_velocity_x()) < 1.0f) // standing { if(dir == LEFT) tux_body->set_action("stand-left"); else // dir == RIGHT tux_body->set_action("stand-right"); } else // moving { if(dir == LEFT) tux_body->set_action("walk-left"); else // dir == RIGHT tux_body->set_action("walk-right"); } } if(idle_timer.check()) { if(is_big()) { if(dir == LEFT) tux_body->head->set_action("idle-left", 1); else // dir == RIGHT tux_body->head->set_action("idle-right", 1); } } // Tux is holding something if ((grabbed_object != 0 && physic.get_velocity_y() == 0) || (shooting_timer.get_timeleft() > 0 && !shooting_timer.check())) { if (duck) { if(dir == LEFT) tux_body->arms->set_action("duck+grab-left"); else // dir == RIGHT tux_body->arms->set_action("duck+grab-right"); } else { if(dir == LEFT) tux_body->arms->set_action("grab-left"); else // dir == RIGHT tux_body->arms->set_action("grab-right"); } } /* Draw Tux */ if(dying) { smalltux_gameover->draw(context, get_pos(), LAYER_FLOATINGOBJECTS + 1); } else if ((growing_timer.get_timeleft() > 0) && (!duck)) { if (dir == RIGHT) { context.draw_surface(growingtux_right[int((growing_timer.get_timegone() * GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); } else { context.draw_surface(growingtux_left[int((growing_timer.get_timegone() * GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); } } else if (safe_timer.started() && size_t(game_time*40)%2) ; // don't draw Tux else tux_body->draw(context, get_pos(), layer); // Draw blinking star overlay if (invincible_timer.started() && (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING || size_t(game_time*20)%2) && !dying) { if (!is_big() || duck) smalltux_star->draw(context, get_pos(), layer + 5); else bigtux_star->draw(context, get_pos(), layer + 5); } }
static Eterm reference_table_term(Uint **hpp, Uint *szp) { #undef MK_2TUP #undef MK_3TUP #undef MK_CONS #undef MK_UINT #define MK_2TUP(E1, E2) erts_bld_tuple(hpp, szp, 2, (E1), (E2)) #define MK_3TUP(E1, E2, E3) erts_bld_tuple(hpp, szp, 3, (E1), (E2), (E3)) #define MK_CONS(CAR, CDR) erts_bld_cons(hpp, szp, (CAR), (CDR)) #define MK_UINT(UI) erts_bld_uint(hpp, szp, (UI)) int i; Eterm tup; Eterm tup2; Eterm nl = NIL; Eterm dl = NIL; Eterm nrid; for(i = 0; i < no_referred_nodes; i++) { NodeReferrer *nrp; Eterm nril = NIL; for(nrp = referred_nodes[i].referrers; nrp; nrp = nrp->next) { Eterm nrl = NIL; /* NodeReferenceList = [{ReferenceType,References}] */ if(nrp->heap_ref) { tup = MK_2TUP(AM_heap, MK_UINT(nrp->heap_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->link_ref) { tup = MK_2TUP(AM_link, MK_UINT(nrp->link_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->monitor_ref) { tup = MK_2TUP(AM_monitor, MK_UINT(nrp->monitor_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->ets_ref) { tup = MK_2TUP(AM_ets, MK_UINT(nrp->ets_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->bin_ref) { tup = MK_2TUP(AM_binary, MK_UINT(nrp->bin_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->timer_ref) { tup = MK_2TUP(AM_timer, MK_UINT(nrp->timer_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->system_ref) { tup = MK_2TUP(AM_system, MK_UINT(nrp->system_ref)); nrl = MK_CONS(tup, nrl); } nrid = nrp->id; if (!IS_CONST(nrp->id)) { Uint nrid_sz = size_object(nrp->id); if (szp) *szp += nrid_sz; if (hpp) nrid = copy_struct(nrp->id, nrid_sz, hpp, NULL); } if (is_internal_pid(nrid) || nrid == am_error_logger) { ASSERT(!nrp->ets_ref && !nrp->bin_ref && !nrp->system_ref); tup = MK_2TUP(AM_process, nrid); } else if (is_tuple(nrid)) { Eterm *t; ASSERT(!nrp->ets_ref && !nrp->bin_ref); t = tuple_val(nrid); ASSERT(2 == arityval(t[0])); tup = MK_2TUP(t[1], t[2]); } else if(is_internal_port(nrid)) { ASSERT(!nrp->heap_ref && !nrp->ets_ref && !nrp->bin_ref && !nrp->timer_ref && !nrp->system_ref); tup = MK_2TUP(AM_port, nrid); } else if(nrp->ets_ref) { ASSERT(!nrp->heap_ref && !nrp->link_ref && !nrp->monitor_ref && !nrp->bin_ref && !nrp->timer_ref && !nrp->system_ref); tup = MK_2TUP(AM_ets, nrid); } else if(nrp->bin_ref) { ASSERT(is_small(nrid) || is_big(nrid)); ASSERT(!nrp->heap_ref && !nrp->ets_ref && !nrp->link_ref && !nrp->monitor_ref && !nrp->timer_ref && !nrp->system_ref); tup = MK_2TUP(AM_match_spec, nrid); } else { ASSERT(!nrp->heap_ref && !nrp->ets_ref && !nrp->bin_ref); ASSERT(is_atom(nrid)); tup = MK_2TUP(AM_dist, nrid); } tup = MK_2TUP(tup, nrl); /* NodeReferenceIdList = [{{ReferrerType, ID}, NodeReferenceList}] */ nril = MK_CONS(tup, nril); } /* NodeList = [{{Node, Creation}, Refc, NodeReferenceIdList}] */ tup = MK_2TUP(referred_nodes[i].node->sysname, MK_UINT(referred_nodes[i].node->creation)); tup = MK_3TUP(tup, MK_UINT(erts_refc_read(&referred_nodes[i].node->refc, 1)), nril); nl = MK_CONS(tup, nl); } for(i = 0; i < no_referred_dists; i++) { DistReferrer *drp; Eterm dril = NIL; for(drp = referred_dists[i].referrers; drp; drp = drp->next) { Eterm drl = NIL; /* DistReferenceList = [{ReferenceType,References}] */ if(drp->node_ref) { tup = MK_2TUP(AM_node, MK_UINT(drp->node_ref)); drl = MK_CONS(tup, drl); } if(drp->ctrl_ref) { tup = MK_2TUP(AM_control, MK_UINT(drp->ctrl_ref)); drl = MK_CONS(tup, drl); } if (is_internal_pid(drp->id)) { ASSERT(drp->ctrl_ref && !drp->node_ref); tup = MK_2TUP(AM_process, drp->id); } else if(is_internal_port(drp->id)) { ASSERT(drp->ctrl_ref && !drp->node_ref); tup = MK_2TUP(AM_port, drp->id); } else { ASSERT(!drp->ctrl_ref && drp->node_ref); ASSERT(is_atom(drp->id)); tup = MK_2TUP(drp->id, MK_UINT(drp->creation)); tup = MK_2TUP(AM_node, tup); } tup = MK_2TUP(tup, drl); /* DistReferenceIdList = [{{ReferrerType, ID}, DistReferenceList}] */ dril = MK_CONS(tup, dril); } /* DistList = [{Dist, Refc, ReferenceIdList}] */ tup = MK_3TUP(referred_dists[i].dist->sysname, MK_UINT(erts_refc_read(&referred_dists[i].dist->refc, 1)), dril); dl = MK_CONS(tup, dl); } /* {{node_references, NodeList}, {dist_references, DistList}} */ tup = MK_2TUP(AM_node_references, nl); tup2 = MK_2TUP(AM_dist_references, dl); tup = MK_2TUP(tup, tup2); return tup; #undef MK_2TUP #undef MK_3TUP #undef MK_CONS #undef MK_UINT }
static ERTS_INLINE Eterm bld_unique_integer_term(Eterm **hpp, Uint *szp, Uint64 val0, Uint64 val1, int positive) { Uint hsz; Uint64 unique_val[2]; unique_val[0] = ((Uint64) val0); unique_val[0] |= ((Uint64) val1) << unique_data.r.o.left_shift; unique_val[1] = ((Uint64) val1) >> unique_data.r.o.right_shift; unique_val[1] &= unique_data.r.o.mask; if (positive) { unique_val[0]++; if (unique_val[0] == 0) unique_val[1]++; } else { ASSERT(MIN_SMALL < 0); if (unique_val[1] == 0 && unique_val[0] < ((Uint64) -1*((Sint64) MIN_SMALL))) { Sint64 s_unique_val = (Sint64) unique_val[0]; s_unique_val += MIN_SMALL; ASSERT(MIN_SMALL <= s_unique_val && s_unique_val < 0); if (szp) *szp = 0; if (!hpp) return THE_NON_VALUE; return make_small((Sint) s_unique_val); } if (unique_val[0] < ((Uint64) -1*((Sint64) MIN_SMALL))) { ASSERT(unique_val[1] != 0); unique_val[1] -= 1; } unique_val[0] += MIN_SMALL; } if (!unique_val[1]) { if (unique_val[0] <= MAX_SMALL) { if (szp) *szp = 0; if (!hpp) return THE_NON_VALUE; return make_small((Uint) unique_val[0]); } if (szp) *szp = ERTS_UINT64_HEAP_SIZE(unique_val[0]); if (!hpp) return THE_NON_VALUE; return erts_uint64_to_big(unique_val[0], hpp); } else { Eterm tmp, *tmp_hp, res; DeclareTmpHeapNoproc(local_heap, 2*ERTS_MAX_UNIQUE_INT_HEAP_SIZE); UseTmpHeapNoproc(2*ERTS_MAX_UNIQUE_INT_HEAP_SIZE); tmp_hp = local_heap; tmp = erts_uint64_array_to_big(&tmp_hp, 0, 2, unique_val); ASSERT(is_big(tmp)); hsz = big_arity(tmp) + 1; ASSERT(hsz <= ERTS_MAX_UNIQUE_INT_HEAP_SIZE); if (szp) *szp = hsz; if (!hpp) res = THE_NON_VALUE; else { int hix; Eterm *hp = *hpp; tmp_hp = big_val(tmp); for (hix = 0; hix < hsz; hix++) hp[hix] = tmp_hp[hix]; *hpp = hp + hsz; res = make_big(hp); } UnUseTmpHeapNoproc(2*ERTS_MAX_UNIQUE_INT_HEAP_SIZE); return res; } }
jsval to_js(ErlNifEnv* env, JSContext* cx, ERL_NIF_TERM term) { int intval; unsigned int uintval; long longval; unsigned long ulongval; double doubleval; ERL_NIF_TERM head; ERL_NIF_TERM tail; const ERL_NIF_TERM* tuple; int arity; if(enif_is_atom(env, term)) { return to_js_special(env, cx, term); } if(enif_is_binary(env, term)) { return to_js_string(env, cx, term); } if(enif_is_empty_list(env, term)) { return to_js_empty_array(cx); } if(enif_get_int(env, term, &intval)) { return to_js_number(cx, (double) intval); } if(enif_get_uint(env, term, &uintval)) { return to_js_number(cx, (double) uintval); } if(enif_get_long(env, term, &longval)) { return to_js_number(cx, (double) longval); } if(enif_get_ulong(env, term, &ulongval)) { return to_js_number(cx, (double) ulongval); } if(enif_get_double(env, term, &doubleval)) { return to_js_number(cx, doubleval); } // enif doesn't seem to have any API to decode bignums, so use lower-level functions: if(is_big(term) && big_to_double(term, &doubleval) == 0) { return to_js_number(cx, doubleval); } if(enif_get_list_cell(env, term, &head, &tail)) { return to_js_array(env, cx, head, tail); } if(enif_get_tuple(env, term, &arity, &tuple)) { if(arity == 1) { return to_js_object(env, cx, tuple[0]); } } return JSVAL_VOID; }
/** * Delete pair from the page whose key starts at position i. * * @return TRUE if OK. */ bool delipair(DBM *db, char *pag, int i, bool free_bigdata) { int n; unsigned short *ino = (unsigned short *) pag; n = ino[0]; /* Must be in range, and odd number */ if G_UNLIKELY(0 == n || i >= n || !(i & 0x1)) return FALSE; /* * found the key. if it is the last entry * [i.e. i == n - 1] we just adjust the entry count. * hard case: move all data down onto the deleted pair, * shift offsets onto deleted offsets, and adjust them. * [note: 0 < i < n] */ #ifdef BIGDATA if (free_bigdata) { unsigned end = (i > 1) ? offset(ino[i - 1]) : DBM_PBLKSIZ; unsigned koff = offset(ino[i]); unsigned voff = offset(ino[i+1]); /* Free space used by large keys and values */ if (is_big(ino[i]) && !bigkey_free(db, pag + koff, end - koff)) return FALSE; if (is_big(ino[i+1]) && !bigval_free(db, pag + voff, koff - voff)) return FALSE; } #else (void) db; /* Unused parameter unless BIGDATA */ #endif if (i < n - 1) { int m; char *dst = pag + (i == 1 ? DBM_PBLKSIZ : offset(ino[i - 1])); char *src = pag + offset(ino[i + 1]); int zoo = dst - src; debug(("free-up %d ", zoo)); /* * shift data/keys down */ m = offset(ino[i + 1]) - offset(ino[n]); #ifdef DUFF #define MOVB *--dst = *--src if (m > 0) { int loop = (m + 8 - 1) >> 3; switch (m & (8 - 1)) { case 0: do { MOVB; case 7: MOVB; case 6: MOVB; case 5: MOVB; case 4: MOVB; case 3: MOVB; case 2: MOVB; case 1: MOVB; } while (--loop); } }
void Player::draw(DrawingContext& context) { if(!visible) return; // if Tux is above camera, draw little "air arrow" to show where he is x-wise if (Sector::current() && Sector::current()->camera && (get_bbox().p2.y - 16 < Sector::current()->camera->get_translation().y)) { float px = get_pos().x + (get_bbox().p2.x - get_bbox().p1.x - airarrow.get()->get_width()) / 2; float py = Sector::current()->camera->get_translation().y; py += std::min(((py - (get_bbox().p2.y + 16)) / 4), 16.0f); context.draw_surface(airarrow, Vector(px, py), LAYER_HUD - 1); } // Show where Tux will land after using jump helper if (jump_helper_draw && Sector::current() && Sector::current()->camera) { float px = jump_helper_x + (get_bbox().p2.x - get_bbox().p1.x) / 2 - jumparrow.get()->get_width() / 2; float py = get_bbox().p2.y - jumparrow.get()->get_height(); context.draw_surface(jumparrow, Vector(px, py), LAYER_HUD - 1); } std::string sa_prefix = ""; std::string sa_postfix = ""; if (player_status->bonus == GROWUP_BONUS) sa_prefix = "big"; else if (player_status->bonus == FIRE_BONUS) sa_prefix = "fire"; else if (player_status->bonus == ICE_BONUS) sa_prefix = "ice"; else sa_prefix = "small"; if(dir == LEFT) sa_postfix = "-left"; else sa_postfix = "-right"; /* Set Tux sprite action */ if(dying) { sprite->set_action("gameover"); } else if (growing) { sprite->set_action_continued("grow"+sa_postfix); // while growing, do not change action // do_duck() will take care of cancelling growing manually // update() will take care of cancelling when growing completed } else if (climbing) { sprite->set_action(sa_prefix+"-climbing"+sa_postfix); } else if (backflipping) { sprite->set_action(sa_prefix+"-backflip"+sa_postfix); } else if (duck && is_big()) { sprite->set_action(sa_prefix+"-duck"+sa_postfix); } else if (skidding_timer.started() && !skidding_timer.check()) { sprite->set_action(sa_prefix+"-skid"+sa_postfix); } else if (kick_timer.started() && !kick_timer.check()) { sprite->set_action(sa_prefix+"-kick"+sa_postfix); } else if ((wants_buttjump || does_buttjump) && is_big()) { sprite->set_action(sa_prefix+"-buttjump"+sa_postfix); } else if (!on_ground() || fall_mode != ON_GROUND) { if(physic.get_velocity_x() != 0 || fall_mode != ON_GROUND) { sprite->set_action(sa_prefix+"-jump"+sa_postfix); } } else { if (fabsf(physic.get_velocity_x()) < 1.0f) { // Determine which idle stage we're at if (sprite->get_action().find("-stand-") == std::string::npos && sprite->get_action().find("-idle-") == std::string::npos) { idle_stage = 0; idle_timer.start(IDLE_TIME[idle_stage]/1000.0f); sprite->set_action_continued(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix); } else if (idle_timer.check() || (IDLE_TIME[idle_stage] == 0 && sprite->animation_done())) { idle_stage++; if (idle_stage >= IDLE_STAGE_COUNT) idle_stage = 1; idle_timer.start(IDLE_TIME[idle_stage]/1000.0f); if (IDLE_TIME[idle_stage] == 0) sprite->set_action(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix, 1); else sprite->set_action(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix); } else { sprite->set_action_continued(sa_prefix+("-" + IDLE_STAGES[idle_stage])+sa_postfix); } } else { sprite->set_action(sa_prefix+"-walk"+sa_postfix); } } /* // Tux is holding something if ((grabbed_object != 0 && physic.get_velocity_y() == 0) || (shooting_timer.get_timeleft() > 0 && !shooting_timer.check())) { if (duck) { } else { } } */ /* Draw Tux */ if (safe_timer.started() && size_t(game_time*40)%2) ; // don't draw Tux else { sprite->draw(context, get_pos(), LAYER_OBJECTS + 1); } }
/* Kill Player! */ void Player::kill(bool completely) { if(dying || deactivated || is_winning() ) return; if(!completely && (safe_timer.started() || invincible_timer.started())) return; growing = false; if (climbing) stop_climbing(*climbing); physic.set_velocity_x(0); sprite->set_angle(0.0f); if(!completely && is_big()) { SoundManager::current()->play("sounds/hurt.wav"); if(player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS) { safe_timer.start(TUX_SAFE_TIME); set_bonus(GROWUP_BONUS, true); } else if(player_status->bonus == GROWUP_BONUS) { safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */); adjust_height(SMALL_TUX_HEIGHT); duck = false; backflipping = false; sprite->set_angle(0.0f); set_bonus(NO_BONUS, true); } else if(player_status->bonus == NO_BONUS) { safe_timer.start(TUX_SAFE_TIME); adjust_height(SMALL_TUX_HEIGHT); duck = false; } } else { SoundManager::current()->play("sounds/kill.wav"); // do not die when in edit mode if (edit_mode) { set_ghost_mode(true); return; } if (player_status->coins >= 25 && !GameSession::current()->get_reset_point_sectorname().empty()) { for (int i = 0; i < 5; i++) { // the numbers: starting x, starting y, velocity y Sector::current()->add_object(std::make_shared<FallingCoin>(get_pos() + Vector(graphicsRandom.rand(5), graphicsRandom.rand(-32,18)), graphicsRandom.rand(-100,100))); } player_status->coins -= std::max(player_status->coins/10, 25); } else { GameSession::current()->set_reset_point("", Vector()); } physic.enable_gravity(true); physic.set_gravity_modifier(1.0f); // Undo jump_early_apex safe_timer.stop(); invincible_timer.stop(); physic.set_acceleration(0, 0); physic.set_velocity(0, -700); set_bonus(NO_BONUS, true); dying = true; dying_timer.start(3.0); set_group(COLGROUP_DISABLED); // TODO: need nice way to handle players dying in co-op mode Sector::current()->effect->fade_out(3.0); SoundManager::current()->stop_music(3.0); } }