diff --git a/src/karts/controller/ai_base_controller.cpp b/src/karts/controller/ai_base_controller.cpp index b7576588b..fa1263fe6 100644 --- a/src/karts/controller/ai_base_controller.cpp +++ b/src/karts/controller/ai_base_controller.cpp @@ -336,7 +336,7 @@ void AIBaseController::saveState(BareNetworkString *buffer) const { // Endcontroller needs this for proper offset in kart rewinder // Must match the number of bytes in Playercontroller. - buffer->addUInt32(0).addUInt16(0).addUInt8(0); + buffer->addInt24(0).addUInt16(0).addUInt8(0); } // copyToBuffer //----------------------------------------------------------------------------- @@ -344,5 +344,5 @@ void AIBaseController::rewindTo(BareNetworkString *buffer) { // Endcontroller needs this for proper offset in kart rewinder. // Skip the same number of bytes as PlayerController. - buffer->skip(4 + 2 + 1); + buffer->skip(3 + 2 + 1); } // rewindTo diff --git a/src/karts/controller/kart_control.cpp b/src/karts/controller/kart_control.cpp index 91f8b7c01..d6816301f 100644 --- a/src/karts/controller/kart_control.cpp +++ b/src/karts/controller/kart_control.cpp @@ -19,18 +19,23 @@ #include "karts/controller/kart_control.hpp" #include "network/network_string.hpp" +#include "irrMath.h" +#include + // ------------------------------------------------------------------------ /** Sets the current steering value. */ void KartControl::setSteer(float f) { - m_steer = f; + int steer = irr::core::clamp((int)(f * 32767.0f), -32767, 32767); + m_steer = (int16_t)steer; } // setSteer // ---------------------------------------------------------------------------- /** Sets the acceleration. */ void KartControl::setAccel(float f) { - m_accel = f; + int accel = std::min((int)(f * 65535.0f), 65535); + m_accel = (uint16_t)accel; } // setAccel // ---------------------------------------------------------------------------- @@ -78,8 +83,8 @@ void KartControl::setLookBack(bool b) /** Copies the important data from this objects into a memory buffer. */ void KartControl::saveState(BareNetworkString *buffer) const { - buffer->add(m_steer); - buffer->add(m_accel); + buffer->addUInt16(m_steer); + buffer->addUInt16(m_accel); buffer->addChar(getButtonsCompressed()); } // saveState @@ -87,7 +92,7 @@ void KartControl::saveState(BareNetworkString *buffer) const /** Restores this object from a previously saved memory buffer. */ void KartControl::rewindTo(BareNetworkString *buffer) { - m_steer = buffer->getFloat(); - m_accel = buffer->getFloat(); + m_steer = buffer->getUInt16(); + m_accel = buffer->getUInt16(); setButtonsCompressed(buffer->getUInt8()); } // setFromMemory diff --git a/src/karts/controller/kart_control.hpp b/src/karts/controller/kart_control.hpp index cc060fcae..8da05be82 100644 --- a/src/karts/controller/kart_control.hpp +++ b/src/karts/controller/kart_control.hpp @@ -19,6 +19,8 @@ #ifndef HEADER_KART_CONTROL_HPP #define HEADER_KART_CONTROL_HPP +#include "utils/types.hpp" + class BareNetworkString; /** @@ -33,10 +35,10 @@ public: enum SkidControl {SC_NONE, SC_NO_DIRECTION, SC_LEFT, SC_RIGHT}; private: - /** The current steering value in [-1, 1]. */ - float m_steer; - /** Acceleration, in [0, 1]. */ - float m_accel; + /** The current steering value in [-32767, 32767]. */ + int16_t m_steer; + /** Acceleration, in [0, 65535]. */ + uint16_t m_accel; /** True if the kart brakes. */ bool m_brake; /** True if the kart activates nitro. */ @@ -126,11 +128,11 @@ public: m_skid = (SkidControl)((c & 96) >> 5); } // setButtonsCompressed // ------------------------------------------------------------------------ - /** Returns the current steering value. */ - float getSteer() const { return m_steer; } + /** Returns the current steering value in [-1, 1]. */ + float getSteer() const { return (float)m_steer / 32767.0f; } // ------------------------------------------------------------------------ - /** Returns current acceleration. */ - float getAccel() const { return m_accel; } + /** Returns current acceleration in [0, 1]. */ + float getAccel() const { return (float)m_accel / 65535.0f; } // ------------------------------------------------------------------------ /** Returns if the kart is braking. */ bool getBrake() const { return m_brake; } diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index 2ecca6155..07c46fa30 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -375,7 +375,7 @@ void PlayerController::saveState(BareNetworkString *buffer) const { // NOTE: when the size changes, the AIBaseController::saveState and // restore state MUST be adjusted!! - buffer->addUInt32(m_steer_val).addUInt16(m_prev_accel) + buffer->addInt24(m_steer_val).addUInt16(m_prev_accel) .addUInt8((m_prev_brake ? 1 : 0) | (m_prev_nitro ? 2 : 0)); } // copyToBuffer @@ -384,7 +384,7 @@ void PlayerController::rewindTo(BareNetworkString *buffer) { // NOTE: when the size changes, the AIBaseController::saveState and // restore state MUST be adjusted!! - m_steer_val = buffer->getUInt32(); + m_steer_val = buffer->getInt24(); m_prev_accel = buffer->getUInt16(); uint8_t c = buffer->getUInt8(); m_prev_brake = (c & 1) != 0; diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 676e380b8..fcb96c45d 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1142,8 +1142,8 @@ void Kart::collectedItem(ItemState *item_state) item_state->getPreviousOwner()->getIdent() == "nolok"); // slow down - m_bubblegum_ticks = - stk_config->time2Ticks(m_kart_properties->getBubblegumDuration()); + m_bubblegum_ticks = (int16_t)stk_config->time2Ticks( + m_kart_properties->getBubblegumDuration()); m_bubblegum_torque = ((World::getWorld()->getTicksSinceStart() / 10) % 2 == 0) ? m_kart_properties->getBubblegumTorque() : diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 1cd2990ab..bf0f9cb71 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -494,10 +494,9 @@ public: /** Makes a kart invulnerable for a certain amount of time. */ virtual void setInvulnerableTicks(int ticks) OVERRIDE { - // The last 3 bits are saving fire clicked, kart animation status and - // plunger state for rewind - if (ticks > 8191) - ticks = 8191; + // int16_t max + if (ticks > 32767) + ticks = 32767; m_invulnerable_ticks = ticks; } // setInvulnerableTicks // ------------------------------------------------------------------------ diff --git a/src/karts/kart_rewinder.cpp b/src/karts/kart_rewinder.cpp index 8bdc55168..015620538 100644 --- a/src/karts/kart_rewinder.cpp +++ b/src/karts/kart_rewinder.cpp @@ -157,18 +157,35 @@ BareNetworkString* KartRewinder::saveState(std::vector* ru) BareNetworkString *buffer = new BareNetworkString(MEMSIZE); - // 1) Firing and related handling - // ----------- - buffer->addUInt16(m_bubblegum_ticks); - bool plunger_on = m_view_blocked_by_plunger != 0; - // m_invulnerable_ticks will not be negative - bool has_animation = m_kart_animation != NULL; - uint16_t fire_and_invulnerable = (m_fire_clicked ? 1 << 15 : 0) | - (has_animation ? 1 << 14 : 0) | (plunger_on ? 1 << 13 : 0) | - m_invulnerable_ticks; - buffer->addUInt16(fire_and_invulnerable); - if (plunger_on) + // 1) Boolean handling to determine if need saving + const bool has_animation = m_kart_animation != NULL; + uint8_t bool_for_each_data = 0; + if (m_fire_clicked) + bool_for_each_data |= 1; + if (m_bubblegum_ticks > 0) + bool_for_each_data |= (1 << 1); + if (m_view_blocked_by_plunger > 0) + bool_for_each_data |= (1 << 2); + if (m_invulnerable_ticks > 0) + bool_for_each_data |= (1 << 3); + if (getEnergy() > 0.0f) + bool_for_each_data |= (1 << 4); + if (has_animation) + bool_for_each_data |= (1 << 5); + if (m_vehicle->getTimedRotationTicks() > 0) + bool_for_each_data |= (1 << 6); + if (m_vehicle->getCentralImpulseTicks() > 0) + bool_for_each_data |= (1 << 7); + buffer->addUInt8(bool_for_each_data); + + if (m_bubblegum_ticks > 0) + buffer->addUInt16(m_bubblegum_ticks); + if (m_view_blocked_by_plunger > 0) buffer->addUInt16(m_view_blocked_by_plunger); + if (m_invulnerable_ticks > 0) + buffer->addUInt16(m_invulnerable_ticks); + if (getEnergy() > 0.0f) + buffer->addFloat(getEnergy()); // 2) Kart animation status or physics values (transform and velocities) // ------------------------------------------- @@ -186,13 +203,19 @@ BareNetworkString* KartRewinder::saveState(std::vector* ru) buffer->add(q); buffer->add(body->getLinearVelocity()); buffer->add(body->getAngularVelocity()); - buffer->addUInt16(m_vehicle->getTimedRotationTicks()); - buffer->addFloat(m_vehicle->getTimedRotation()); + if (m_vehicle->getTimedRotationTicks() > 0) + { + buffer->addUInt16(m_vehicle->getTimedRotationTicks()); + buffer->addFloat(m_vehicle->getTimedRotation()); + } // For collision rewind buffer->addUInt16(m_bounce_back_ticks); - buffer->addUInt16(m_vehicle->getCentralImpulseTicks()); - buffer->add(m_vehicle->getAdditionalImpulse()); + if (m_vehicle->getCentralImpulseTicks() > 0) + { + buffer->addUInt16(m_vehicle->getCentralImpulseTicks()); + buffer->add(m_vehicle->getAdditionalImpulse()); + } } // 3) Steering and other player controls @@ -204,7 +227,6 @@ BareNetworkString* KartRewinder::saveState(std::vector* ru) // ----------------------------- getAttachment()->saveState(buffer); getPowerup()->saveState(buffer); - buffer->addFloat(getEnergy()); // 5) Max speed info // ------------------ @@ -227,19 +249,40 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count) { m_has_server_state = true; - // 1) Firing and related handling + // 1) Boolean handling to determine if need saving // ----------- - m_bubblegum_ticks = buffer->getUInt16(); - uint16_t fire_and_invulnerable = buffer->getUInt16(); - m_fire_clicked = ((fire_and_invulnerable >> 15) & 1) == 1; - bool has_animation_in_state = ((fire_and_invulnerable >> 14) & 1) == 1; - bool has_plunger = ((fire_and_invulnerable >> 13) & 1) == 1; - if (has_plunger) + uint8_t bool_for_each_data = buffer->getUInt8(); + m_fire_clicked = (bool_for_each_data & 1) == 1; + bool read_bubblegum = ((bool_for_each_data >> 1) & 1) == 1; + bool read_plunger = ((bool_for_each_data >> 2) & 1) == 1; + bool read_invulnerable = ((bool_for_each_data >> 3) & 1) == 1; + bool read_energy = ((bool_for_each_data >> 4) & 1) == 1; + bool has_animation_in_state = ((bool_for_each_data >> 5) & 1) == 1; + bool read_timed_rotation = ((bool_for_each_data >> 6) & 1) == 1; + bool read_impulse = ((bool_for_each_data >> 7) & 1) == 1; + + if (read_bubblegum) + m_bubblegum_ticks = buffer->getUInt16(); + else + m_bubblegum_ticks = 0; + + if (read_plunger) m_view_blocked_by_plunger = buffer->getUInt16(); else m_view_blocked_by_plunger = 0; - m_invulnerable_ticks = fire_and_invulnerable & ~(1 << 13); + if (read_invulnerable) + m_invulnerable_ticks = buffer->getUInt16(); + else + m_invulnerable_ticks = 0; + + if (read_energy) + { + float nitro = buffer->getFloat(); + setEnergy(nitro); + } + else + setEnergy(0.0f); // 2) Kart animation status or transform and velocities // ----------- @@ -294,18 +337,28 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count) // before Moveable::update() is called (which updates the transform) setTrans(kart_trans); - uint16_t time_rot = buffer->getUInt16(); - float timed_rotation_y = buffer->getFloat(); - // Set timed rotation divides by time_rot - m_vehicle->setTimedRotation(time_rot, - stk_config->ticks2Time(time_rot) * timed_rotation_y); + if (read_timed_rotation) + { + uint16_t time_rot = buffer->getUInt16(); + float timed_rotation_y = buffer->getFloat(); + // Set timed rotation divides by time_rot + m_vehicle->setTimedRotation(time_rot, + stk_config->ticks2Time(time_rot) * timed_rotation_y); + } + else + m_vehicle->setTimedRotation(0, 0.0f); // Collision rewind m_bounce_back_ticks = buffer->getUInt16(); - uint16_t central_impulse_ticks = buffer->getUInt16(); - Vec3 additional_impulse = buffer->getVec3(); - m_vehicle->setTimedCentralImpulse(central_impulse_ticks, - additional_impulse, true/*rewind*/); + if (read_impulse) + { + uint16_t central_impulse_ticks = buffer->getUInt16(); + Vec3 additional_impulse = buffer->getVec3(); + m_vehicle->setTimedCentralImpulse(central_impulse_ticks, + additional_impulse, true/*rewind*/); + } + else + m_vehicle->setTimedCentralImpulse(0, Vec3(0.0f), true/*rewind*/); // For the raycast to determine the current material under the kart // the m_hardPointWS of the wheels is used. So after a rewind we @@ -327,8 +380,6 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count) updateWeight(); getPowerup()->rewindTo(buffer); - float nitro = buffer->getFloat(); - setEnergy(nitro); // 5) Max speed info // ------------------