/* ** convert an hexadecimal numeric string to a number, following ** C99 specification for 'strtod' */ static lua_Number lua_strx2number (const char *s, char **endptr) { lua_Number r = 0.0; /* result (accumulator) */ int sigdig = 0; /* number of significant digits */ int nosigdig = 0; /* number of non-significant digits */ int e = 0; /* exponent correction */ int neg = 0; /* 1 if number is negative */ int dot = 0; /* true after seen a dot */ *endptr = cast(char *, s); /* nothing is valid yet */ while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ neg = isneg(&s); /* check signal */ if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ return 0.0; /* invalid format (no '0x') */ for (s += 2; ; s++) { /* skip '0x' and read numeral */ if (*s == '.') { if (dot) break; /* second dot? stop loop */ else dot = 1; } else if (lisxdigit(cast_uchar(*s))) { if (sigdig == 0 && *s == '0') { /* non-significant zero? */ nosigdig++; if (dot) e--; /* zero after dot? correct exponent */ } else { if (++sigdig <= MAXSIGDIG) { /* can read it without overflow? */ r = (r * cast_num(16.0)) + luaO_hexavalue(cast_uchar(*s)); if (dot) e--; /* decimal digit */ } else /* too many digits; ignore */ if (!dot) e++; /* still count it for exponent */ } } else break; /* neither a dot nor a digit */ } if (nosigdig + sigdig == 0) /* no digits? */ return 0.0; /* invalid format */ *endptr = cast(char *, s); /* valid up to here */ e *= 4; /* each digit multiplies/divides value by 2^4 */ if (*s == 'p' || *s == 'P') { /* exponent part? */ int exp1 = 0; /* exponent value */ int neg1; /* exponent signal */ s++; /* skip 'p' */ neg1 = isneg(&s); /* signal */ if (!lisdigit(cast_uchar(*s))) return 0.0; /* invalid; must have at least one digit */ while (lisdigit(cast_uchar(*s))) /* read exponent */ exp1 = exp1 * 10 + *(s++) - '0'; if (neg1) exp1 = -exp1; e += exp1; *endptr = cast(char *, s); /* valid up to here */ }
char *ft_itoa(int n) { char *str; int tmpn; int len; int neg; tmpn = n; len = 1; neg = 0; isneg(&n, &neg); if (n == -2147483648) return (ft_strdup("-2147483648")); while (tmpn /= 10) len++; len += neg; if ((str = (char*)malloc(sizeof(char) * len)) == NULL) return (NULL); str[len] = '\0'; while (len--) { str[len] = n % 10 + '0'; n = n / 10; } if (neg) str[0] = '-'; return (str); }
/* ** convert an hexadecimal numeric string to a number, following ** C99 specification for 'strtod' */ static lua_Number lua_strx2number (const char *s, char **endptr) { lua_Number r = 0.0; int e = 0, i = 0; int neg = 0; /* 1 if number is negative */ *endptr = cast(char *, s); /* nothing is valid yet */ while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ neg = isneg(&s); /* check signal */ if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ return 0.0; /* invalid format (no '0x') */ s += 2; /* skip '0x' */ r = readhexa(&s, r, &i); /* read integer part */ if (*s == '.') { s++; /* skip dot */ r = readhexa(&s, r, &e); /* read fractional part */ } if (i == 0 && e == 0) return 0.0; /* invalid format (no digit) */ e *= -4; /* each fractional digit divides value by 2^-4 */ *endptr = cast(char *, s); /* valid up to here */ if (*s == 'p' || *s == 'P') { /* exponent part? */ int exp1 = 0; int neg1; s++; /* skip 'p' */ neg1 = isneg(&s); /* signal */ if (!lisdigit(cast_uchar(*s))) goto ret; /* must have at least one digit */ while (lisdigit(cast_uchar(*s))) /* read exponent */ exp1 = exp1 * 10 + *(s++) - '0'; if (neg1) exp1 = -exp1; e += exp1; } *endptr = cast(char *, s); /* valid up to here */ ret: if (neg) r = -r; return l_mathop(ldexp)(r, e); }
char *ft_itoa(int n) { char *nb; int i; char *rnb; i = 0; nb = (char *)malloc(sizeof(char) * 12); rnb = (char *)malloc(sizeof(char) * 12); if (n == -2147483648) return (ft_strdup("-2147483648")); if (n >= 0 && n < 10) { nb[0] = n + 48; nb[1] = '\0'; free(rnb); return (nb); } if (n > 9) return (ispos(n, nb, rnb)); if (n < 0) return (isneg(n, nb, rnb)); return (NULL); }
////////////////////////////////////////////////////////////////////////// // NOTE: This function must be thread-safe. Before adding stuff contact MarcoC. void CVehicleMovementStdBoat::ProcessMovement(const float deltaTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); static const float fWaterLevelMaxDiff = 0.15f; // max allowed height difference between propeller center and water level static const float fSubmergedMin = 0.01f; static const float fMinSpeedForTurn = 0.5f; // min speed so that turning becomes possible if (m_bNetSync) m_netActionSync.UpdateObject(this); CryAutoCriticalSection lk(m_lock); CVehicleMovementBase::ProcessMovement(deltaTime); IEntity* pEntity = m_pVehicle->GetEntity(); IPhysicalEntity* pPhysics = pEntity->GetPhysics(); SVehiclePhysicsStatus* physStatus = &m_physStatus[k_physicsThread]; assert(pPhysics); float frameTime = min(deltaTime, 0.1f); if (abs(m_movementAction.power) < 0.001f) m_movementAction.power = 0.f; if (abs(m_movementAction.rotateYaw) < 0.001f) m_movementAction.rotateYaw = 0.f; Matrix34 wTM( physStatus->q ); wTM.AddTranslation( physStatus->pos ); Matrix34 wTMInv = wTM.GetInvertedFast(); Vec3 localVel = wTMInv.TransformVector( physStatus->v ); Vec3 localW = wTMInv.TransformVector( physStatus->w ); const Vec3 xAxis = wTM.GetColumn0(); const Vec3 yAxis = wTM.GetColumn1(); const Vec3 zAxis = wTM.GetColumn2(); // check if propeller is in water Vec3 worldPropPos = wTM * m_pushOffset; float waterLevelWorld = gEnv->p3DEngine->GetWaterLevel( &worldPropPos ); float fWaterLevelDiff = worldPropPos.z - waterLevelWorld; bool submerged = physStatus->submergedFraction > fSubmergedMin; m_inWater = submerged && fWaterLevelDiff < fWaterLevelMaxDiff; float speed = physStatus->v.len2() > 0.001f ? physStatus->v.len() : 0.f; float speedRatio = min(1.f, speed/(m_maxSpeed*m_factorMaxSpeed)); float absPedal = abs(m_movementAction.power); float absSteer = abs(m_movementAction.rotateYaw); // wave stuff float waveFreq = 1.f; waveFreq += 3.f*speedRatio; float waveTimerPrev = m_waveTimer; m_waveTimer += frameTime*waveFreq; // new randomized amount for this oscillation if (m_waveTimer >= gf_PI && waveTimerPrev < gf_PI) m_waveRandomMult = cry_random(0.0f, 1.0f); if (m_waveTimer >= 2*gf_PI) m_waveTimer -= 2*gf_PI; float kx = m_waveIdleStrength.x*(m_waveRandomMult+0.3f) * (1.f-speedRatio + m_waveSpeedMult*speedRatio); float ky = m_waveIdleStrength.y * (1.f - 0.5f*absPedal - 0.5f*absSteer); Vec3 waveLoc = m_massOffset; waveLoc.y += speedRatio*min(0.f, m_pushOffset.y-m_massOffset.y); waveLoc = wTM * waveLoc; bool visible = m_pVehicle->GetGameObject()->IsProbablyVisible(); bool doWave = visible && submerged && physStatus->submergedFraction < 0.99f; if (doWave && !m_isEnginePowered) m_pVehicle->NeedsUpdate(IVehicle::eVUF_AwakePhysics); if (m_isEnginePowered || (visible && !m_pVehicle->IsProbablyDistant())) { if (doWave && (m_isEnginePowered || g_pGameCVars->v_rockBoats)) { pe_action_impulse waveImp; waveImp.angImpulse.x = Boosting() ? 0.f : sinf(m_waveTimer) * frameTime * m_Inertia.x * kx; if (isneg(waveImp.angImpulse.x)) waveImp.angImpulse.x *= (1.f - min(1.f, 2.f*speedRatio)); // less amplitude for negative impulse waveImp.angImpulse.y = sinf(m_waveTimer-0.5f*gf_PI) * frameTime * m_Inertia.y * ky; waveImp.angImpulse.z = 0.f; waveImp.angImpulse = wTM.TransformVector(waveImp.angImpulse); waveImp.point = waveLoc; if (!m_movementAction.isAI) pPhysics->Action(&waveImp, 1); } } // ~wave stuff if (!m_isEnginePowered) return; pe_action_impulse linearImp, angularImp, dampImp, liftImp; float turnAccel = 0, turnAccelNorm = 0; if (m_inWater) { // Lateral damping if (m_lateralDamping>0.f) { pe_action_impulse impulse; impulse.impulse = - physStatus->mass * xAxis * (localVel.x * (frameTime * m_lateralDamping)/(1.f + frameTime*m_lateralDamping)); pPhysics->Action(&impulse, 1); } // optional lifting (catamarans) if (m_velLift > 0.f) { if (localVel.y > m_velLift && !IsLifted()) Lift(true); else if (localVel.y < m_velLift && IsLifted()) Lift(false); } if (Boosting() && IsLifted()) { // additional lift force liftImp.impulse = Vec3(0,0,physStatus->mass*frameTime*(localVel.y/(m_velMax*m_factorMaxSpeed))*3.f); liftImp.point = wTM * m_massOffset; pPhysics->Action(&liftImp, 1); } // apply driving force float a = m_movementAction.power; if (sgn(a)*sgn(localVel.y) > 0) { // reduce acceleration with increasing speed float ratio = (localVel.y > 0.f) ? localVel.y/(m_velMax*m_factorMaxSpeed) : -localVel.y/(m_velMaxReverse*m_factorMaxSpeed); a = (ratio>1.f) ? 0.f : sgn(a)*min(abs(a), 1.f-((1.f-m_accelVelMax)*sqr(ratio))); } if (a != 0) { if (sgn(a) * sgn(localVel.y) < 0) // "braking" a *= m_accelCoeff; else a = max(a, -m_pedalLimitReverse); Vec3 pushDir(FORWARD_DIRECTION); // apply force downwards a bit for more realistic response if (a > 0) pushDir = Quat_tpl<float>::CreateRotationAA( DEG2RAD(m_pushTilt), Vec3(-1,0,0) ) * pushDir; pushDir = wTM.TransformVector( pushDir ); linearImp.impulse = pushDir * physStatus->mass * a * m_accel * m_factorAccel * frameTime; linearImp.point = m_pushOffset; linearImp.point.x = m_massOffset.x; linearImp.point = wTM * linearImp.point; pPhysics->Action(&linearImp, 1); } float roll = (float)__fsel(zAxis.z - 0.2f, xAxis.z / (frameTime + frameTime*frameTime), 0.f); // Roll damping (with a exp. time constant of 1 sec) // apply steering if (m_movementAction.rotateYaw != 0) { if (abs(localVel.y) < fMinSpeedForTurn){ // if forward speed too small, no turning possible turnAccel = 0; } else { int iDir = m_movementAction.power != 0.f ? sgn(m_movementAction.power) : sgn(localVel.y); turnAccelNorm = m_movementAction.rotateYaw * iDir * max(1.f, m_turnVelocityMult * speedRatio); // steering and current w in same direction? int sgnSteerW = sgn(m_movementAction.rotateYaw) * iDir * sgn(-localW.z); if (sgnSteerW < 0) { // "braking" turnAccelNorm *= m_turnAccelCoeff; } else { // reduce turn vel towards max float maxRatio = 1.f - 0.15f*min(1.f, abs(localW.z)/m_turnRateMax); turnAccelNorm = sgn(turnAccelNorm) * min(abs(turnAccelNorm), maxRatio); } turnAccel = turnAccelNorm * m_turnAccel; //roll = 0.2f * turnAccel; // slight roll } } // Use the centripetal acceleration to determine the amount of roll float centripetalAccel = clamp_tpl(speed * localW.z, -10.f, +10.f); roll -= (1.f - 2.f*fabsf(xAxis.z)) * m_rollAccel * centripetalAccel; // Always damp rotation! turnAccel += localW.z * m_turnDamping; if (turnAccel != 0) { Vec3& angImp = angularImp.angImpulse; angImp.x = 0.f; angImp.y = roll * frameTime * m_Inertia.y; angImp.z = -turnAccel * frameTime * m_Inertia.z; angImp = wTM.TransformVector( angImp ); pPhysics->Action(&angularImp, 1); } if (abs(localVel.x) > 0.01f) { // lateral force Vec3& cornerForce = dampImp.impulse; cornerForce.x = -localVel.x * m_cornerForceCoeff * physStatus->mass * frameTime; cornerForce.y = 0.f; cornerForce.z = 0.f; if (m_cornerTilt != 0) cornerForce = Quat_tpl<float>::CreateRotationAA( sgn(localVel.x)*DEG2RAD(m_cornerTilt), Vec3(0,1,0) ) * cornerForce; dampImp.impulse = wTM.TransformVector(cornerForce); dampImp.point = m_cornerOffset; dampImp.point.x = m_massOffset.x; dampImp.point = wTM.TransformPoint( dampImp.point ); pPhysics->Action(&dampImp, 1); } } EjectionTest(deltaTime); if (!m_pVehicle->GetStatus().doingNetPrediction) { if (m_bNetSync && m_netActionSync.PublishActions( CNetworkMovementStdBoat(this) )) CHANGED_NETWORK_STATE(m_pVehicle, CNetworkMovementStdBoat::CONTROLLED_ASPECT ); } }
/* Evaluate an expression AST, also record an additive external symbol. * If pass is 1 or 2, the expression must be defined in pass 1 or 2 resp. */ Value eval(Expr *e, Sym **ext, int pass) { int shft; Value v, v2; Sym *ex1, *ex2; char name[8]; switch(e->type){ case 0: v.val = e->w; v.rel = 0; return v; case 1: if(!pass2 && pass == 1 && (e->s->type & Def) == 0 || pass2 && pass == 2 && e->s->type & Extern){ unsixbit(e->s->name, name); err(1, "error: symbol %s must be defined", name); return (Value){ 0, 0 }; } if(e->s->type & Extern){ *ext = e->s; return (Value){ 0, 0 }; } return e->s->v; case 2: if(e->op == Minus){ v = eval(e->r, ext, pass); if(*ext) err(1, "error: Invalid use of external"); v.val = negw(v.val); return v; } panic("expression operator"); case 3: ex1 = nil; ex2 = nil; v = eval(e->l, &ex1, pass); v2 = eval(e->r, &ex2, pass); if(ex1 == nil) *ext = ex2; else if(ex2 == nil) *ext = ex1; else err(1, "error: Invalid use of external"); shft = v2.val; if(isneg(v2.val)) shft = -negw(v2.val); switch(e->op){ case Shift: if(shft < 0) v.val >>= -shft; else v.val <<= shft; break; case Exclam: v.val |= v2.val; break; case Amper: v.val &= v2.val; break; case Star: v.val *= v2.val; break; case Slash: v.val /= v2.val; break; case Plus: v.val += v2.val; break; case Minus: v.val -= v2.val; if(v.rel == v2.rel) v.rel = 0; goto ret; default: panic("expression operator"); } v.rel += v2.rel; if(v.rel > 1){ err(1, "error: invalid expression type"); return (Value){ 0, 0 }; } ret: v.val &= 0777777777777; return v; }