Compress kart control action
This commit is contained in:
parent
01b95d873e
commit
4c6d535f00
@ -335,7 +335,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).addUInt32(0).addUInt8(0);
|
||||
buffer->addUInt32(0).addUInt16(0).addUInt8(0);
|
||||
} // copyToBuffer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -343,5 +343,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(4 + 2 + 1);
|
||||
} // rewindTo
|
||||
|
@ -171,10 +171,12 @@ bool PlayerController::action(PlayerAction action, int value, bool dry_run)
|
||||
|
||||
break;
|
||||
case PA_ACCEL:
|
||||
SET_OR_TEST(m_prev_accel, value);
|
||||
if (value)
|
||||
{
|
||||
uint16_t v16 = (uint16_t)value;
|
||||
SET_OR_TEST(m_prev_accel, v16);
|
||||
if (v16)
|
||||
{
|
||||
SET_OR_TEST_GETTER(Accel, value/32768.0f);
|
||||
SET_OR_TEST_GETTER(Accel, v16 / 32768.0f);
|
||||
SET_OR_TEST_GETTER(Brake, false);
|
||||
SET_OR_TEST_GETTER(Nitro, m_prev_nitro);
|
||||
}
|
||||
@ -185,6 +187,7 @@ bool PlayerController::action(PlayerAction action, int value, bool dry_run)
|
||||
SET_OR_TEST_GETTER(Nitro, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PA_BRAKE:
|
||||
SET_OR_TEST(m_prev_brake, value!=0);
|
||||
// let's consider below that to be a deadzone
|
||||
@ -374,8 +377,8 @@ 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).addUInt32(m_prev_accel)
|
||||
.addUInt8(m_prev_brake);
|
||||
buffer->addUInt32(m_steer_val).addUInt16(m_prev_accel)
|
||||
.addUInt8((m_prev_brake ? 1 : 0) | (m_prev_nitro ? 2 : 0));
|
||||
} // copyToBuffer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -384,8 +387,10 @@ 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_prev_accel = buffer->getUInt32();
|
||||
m_prev_brake = buffer->getUInt8();
|
||||
m_prev_accel = buffer->getUInt16();
|
||||
uint8_t c = buffer->getUInt8();
|
||||
m_prev_brake = (c & 1) != 0;
|
||||
m_prev_nitro = (c & 2) != 0;
|
||||
} // rewindTo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -29,7 +29,7 @@ class PlayerController : public Controller
|
||||
friend class KartRewinder;
|
||||
protected:
|
||||
int m_steer_val, m_steer_val_l, m_steer_val_r;
|
||||
int m_prev_accel;
|
||||
uint16_t m_prev_accel;
|
||||
bool m_prev_brake;
|
||||
bool m_prev_nitro;
|
||||
|
||||
|
@ -77,11 +77,17 @@ void GameProtocol::sendActions()
|
||||
// Clear left-over data from previous frame. This way the network
|
||||
// string will increase till it reaches maximum size necessary
|
||||
m_data_to_send->clear();
|
||||
if (m_all_actions.size() > 255)
|
||||
{
|
||||
Log::warn("GameProtocol",
|
||||
"Too many actions unsent %d.", (int)m_all_actions.size());
|
||||
m_all_actions.resize(255);
|
||||
}
|
||||
m_data_to_send->addUInt8(GP_CONTROLLER_ACTION)
|
||||
.addUInt8(uint8_t(m_all_actions.size()));
|
||||
|
||||
// Add all actions
|
||||
for (auto a : m_all_actions)
|
||||
for (auto& a : m_all_actions)
|
||||
{
|
||||
if (Network::m_connection_debug)
|
||||
{
|
||||
@ -92,8 +98,9 @@ void GameProtocol::sendActions()
|
||||
}
|
||||
m_data_to_send->addUInt32(a.m_ticks);
|
||||
m_data_to_send->addUInt8(a.m_kart_id);
|
||||
m_data_to_send->addUInt8((uint8_t)(a.m_action)).addUInt32(a.m_value)
|
||||
.addUInt32(a.m_value_l).addUInt32(a.m_value_r);
|
||||
const auto& c = compressAction(a);
|
||||
m_data_to_send->addUInt8(std::get<0>(c)).addUInt16(std::get<1>(c))
|
||||
.addUInt16(std::get<2>(c)).addUInt16(std::get<3>(c));
|
||||
} // for a in m_all_actions
|
||||
|
||||
// FIXME: for now send reliable
|
||||
@ -147,12 +154,12 @@ void GameProtocol::controllerAction(int kart_id, PlayerAction action,
|
||||
a.m_ticks = World::getWorld()->getTicksSinceStart();
|
||||
|
||||
m_all_actions.push_back(a);
|
||||
|
||||
const auto& c = compressAction(a);
|
||||
// Store the event in the rewind manager, which is responsible
|
||||
// for freeing the allocated memory
|
||||
BareNetworkString *s = new BareNetworkString(4);
|
||||
s->addUInt8(kart_id).addUInt8(action).addUInt32(value)
|
||||
.addUInt32(val_l).addUInt32(val_r);
|
||||
s->addUInt8(kart_id).addUInt8(std::get<0>(c)).addUInt16(std::get<1>(c))
|
||||
.addUInt16(std::get<2>(c)).addUInt16(std::get<3>(c));
|
||||
|
||||
RewindManager::get()->addEvent(this, s, /*confirmed*/true,
|
||||
World::getWorld()->getTicksSinceStart());
|
||||
@ -193,19 +200,21 @@ void GameProtocol::handleControllerAction(Event *event)
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerAction action = (PlayerAction)(data.getUInt8());
|
||||
int value = data.getUInt32();
|
||||
int value_l = data.getUInt32();
|
||||
int value_r = data.getUInt32();
|
||||
uint8_t w = data.getUInt8();
|
||||
uint16_t x = data.getUInt16();
|
||||
uint16_t y = data.getUInt16();
|
||||
uint16_t z = data.getUInt16();
|
||||
if (Network::m_connection_debug)
|
||||
{
|
||||
const auto& a = decompressAction(w, x, y, z);
|
||||
Log::verbose("GameProtocol",
|
||||
"Controller action: %d %d %d %d %d %d",
|
||||
cur_ticks, kart_id, action, value, value_l, value_r);
|
||||
cur_ticks, kart_id, std::get<0>(a), std::get<1>(a),
|
||||
std::get<2>(a), std::get<3>(a));
|
||||
}
|
||||
BareNetworkString *s = new BareNetworkString(3);
|
||||
s->addUInt8(kart_id).addUInt8(action).addUInt32(value)
|
||||
.addUInt32(value_l).addUInt32(value_r);
|
||||
s->addUInt8(kart_id).addUInt8(w).addUInt16(x).addUInt16(y)
|
||||
.addUInt16(z);
|
||||
RewindManager::get()->addNetworkEvent(this, s, cur_ticks);
|
||||
}
|
||||
|
||||
@ -425,15 +434,19 @@ void GameProtocol::undo(BareNetworkString *buffer)
|
||||
void GameProtocol::rewind(BareNetworkString *buffer)
|
||||
{
|
||||
int kart_id = buffer->getUInt8();
|
||||
PlayerAction action = PlayerAction(buffer->getUInt8());
|
||||
int value = buffer->getUInt32();
|
||||
int value_l = buffer->getUInt32();
|
||||
int value_r = buffer->getUInt32();
|
||||
uint8_t w = buffer->getUInt8();
|
||||
uint16_t x = buffer->getUInt16();
|
||||
uint16_t y = buffer->getUInt16();
|
||||
uint16_t z = buffer->getUInt16();
|
||||
const auto& a = decompressAction(w, x, y, z);
|
||||
Controller *c = World::getWorld()->getKart(kart_id)->getController();
|
||||
PlayerController *pc = dynamic_cast<PlayerController*>(c);
|
||||
// This can be endcontroller when finishing the race
|
||||
if (pc)
|
||||
pc->actionFromNetwork(action, value, value_l, value_r);
|
||||
{
|
||||
pc->actionFromNetwork(std::get<0>(a), std::get<1>(a), std::get<2>(a),
|
||||
std::get<3>(a));
|
||||
}
|
||||
} // rewind
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -26,8 +26,10 @@
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
class BareNetworkString;
|
||||
class NetworkString;
|
||||
@ -75,7 +77,28 @@ private:
|
||||
static std::weak_ptr<GameProtocol> m_game_protocol;
|
||||
std::map<STKPeer*, int> m_initial_ticks;
|
||||
std::map<STKPeer*, double> m_last_adjustments;
|
||||
|
||||
// Maximum value of values are only 32768
|
||||
std::tuple<uint8_t, uint16_t, uint16_t, uint16_t>
|
||||
compressAction(const Action& a)
|
||||
{
|
||||
uint8_t w = (uint8_t)(a.m_action & 63) |
|
||||
(a.m_value_l > 0 ? 64 : 0) | (a.m_value_r > 0 ? 128 : 0);
|
||||
uint16_t x = (uint16_t)a.m_value;
|
||||
uint16_t y = (uint16_t)std::abs(a.m_value_l);
|
||||
uint16_t z = (uint16_t)std::abs(a.m_value_r);
|
||||
return std::make_tuple(w, x, y, z);
|
||||
}
|
||||
std::tuple<PlayerAction, int, int, int>
|
||||
decompressAction(uint8_t w, uint16_t x, uint16_t y , uint16_t z)
|
||||
{
|
||||
PlayerAction a = (PlayerAction)(w & 63);
|
||||
int l_sign = ((w >> 6) & 1) != 0 ? 1 : -1;
|
||||
int r_sign = ((w >> 7) & 1) != 0 ? 1 : -1;
|
||||
int b = x;
|
||||
int c = y * l_sign;
|
||||
int d = z * r_sign;
|
||||
return std::make_tuple(a, b, c, d);
|
||||
}
|
||||
public:
|
||||
GameProtocol();
|
||||
virtual ~GameProtocol();
|
||||
|
Loading…
x
Reference in New Issue
Block a user