Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
  3.  * It is copyright by its individual contributors, as recorded in the
  4.  * project's Git history.  See COPYING.txt at the top level for license
  5.  * terms and a link to the Git history.
  6.  */
  7. #pragma once
  8.  
  9. #include <type_traits>
  10. #include "dxxerror.h"
  11. #include "object.h"
  12. #include "powerup.h"
  13. #include "serial.h"
  14. #include "fwd-player.h"
  15.  
  16. #define _UNPACK_MULTIPLAYER_SERIAL_MESSAGE(A,...)       A, ## __VA_ARGS__
  17. #define DEFINE_MULTIPLAYER_SERIAL_MESSAGE(C,T,V,A)      \
  18.         DEFINE_SERIAL_UDT_TO_MESSAGE(T,V, (multiplayer_command<C>(), _UNPACK_MULTIPLAYER_SERIAL_MESSAGE A));    \
  19.         ASSERT_SERIAL_UDT_MESSAGE_SIZE(T, command_length<C>::value)
  20.  
  21. #define define_multiplayer_command(NAME,SIZE)   NAME,
  22.  
  23. #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
  24. #define for_each_multiplayer_command(VALUE)     \
  25.         VALUE(MULTI_POSITION              , 1 + quaternionpos::packed_size::value)      \
  26.         VALUE(MULTI_REAPPEAR              , 4)  \
  27.         VALUE(MULTI_FIRE                  , 18) \
  28.         VALUE(MULTI_FIRE_TRACK            , 21) \
  29.         VALUE(MULTI_FIRE_BOMB             , 20) \
  30.         VALUE(MULTI_REMOVE_OBJECT         , 4)  \
  31.         VALUE(MULTI_MESSAGE               , 37) /* (MAX_MESSAGE_LENGTH = 40) */ \
  32.         VALUE(MULTI_QUIT                  , 2)  \
  33.         VALUE(MULTI_PLAY_SOUND           , 8)   \
  34.         VALUE(MULTI_CONTROLCEN           , 4)   \
  35.         VALUE(MULTI_ROBOT_CLAIM          , 5)   \
  36.         VALUE(MULTI_CLOAK                , 2)   \
  37.         VALUE(MULTI_ENDLEVEL_START       , DXX_MP_SIZE_ENDLEVEL_START)  \
  38.         VALUE(MULTI_CREATE_EXPLOSION     , 2)   \
  39.         VALUE(MULTI_CONTROLCEN_FIRE      , 16)  \
  40.         VALUE(MULTI_CREATE_POWERUP       , 19)  \
  41.         VALUE(MULTI_DECLOAK              , 2)   \
  42.         VALUE(MULTI_ROBOT_POSITION       , 5 + quaternionpos::packed_size::value)       \
  43.         VALUE(MULTI_PLAYER_DERES         , DXX_MP_SIZE_PLAYER_RELATED)  \
  44.         VALUE(MULTI_DOOR_OPEN            , DXX_MP_SIZE_DOOR_OPEN)       \
  45.         VALUE(MULTI_ROBOT_EXPLODE        , 7)   \
  46.         VALUE(MULTI_ROBOT_RELEASE        , 5)   \
  47.         VALUE(MULTI_ROBOT_FIRE           , 18)  \
  48.         VALUE(MULTI_SCORE                , 6)   \
  49.         VALUE(MULTI_CREATE_ROBOT         , 6)   \
  50.         VALUE(MULTI_TRIGGER              , 3)   \
  51.         VALUE(MULTI_BOSS_TELEPORT        , 5)   \
  52.         VALUE(MULTI_BOSS_CLOAK           , 3)   \
  53.         VALUE(MULTI_BOSS_START_GATE      , 3)   \
  54.         VALUE(MULTI_BOSS_STOP_GATE       , 3)   \
  55.         VALUE(MULTI_BOSS_CREATE_ROBOT    , 8)   \
  56.         VALUE(MULTI_CREATE_ROBOT_POWERUPS, 27)  \
  57.         VALUE(MULTI_HOSTAGE_DOOR         , 7)   \
  58.         VALUE(MULTI_SAVE_GAME            , 2+24)        /* (ubyte slot, uint id, char name[20]) */      \
  59.         VALUE(MULTI_RESTORE_GAME         , 2+4) /* (ubyte slot, uint id) */     \
  60.         VALUE(MULTI_HEARTBEAT            , 5)   \
  61.         VALUE(MULTI_KILLGOALS            , 1 + MAX_PLAYERS)     \
  62.         VALUE(MULTI_DO_BOUNTY            , 2)   \
  63.         VALUE(MULTI_TYPING_STATE         , 3)   \
  64.         VALUE(MULTI_GMODE_UPDATE         , 3)   \
  65.         VALUE(MULTI_KILL_HOST            , 7)   \
  66.         VALUE(MULTI_KILL_CLIENT          , 5)   \
  67.         VALUE(MULTI_RANK                 , 3)   \
  68.         VALUE(MULTI_DROP_WEAPON          , 10)  \
  69.         VALUE(MULTI_PLAYER_INV           , DXX_MP_SIZE_PLAYER_INVENTORY)        \
  70.         D2X_MP_COMMANDS(VALUE)  \
  71.  
  72. #if defined(DXX_BUILD_DESCENT_I)
  73. #define DXX_MP_SIZE_ENDLEVEL_START      3
  74. #define DXX_MP_SIZE_PLAYER_RELATED      58
  75. #define DXX_MP_SIZE_PLAYER_INVENTORY    15
  76. #define DXX_MP_SIZE_BEGIN_SYNC  37
  77. #define DXX_MP_SIZE_DOOR_OPEN   4
  78. #define D2X_MP_COMMANDS(VALUE)
  79. #elif defined(DXX_BUILD_DESCENT_II)
  80. #define DXX_MP_SIZE_ENDLEVEL_START      2
  81. #define DXX_MP_SIZE_PLAYER_RELATED      (97+10)
  82. #define DXX_MP_SIZE_PLAYER_INVENTORY    21
  83. #define DXX_MP_SIZE_BEGIN_SYNC  41
  84. #define DXX_MP_SIZE_DOOR_OPEN   5
  85. #define D2X_MP_COMMANDS(VALUE)  \
  86.         VALUE(MULTI_MARKER               , 55)  \
  87.         VALUE(MULTI_GUIDED               , 26)  \
  88.         VALUE(MULTI_STOLEN_ITEMS         , 1 + std::tuple_size<decltype(d_thief_unique_state::Stolen_items)>::value)    \
  89.         VALUE(MULTI_WALL_STATUS          , 6)   /* send to new players */       \
  90.         VALUE(MULTI_SEISMIC              , 5)   \
  91.         VALUE(MULTI_LIGHT                , 16)  \
  92.         VALUE(MULTI_START_TRIGGER        , 2)   \
  93.         VALUE(MULTI_FLAGS                , 6)   \
  94.         VALUE(MULTI_DROP_BLOB            , 2)   \
  95.         VALUE(MULTI_SOUND_FUNCTION       , 4)   \
  96.         VALUE(MULTI_CAPTURE_BONUS        , 2)   \
  97.         VALUE(MULTI_GOT_FLAG             , 2)   \
  98.         VALUE(MULTI_DROP_FLAG            , 8)   \
  99.         VALUE(MULTI_FINISH_GAME          , 2)   \
  100.         VALUE(MULTI_ORB_BONUS            , 3)   \
  101.         VALUE(MULTI_GOT_ORB              , 2)   \
  102.         VALUE(MULTI_EFFECT_BLOWUP        , 17)  \
  103.         VALUE(MULTI_VULWPN_AMMO_ADJ      , 6)   \
  104.         VALUE(MULTI_UPDATE_BUDDY_STATE, 7)      \
  105.  
  106. #endif
  107.  
  108. #include "dxxsconf.h"
  109.  
  110. enum multiplayer_command_t : uint8_t
  111. {
  112.         for_each_multiplayer_command(define_multiplayer_command)
  113. };
  114.  
  115. template <multiplayer_command_t>
  116. struct command_length;
  117. #define define_command_length(NAME,SIZE)        \
  118.         template <>     \
  119.         struct command_length<NAME> : public std::integral_constant<unsigned, SIZE> {};
  120. for_each_multiplayer_command(define_command_length);
  121.  
  122. template <multiplayer_command_t C>
  123. struct multi_command : public std::array<uint8_t, command_length<C>::value>
  124. {
  125. };
  126.  
  127. void _multi_send_data(const uint8_t *buf, unsigned len, int priority);
  128.  
  129. template <multiplayer_command_t C>
  130. static inline void multi_send_data(uint8_t *const buf, const unsigned len, const int priority)
  131. {
  132.         buf[0] = C;
  133.         constexpr unsigned expected = command_length<C>::value;
  134. #ifdef DXX_CONSTANT_TRUE
  135.         if (DXX_CONSTANT_TRUE(len != expected))
  136.                 DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_multi_send_data, "wrong packet size");
  137. #endif
  138.         if (len != expected)
  139.         {
  140.                 Error("multi_send_data: Packet type %i length: %i, expected: %i\n", C, len, expected);
  141.         }
  142.         _multi_send_data(buf, len, priority);
  143. }
  144.  
  145. template <multiplayer_command_t C>
  146. static inline void multi_send_data(multi_command<C> &buf, const int priority)
  147. {
  148.         buf[0] = C;
  149.         _multi_send_data(buf.data(), buf.size(), priority);
  150. }
  151.  
  152. template <typename T>
  153. static inline void multi_serialize_read(const uint8_t *const buf, T &t)
  154. {
  155.         serial::reader::bytebuffer_t b(buf);
  156.         serial::process_buffer(b, t);
  157. }
  158.  
  159. template <typename T>
  160. static inline void multi_serialize_write(int priority, const T &t)
  161. {
  162.         constexpr size_t maximum_size = serial::message_type<T>::maximum_size;
  163.         uint8_t buf[maximum_size];
  164.         serial::writer::bytebuffer_t b(buf);
  165.         serial::process_buffer(b, t);
  166.         _multi_send_data(buf, maximum_size, priority);
  167. }
  168.  
  169. template <multiplayer_command_t C>
  170. using multiplayer_command = serial::pad<1, static_cast<uint8_t>(C)>;
  171.  
  172. #endif
  173.