mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-17 20:00:25 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28fdc704c6 |
No files matched your search
@@ -57,15 +57,17 @@ The native builds' messages differ from the Xbox game's (longer arrays, the
|
||||
game settings record in fragments), so they search for games with their own
|
||||
protocol version and never see the Xbox game's, or it theirs. */
|
||||
|
||||
#define HALO_PORT_NETWORK_GAME_MESSAGE_VERSION 2
|
||||
/* 3: game updates carry the VR players' blocks (game/players.h) */
|
||||
#define HALO_PORT_NETWORK_GAME_MESSAGE_VERSION 3
|
||||
|
||||
/* a message header's 12-bit length allows messages of up to 0xFFF bytes,
|
||||
header included; the per-tick update of 128 players is 3,857 */
|
||||
#define HALO_PORT_MAXIMUM_NETWORK_MESSAGE_SIZE 0x1000
|
||||
|
||||
/* the packet codec's limit on a decoded or encoded packet; the per-tick
|
||||
update of 128 players decodes to 0x1010 bytes */
|
||||
#define HALO_PORT_NETWORK_PACKET_SIZE 0x1100
|
||||
update of 128 players decodes to 0x12D4 bytes, 16 VR players' blocks
|
||||
(game/players.h) included */
|
||||
#define HALO_PORT_NETWORK_PACKET_SIZE 0x1400
|
||||
|
||||
/* the game settings record (HALO_PORT_NETWORK_GAME_SIZE, 13,092 bytes at 128
|
||||
machines and players) does not fit one message; it is sent in pieces of
|
||||
|
||||
@@ -587,22 +587,23 @@ long player_aim_projectile(
|
||||
real autoaim_level;
|
||||
|
||||
director_camera_deterministic(player->unit_index, &camera_position, &camera_direction);
|
||||
#ifdef HALO_ANDROID
|
||||
if (halo_vr_active() && player->local_player_index==0)
|
||||
#ifdef HALO_LINUX
|
||||
if (player_action_vr_get(player_index))
|
||||
{
|
||||
struct player_action_vr const *vr_action= player_action_vr_get(player_index);
|
||||
struct unit_datum *vr_unit= unit_get(player->unit_index);
|
||||
float vr_eyes[3], vr_heading[3];
|
||||
|
||||
if (vr_unit->object.parent_object_index!=NONE &&
|
||||
halo_vr_body_frame(player->local_player_index, vr_eyes, vr_heading))
|
||||
TEST_FLAG(vr_action->flags, _player_action_vr_eyes_bit))
|
||||
{
|
||||
/* VR, seated: as the game aims a vehicle's gun, at what lies
|
||||
along the player's aim, from the eyes (vr.c draws the crosshair
|
||||
there); its barrel alone points elsewhere (a Banshee's nose
|
||||
rises as it hovers, a tank's turret lags) */
|
||||
camera_position.x= vr_eyes[0];
|
||||
camera_position.y= vr_eyes[1];
|
||||
camera_position.z= vr_eyes[2];
|
||||
unit_get_camera_position(player->unit_index, &camera_position);
|
||||
camera_position.x+= player_action_vr_offset(vr_action->eyes[0]);
|
||||
camera_position.y+= player_action_vr_offset(vr_action->eyes[1]);
|
||||
camera_position.z+= player_action_vr_offset(vr_action->eyes[2]);
|
||||
camera_direction= vr_unit->unit.aiming_vector;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -389,6 +389,81 @@ static void player_control_vr_spawn_vehicle(
|
||||
platform_log("VR: spawning %s: %s", name, object_new(&data) == NONE ? "failed" : "done");
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef HALO_ANDROID
|
||||
/* VR: what the headset adds to the local player's input this tick (game/
|
||||
players.h), in the whole numbers every machine in a game works with; the
|
||||
simulation reads it from the input, never from the headset */
|
||||
static void player_control_vr_quantize_direction(
|
||||
const float direction[3],
|
||||
short quantized[3])
|
||||
{
|
||||
short axis;
|
||||
|
||||
for (axis = 0; axis < 3; axis++)
|
||||
quantized[axis] = player_action_vr_quantize_direction(direction[axis]);
|
||||
}
|
||||
|
||||
static void player_control_vr_quantize_offset(
|
||||
const float point[3],
|
||||
real_point3d const *camera,
|
||||
short quantized[3])
|
||||
{
|
||||
quantized[0] = player_action_vr_quantize_offset(point[0] - camera->x);
|
||||
quantized[1] = player_action_vr_quantize_offset(point[1] - camera->y);
|
||||
quantized[2] = player_action_vr_quantize_offset(point[2] - camera->z);
|
||||
}
|
||||
|
||||
static void player_control_vr_sample(
|
||||
short local_player_index,
|
||||
struct player_datum *player,
|
||||
struct player_action_vr *vr)
|
||||
{
|
||||
float vector[3], point[3], strength;
|
||||
real_point3d camera;
|
||||
boolean has_unit = player->unit_index != NONE;
|
||||
|
||||
if (!halo_vr_active() || local_player_index != 0)
|
||||
return;
|
||||
if (has_unit)
|
||||
unit_get_camera_position(player->unit_index, &camera);
|
||||
if (halo_vr_aim_vector(local_player_index, vector))
|
||||
{
|
||||
vr->flags |= FLAG(_player_action_vr_aim_bit);
|
||||
player_control_vr_quantize_direction(vector, vr->aim);
|
||||
}
|
||||
if (halo_vr_look_vector(local_player_index, vector))
|
||||
{
|
||||
vr->flags |= FLAG(_player_action_vr_look_bit);
|
||||
player_control_vr_quantize_direction(vector, vr->look);
|
||||
}
|
||||
if (has_unit && halo_vr_weapon_origin(local_player_index, point))
|
||||
{
|
||||
vr->flags |= FLAG(_player_action_vr_muzzle_bit);
|
||||
player_control_vr_quantize_offset(point, &camera, vr->muzzle);
|
||||
}
|
||||
if (has_unit && halo_vr_body_frame(local_player_index, point, vector))
|
||||
{
|
||||
vr->flags |= FLAG(_player_action_vr_eyes_bit);
|
||||
player_control_vr_quantize_offset(point, &camera, vr->eyes);
|
||||
}
|
||||
if (halo_vr_grenade_held(local_player_index))
|
||||
vr->flags |= FLAG(_player_action_vr_grenade_held_bit);
|
||||
if (has_unit && halo_vr_grenade_throw(local_player_index, point, vector, &strength))
|
||||
{
|
||||
vr->flags |= FLAG(_player_action_vr_grenade_thrown_bit);
|
||||
player_control_vr_quantize_offset(point, &camera, vr->grenade_offset);
|
||||
player_control_vr_quantize_direction(vector, vr->grenade_direction);
|
||||
vr->grenade_strength = player_action_vr_quantize_direction(strength);
|
||||
}
|
||||
strength = halo_vr_melee_strength();
|
||||
if (strength > 0.f)
|
||||
{
|
||||
vr->flags |= FLAG(_player_action_vr_melee_bit);
|
||||
vr->melee_strength = player_action_vr_quantize_direction(strength);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* ---------- public code */
|
||||
|
||||
@@ -879,6 +954,20 @@ static void handle_one_player_input(
|
||||
0x36A,
|
||||
action.desired_facing.yaw);
|
||||
update_client_queue(&action);
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* and what the headset adds to it (game/players.h), for every
|
||||
local player so their slots stay in step */
|
||||
struct player_action_vr vr;
|
||||
|
||||
csmemset(&vr, 0, sizeof(vr));
|
||||
#ifdef HALO_ANDROID
|
||||
player_control_vr_sample(local_player_index,
|
||||
player_get(local_player_get_player_index(local_player_index)), &vr);
|
||||
#endif
|
||||
update_client_queue_vr(&vr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -257,6 +257,16 @@ static struct update *update_client_get_update(
|
||||
|
||||
static struct update_server_globals update_server_globals = { 0 };
|
||||
static struct update_client_globals update_client_globals = { 0 };
|
||||
#ifdef HALO_LINUX
|
||||
/* VR (players.h): each step's VR blocks, beside its actions. A grenade the
|
||||
hand threw between two ticks stays thrown until a tick has run. */
|
||||
static struct player_action_vr update_client_pending_vr[MAXIMUM_LOCAL_PLAYERS];
|
||||
static struct player_action_vr update_client_saved_vr[MAXIMUM_LOCAL_PLAYERS];
|
||||
static struct player_action_vr update_server_queue_vr[MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
static struct player_action_vr update_server_updates_vr[MAXIMUM_SERVER_UPDATES][MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
static struct player_action_vr update_client_updates_vr[MAXIMUM_CLIENT_UPDATES][MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
static struct player_action_vr update_client_current_vr[MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
#endif
|
||||
|
||||
/* ---------- public code */
|
||||
|
||||
@@ -376,6 +386,13 @@ void update_server_next_update(
|
||||
update->update.action_count += 1;
|
||||
}
|
||||
update_client_handle_server_update(&update->update, update_number);
|
||||
#ifdef HALO_LINUX
|
||||
csmemcpy(
|
||||
update_server_updates_vr[update - update_server_globals.updates],
|
||||
update_server_queue_vr,
|
||||
sizeof(update_server_queue_vr));
|
||||
update_client_handle_server_vr(update_server_updates_vr[update - update_server_globals.updates], update_number);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -516,6 +533,7 @@ static unsigned long update_client_pending_control_flags[MAXIMUM_LOCAL_PLAYERS];
|
||||
static real update_client_pending_primary_triggers[MAXIMUM_LOCAL_PLAYERS];
|
||||
static long update_client_pending_game_time = NONE;
|
||||
|
||||
|
||||
#endif
|
||||
void update_client_queue(
|
||||
struct player_action const *action)
|
||||
@@ -543,6 +561,35 @@ void update_client_queue(
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HALO_LINUX
|
||||
/* the VR block of the action just queued (update_client_queue) */
|
||||
void update_client_queue_vr(
|
||||
struct player_action_vr const *vr)
|
||||
{
|
||||
long local_player = update_client_globals.current_local_player - 1;
|
||||
|
||||
if (local_player >= 0 && local_player < MAXIMUM_LOCAL_PLAYERS)
|
||||
{
|
||||
struct player_action_vr *pending = &update_client_pending_vr[local_player];
|
||||
struct player_action_vr thrown = *pending;
|
||||
short held_thrown = pending->flags & FLAG(_player_action_vr_grenade_thrown_bit);
|
||||
|
||||
*pending = *vr;
|
||||
if (held_thrown && !(vr->flags & FLAG(_player_action_vr_grenade_thrown_bit)))
|
||||
{
|
||||
/* thrown on an earlier frame of this tick */
|
||||
pending->flags |= held_thrown;
|
||||
csmemcpy(pending->grenade_offset, thrown.grenade_offset, sizeof(pending->grenade_offset));
|
||||
csmemcpy(pending->grenade_direction, thrown.grenade_direction, sizeof(pending->grenade_direction));
|
||||
pending->grenade_strength = thrown.grenade_strength;
|
||||
}
|
||||
update_client_saved_vr[local_player] = *pending;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
void update_client_queue_push(
|
||||
void)
|
||||
{
|
||||
@@ -552,6 +599,7 @@ void update_client_queue_push(
|
||||
game_time_get_paused())
|
||||
{
|
||||
update_client_pending_game_time = game_time_get();
|
||||
csmemset(update_client_pending_vr, 0, sizeof(update_client_pending_vr));
|
||||
csmemset(
|
||||
update_client_pending_control_flags,
|
||||
0,
|
||||
@@ -567,6 +615,9 @@ void update_client_queue_push(
|
||||
&update_client_globals.saved_action_collection,
|
||||
0,
|
||||
sizeof(update_client_globals.saved_action_collection));
|
||||
#ifdef HALO_LINUX
|
||||
csmemset(update_client_saved_vr, 0, sizeof(update_client_saved_vr));
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -644,6 +695,12 @@ boolean update_client_dequeue(
|
||||
0x1E8,
|
||||
(NONE == actions[queue_index].desired_zoom_level) || (actions[queue_index].desired_zoom_level>=0));
|
||||
}
|
||||
#ifdef HALO_LINUX
|
||||
csmemcpy(
|
||||
update_client_current_vr,
|
||||
update_client_updates_vr[update - update_client_globals.updates],
|
||||
sizeof(update_client_current_vr));
|
||||
#endif
|
||||
update_client_globals.next_update_number_to_dequeue += 1;
|
||||
|
||||
return TRUE;
|
||||
@@ -691,6 +748,14 @@ void update_client_local_ticks(
|
||||
game_connection()==_game_connection_local);
|
||||
update_client_build_client_update(&action_collection);
|
||||
update_server_handle_client_update(machine_index, action_collection.actions);
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
struct player_action_vr vr[MAXIMUM_LOCAL_PLAYERS];
|
||||
|
||||
update_client_build_client_vr(vr);
|
||||
update_server_handle_client_vr(machine_index, vr);
|
||||
}
|
||||
#endif
|
||||
while (ticks-->0)
|
||||
{
|
||||
update_server_next_update();
|
||||
@@ -792,6 +857,118 @@ void update_client_handle_server_update(
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HALO_LINUX
|
||||
void update_client_build_client_vr(
|
||||
struct player_action_vr *vr)
|
||||
{
|
||||
csmemcpy(vr, update_client_saved_vr, sizeof(update_client_saved_vr));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* as update_server_handle_client_update: the machine's players, in order */
|
||||
void update_server_handle_client_vr(
|
||||
long machine_index,
|
||||
struct player_action_vr const *vr)
|
||||
{
|
||||
long *player_list = machine_get_player_list(machine_index);
|
||||
long action_index = 0;
|
||||
long player_index;
|
||||
|
||||
for (player_index = 0; player_index<MAXIMUM_LOCAL_PLAYERS; ++player_index)
|
||||
{
|
||||
if (player_list[player_index]!=NONE)
|
||||
{
|
||||
long absolute_index = DATUM_INDEX_TO_ABSOLUTE_INDEX(player_list[player_index]);
|
||||
|
||||
if (absolute_index<MAXIMUM_NUMBER_OF_PLAYERS)
|
||||
update_server_queue_vr[absolute_index] = vr[action_index];
|
||||
action_index++;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* the VR blocks of an update the host built (update_server_build_server_update) */
|
||||
struct player_action_vr const *update_server_get_update_vr(
|
||||
long update_number)
|
||||
{
|
||||
struct update *update = update_server_get_update(update_number);
|
||||
|
||||
return update ? update_server_updates_vr[update - update_server_globals.updates] : NULL;
|
||||
}
|
||||
|
||||
/* as update_client_handle_server_update, for its VR blocks */
|
||||
void update_client_handle_server_vr(
|
||||
struct player_action_vr const *vr,
|
||||
long update_number)
|
||||
{
|
||||
struct update *client_update = update_client_get_update(update_number);
|
||||
|
||||
if (client_update)
|
||||
{
|
||||
csmemcpy(
|
||||
update_client_updates_vr[client_update - update_client_globals.updates],
|
||||
vr,
|
||||
sizeof(update_client_updates_vr[0]));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct player_action_vr const *player_action_vr_get(
|
||||
long player_index)
|
||||
{
|
||||
long absolute_index = DATUM_INDEX_TO_ABSOLUTE_INDEX(player_index);
|
||||
|
||||
if (player_index==NONE || absolute_index<0 || absolute_index>=MAXIMUM_NUMBER_OF_PLAYERS ||
|
||||
!update_client_current_vr[absolute_index].flags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &update_client_current_vr[absolute_index];
|
||||
}
|
||||
|
||||
short player_action_vr_quantize_direction(
|
||||
real value)
|
||||
{
|
||||
return (short)PIN((long)(value * 32767.0f + (value < 0.0f ? -0.5f : 0.5f)), -32767, 32767);
|
||||
}
|
||||
|
||||
real player_action_vr_direction(
|
||||
short value)
|
||||
{
|
||||
return value * (1.0f / 32767.0f);
|
||||
}
|
||||
|
||||
short player_action_vr_quantize_offset(
|
||||
real value)
|
||||
{
|
||||
return (short)PIN((long)(value * 4096.0f + (value < 0.0f ? -0.5f : 0.5f)), -32767, 32767);
|
||||
}
|
||||
|
||||
real player_action_vr_offset(
|
||||
short value)
|
||||
{
|
||||
return value * (1.0f / 4096.0f);
|
||||
}
|
||||
|
||||
/* a direction, made whole again (every machine rounds the same) */
|
||||
void player_action_vr_get_direction(
|
||||
short const quantized[3],
|
||||
real_vector3d *direction)
|
||||
{
|
||||
direction->i = player_action_vr_direction(quantized[0]);
|
||||
direction->j = player_action_vr_direction(quantized[1]);
|
||||
direction->k = player_action_vr_direction(quantized[2]);
|
||||
if (normalize3d(direction) == 0.0f)
|
||||
*direction = *global_forward3d;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
void update_queues_reset_and_fill_with_lies(
|
||||
void)
|
||||
{
|
||||
@@ -811,6 +988,13 @@ void update_queues_reset_and_fill_with_lies(
|
||||
&update_client_globals.saved_action_collection,
|
||||
0,
|
||||
sizeof(update_client_globals.saved_action_collection));
|
||||
#ifdef HALO_LINUX
|
||||
csmemset(update_client_updates_vr, 0, sizeof(update_client_updates_vr));
|
||||
csmemset(update_client_current_vr, 0, sizeof(update_client_current_vr));
|
||||
csmemset(update_client_saved_vr, 0, sizeof(update_client_saved_vr));
|
||||
csmemset(update_server_queue_vr, 0, sizeof(update_server_queue_vr));
|
||||
csmemset(update_server_updates_vr, 0, sizeof(update_server_updates_vr));
|
||||
#endif
|
||||
update_client_globals.latest_update_number_received = NONE;
|
||||
update_client_globals.next_update_number_to_dequeue = 0;
|
||||
game_time = game_time_get();
|
||||
|
||||
@@ -58,6 +58,25 @@ void update_client_handle_server_update(
|
||||
struct server_update *update,
|
||||
long update_number);
|
||||
|
||||
#ifdef HALO_LINUX
|
||||
/* VR (players.h, struct player_action_vr): each step of an action's way has
|
||||
its VR block's beside it */
|
||||
struct player_action_vr;
|
||||
|
||||
void update_client_queue_vr(
|
||||
struct player_action_vr const *vr);
|
||||
void update_client_build_client_vr(
|
||||
struct player_action_vr *vr);
|
||||
void update_server_handle_client_vr(
|
||||
long machine_index,
|
||||
struct player_action_vr const *vr);
|
||||
struct player_action_vr const *update_server_get_update_vr(
|
||||
long update_number);
|
||||
void update_client_handle_server_vr(
|
||||
struct player_action_vr const *vr,
|
||||
long update_number);
|
||||
#endif
|
||||
|
||||
void update_queues_reset_and_fill_with_lies(
|
||||
void);
|
||||
long player_new_queue(
|
||||
|
||||
+13
-20
@@ -3486,31 +3486,24 @@ void players_update_before_game(
|
||||
&action->desired_facing);
|
||||
control_data.facing_vector =
|
||||
control_data.looking_vector = control_data.aiming_vector;
|
||||
#ifdef HALO_ANDROID
|
||||
if (unit->object.parent_object_index == NONE)
|
||||
#ifdef HALO_LINUX
|
||||
if (unit->object.parent_object_index == NONE && player_action_vr_get(iterator.datum_index))
|
||||
{
|
||||
/* VR: on foot, the weapon aims where the right controller
|
||||
points, while the body and the view keep facing where the
|
||||
head looks (port/linux/src/vr.c) */
|
||||
real vr_aim[3];
|
||||
real vr_look[3];
|
||||
head looks (port/linux/src/vr.c; the player's input carries
|
||||
both, game/players.h); and it looks where the head looks,
|
||||
whether or not the game lets the player turn now (scripts
|
||||
test it: unit_can_see_point) */
|
||||
struct player_action_vr const *vr_action = player_action_vr_get(iterator.datum_index);
|
||||
|
||||
/* and it looks where the head looks, whether or not the
|
||||
game lets the player turn now (scripts test it:
|
||||
unit_can_see_point) */
|
||||
if (halo_vr_look_vector(player->local_player_index, vr_look))
|
||||
{
|
||||
control_data.looking_vector.i = vr_look[0];
|
||||
control_data.looking_vector.j = vr_look[1];
|
||||
control_data.looking_vector.k = vr_look[2];
|
||||
}
|
||||
if (halo_vr_aim_vector(player->local_player_index, vr_aim))
|
||||
{
|
||||
control_data.aiming_vector.i = vr_aim[0];
|
||||
control_data.aiming_vector.j = vr_aim[1];
|
||||
control_data.aiming_vector.k = vr_aim[2];
|
||||
}
|
||||
if (TEST_FLAG(vr_action->flags, _player_action_vr_look_bit))
|
||||
player_action_vr_get_direction(vr_action->look, &control_data.looking_vector);
|
||||
if (TEST_FLAG(vr_action->flags, _player_action_vr_aim_bit))
|
||||
player_action_vr_get_direction(vr_action->aim, &control_data.aiming_vector);
|
||||
}
|
||||
#endif
|
||||
#ifdef HALO_ANDROID
|
||||
{
|
||||
real unit_look[3];
|
||||
|
||||
|
||||
@@ -62,6 +62,80 @@ struct player_action
|
||||
|
||||
typedef char player_action_size_assert[
|
||||
sizeof(struct player_action) == 0x20 ? 1 : -1];
|
||||
|
||||
#ifdef HALO_LINUX
|
||||
/* VR (port/linux/src/vr.c): what a player's headset adds to his input each
|
||||
tick, in whole numbers so that every machine in a game, the host too, works
|
||||
with exactly the same (player_queues_new.c carries it beside the action, and
|
||||
the network messages as a list of the players who have one). Directions are
|
||||
unit vectors in 1/32767ths, offsets from the unit's camera in 1/4096 world
|
||||
units, strengths 0..1 in 1/32767ths. */
|
||||
enum
|
||||
{
|
||||
_player_action_vr_aim_bit = 0, /* the weapon aims along aim */
|
||||
_player_action_vr_look_bit, /* the head looks along look */
|
||||
_player_action_vr_muzzle_bit, /* shots start at muzzle */
|
||||
_player_action_vr_eyes_bit, /* seated, a gun aims from the eyes */
|
||||
_player_action_vr_grenade_held_bit, /* the left trigger holds the grenade */
|
||||
_player_action_vr_grenade_thrown_bit, /* the hand threw it this tick */
|
||||
_player_action_vr_melee_bit, /* a swing's melee strength */
|
||||
};
|
||||
|
||||
struct player_action_vr
|
||||
{
|
||||
short flags;
|
||||
short aim[3];
|
||||
short look[3];
|
||||
short muzzle[3];
|
||||
short eyes[3];
|
||||
short grenade_offset[3];
|
||||
short grenade_direction[3];
|
||||
short grenade_strength;
|
||||
short melee_strength;
|
||||
};
|
||||
|
||||
typedef char player_action_vr_size_assert[
|
||||
sizeof(struct player_action_vr) == 42 ? 1 : -1];
|
||||
|
||||
/* on the wire, after a game update's actions: the players who have a VR
|
||||
block (their index in the update, or the machine's local player), up to
|
||||
this many in a host's update */
|
||||
enum
|
||||
{
|
||||
MAXIMUM_VR_PLAYERS_PER_UPDATE = 16,
|
||||
};
|
||||
|
||||
struct player_action_vr_entry
|
||||
{
|
||||
short player;
|
||||
struct player_action_vr vr;
|
||||
};
|
||||
|
||||
typedef char player_action_vr_entry_size_assert[
|
||||
sizeof(struct player_action_vr_entry) == 44 ? 1 : -1];
|
||||
|
||||
#define PLAYER_ACTION_VR_TAIL(maximum) \
|
||||
short vr_count; \
|
||||
struct player_action_vr_entry vr_entries[maximum]; \
|
||||
short vr_pad;
|
||||
|
||||
/* the VR block of a player's input this tick (players_update_before_game),
|
||||
or NULL if his input has none */
|
||||
struct player_action_vr const *player_action_vr_get(
|
||||
long player_index);
|
||||
/* the conversions both ways */
|
||||
short player_action_vr_quantize_direction(
|
||||
real value);
|
||||
real player_action_vr_direction(
|
||||
short value);
|
||||
short player_action_vr_quantize_offset(
|
||||
real value);
|
||||
real player_action_vr_offset(
|
||||
short value);
|
||||
void player_action_vr_get_direction(
|
||||
short const quantized[3],
|
||||
real_vector3d *direction);
|
||||
#endif
|
||||
typedef char player_action_desired_facing_yaw_offset_assert[
|
||||
offsetof(struct player_action, desired_facing.yaw) == 0x4 ? 1 : -1];
|
||||
typedef char player_action_desired_facing_pitch_offset_assert[
|
||||
|
||||
+11
-9
@@ -2254,19 +2254,21 @@ static void trigger_create_projectiles(
|
||||
&up,
|
||||
trigger_definition->first_person_weapon_offset.z,
|
||||
&origin);
|
||||
#ifdef HALO_ANDROID
|
||||
#ifdef HALO_LINUX
|
||||
if (unit->object.parent_object_index == NONE && unit->unit.gunner_object_index == NONE)
|
||||
{
|
||||
/* VR: from the muzzle of the weapon in the right hand; the
|
||||
projectile is kept inside the level from the camera below,
|
||||
so a hand through a wall does not fire through it */
|
||||
real vr_origin[3];
|
||||
/* VR: from the muzzle of the weapon in the right hand (the
|
||||
player's input carries it, game/players.h); the projectile is
|
||||
kept inside the level from the camera below, so a hand
|
||||
through a wall does not fire through it */
|
||||
struct player_action_vr const *vr_action = player_action_vr_get(player_index);
|
||||
|
||||
if (halo_vr_weapon_origin(player_get(player_index)->local_player_index, vr_origin))
|
||||
if (vr_action && TEST_FLAG(vr_action->flags, _player_action_vr_muzzle_bit))
|
||||
{
|
||||
origin.x = vr_origin[0];
|
||||
origin.y = vr_origin[1];
|
||||
origin.z = vr_origin[2];
|
||||
unit_get_camera_position(owner_object_index, &origin);
|
||||
origin.x += player_action_vr_offset(vr_action->muzzle[0]);
|
||||
origin.y += player_action_vr_offset(vr_action->muzzle[1]);
|
||||
origin.z += player_action_vr_offset(vr_action->muzzle[2]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -619,6 +619,9 @@ struct message_server_game_update
|
||||
byte __unknown0C[2];
|
||||
short local_player_count;
|
||||
struct player_action player_actions[MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
#ifdef HALO_LINUX
|
||||
PLAYER_ACTION_VR_TAIL(MAXIMUM_VR_PLAYERS_PER_UPDATE)
|
||||
#endif
|
||||
};
|
||||
|
||||
struct server_update
|
||||
@@ -720,8 +723,10 @@ typedef char player_profile_size_assert[
|
||||
#ifdef HALO_LINUX
|
||||
/* the update and settings layouts follow the session limits
|
||||
(port/linux/include/halo_port_limits.h) */
|
||||
/* (and the VR players' blocks, game/players.h) */
|
||||
typedef char message_server_game_update_size_assert[
|
||||
sizeof(struct message_server_game_update) == 0x10 + MAXIMUM_NUMBER_OF_PLAYERS * 0x20 ? 1 : -1];
|
||||
sizeof(struct message_server_game_update) ==
|
||||
0x10 + MAXIMUM_NUMBER_OF_PLAYERS * 0x20 + 2 + MAXIMUM_VR_PLAYERS_PER_UPDATE * 44 + 2 ? 1 : -1];
|
||||
typedef char server_update_size_assert[
|
||||
sizeof(struct server_update) == 4 + MAXIMUM_NUMBER_OF_PLAYERS * 0x20 ? 1 : -1];
|
||||
#else
|
||||
@@ -1768,6 +1773,23 @@ boolean network_game_client_handle_game_update(
|
||||
update.local_player_count * sizeof(struct player_action));
|
||||
|
||||
update_client_handle_server_update(&update, message_packet->update_number);
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* the VR players' blocks (game/players.h) */
|
||||
static struct player_action_vr vr[MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
short entry;
|
||||
|
||||
csmemset(vr, 0, sizeof(vr));
|
||||
for (entry = 0; entry < message_packet->vr_count && entry < MAXIMUM_VR_PLAYERS_PER_UPDATE; entry++)
|
||||
{
|
||||
short player = message_packet->vr_entries[entry].player;
|
||||
|
||||
if (player >= 0 && player < MAXIMUM_NUMBER_OF_PLAYERS)
|
||||
vr[player] = message_packet->vr_entries[entry].vr;
|
||||
}
|
||||
update_client_handle_server_vr(vr, message_packet->update_number);
|
||||
}
|
||||
#endif
|
||||
|
||||
client->next_update_number++;
|
||||
client->last_update_time = system_milliseconds();
|
||||
|
||||
@@ -392,6 +392,9 @@ struct message_server_game_update
|
||||
byte padding0C[2];
|
||||
short local_player_count;
|
||||
struct player_action player_actions[MAXIMUM_NUMBER_OF_PLAYERS];
|
||||
#ifdef HALO_LINUX
|
||||
PLAYER_ACTION_VR_TAIL(MAXIMUM_VR_PLAYERS_PER_UPDATE)
|
||||
#endif
|
||||
};
|
||||
|
||||
struct message_server_remove_player_ingame
|
||||
|
||||
@@ -175,6 +175,9 @@ struct client_game_update_message
|
||||
short __unknown4;
|
||||
short local_player_count;
|
||||
byte update[0x80];
|
||||
#ifdef HALO_LINUX
|
||||
PLAYER_ACTION_VR_TAIL(MAXIMUM_LOCAL_PLAYERS)
|
||||
#endif
|
||||
};
|
||||
|
||||
struct network_machine
|
||||
@@ -606,6 +609,26 @@ boolean network_game_client_end_frame(
|
||||
|
||||
csmemcpy(message.update, &update, sizeof(update));
|
||||
message.local_player_count = local_player_count();
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* the local players' VR blocks (game/players.h) */
|
||||
struct player_action_vr vr[MAXIMUM_LOCAL_PLAYERS];
|
||||
short slot;
|
||||
|
||||
update_client_build_client_vr(vr);
|
||||
message.vr_count = 0;
|
||||
message.vr_pad = 0;
|
||||
for (slot = 0; slot < MAXIMUM_LOCAL_PLAYERS; slot++)
|
||||
{
|
||||
if (vr[slot].flags)
|
||||
{
|
||||
message.vr_entries[message.vr_count].player = slot;
|
||||
message.vr_entries[message.vr_count].vr = vr[slot];
|
||||
message.vr_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
encoded_message = create_network_game_message(
|
||||
_message_client_game_update,
|
||||
&message,
|
||||
|
||||
@@ -239,7 +239,12 @@ struct network_game_message_packet_definitions
|
||||
struct data_packet_definition client_graceful_game_exit_pregame;
|
||||
struct data_packet_field client_map_is_precached_pregame_fields[2];
|
||||
struct data_packet_definition client_map_is_precached_pregame;
|
||||
#ifdef HALO_LINUX
|
||||
/* ...and the VR players' blocks (game/players.h) */
|
||||
struct data_packet_field server_game_update_fields[12];
|
||||
#else
|
||||
struct data_packet_field server_game_update_fields[8];
|
||||
#endif
|
||||
struct data_packet_definition server_game_update;
|
||||
struct data_packet_field server_add_player_ingame_fields[4];
|
||||
struct data_packet_definition server_add_player_ingame;
|
||||
@@ -249,7 +254,11 @@ struct network_game_message_packet_definitions
|
||||
struct data_packet_definition server_game_over;
|
||||
struct data_packet_field client_loaded_fields[2];
|
||||
struct data_packet_definition client_loaded;
|
||||
#ifdef HALO_LINUX
|
||||
struct data_packet_field client_game_update_fields[12];
|
||||
#else
|
||||
struct data_packet_field client_game_update_fields[8];
|
||||
#endif
|
||||
struct data_packet_definition client_game_update;
|
||||
struct data_packet_field client_add_player_request_ingame_fields[4];
|
||||
struct data_packet_definition client_add_player_request_ingame;
|
||||
@@ -308,8 +317,8 @@ DEFINE_NETWORK_GAME_MESSAGE(message_client_game_start_request, 0x02);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_graceful_game_exit_pregame, 0x04);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_map_is_precached_pregame, 0x100);
|
||||
#ifdef HALO_LINUX
|
||||
/* one 0x20-byte action per player */
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_server_game_update, 0x10 + HALO_PORT_MAXIMUM_NETWORK_PLAYERS * 0x20);
|
||||
/* one 0x20-byte action per player, and the VR players' 44-byte blocks */
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_server_game_update, 0x10 + HALO_PORT_MAXIMUM_NETWORK_PLAYERS * 0x20 + 2 + 16 * 44 + 2);
|
||||
#else
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_server_game_update, 0x210);
|
||||
#endif
|
||||
@@ -317,7 +326,11 @@ DEFINE_NETWORK_GAME_MESSAGE(message_server_add_player_ingame, 0x20);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_server_remove_player_ingame, 0x24);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_server_game_over, 0x04);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_loaded, 0x04);
|
||||
#ifdef HALO_LINUX
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_game_update, 0x88 + 2 + 4 * 44 + 2);
|
||||
#else
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_game_update, 0x88);
|
||||
#endif
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_add_player_request_ingame, 0x20);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_remove_player_request_ingame, 0x20);
|
||||
DEFINE_NETWORK_GAME_MESSAGE(message_client_host_crashed_cry_for_help, 0x10);
|
||||
@@ -469,6 +482,12 @@ struct network_game_message_packet_definitions data_0030aa68 =
|
||||
DATA_PACKET_FIELD(_data_packet_field_shorts, 3),
|
||||
DATA_PACKET_FIELD(_data_packet_field_pad, 2),
|
||||
DATA_PACKET_FIELD_END,
|
||||
#ifdef HALO_LINUX
|
||||
DATA_PACKET_FIELD(_data_packet_field_array, 16),
|
||||
DATA_PACKET_FIELD(_data_packet_field_shorts, 22),
|
||||
DATA_PACKET_FIELD_END,
|
||||
DATA_PACKET_FIELD(_data_packet_field_pad, 2),
|
||||
#endif
|
||||
DATA_PACKET_FIELD_END,
|
||||
},
|
||||
NETWORK_GAME_MESSAGE_DEFINITION(server_game_update, "message_server_game_update_packet", message_server_game_update),
|
||||
@@ -505,6 +524,12 @@ struct network_game_message_packet_definitions data_0030aa68 =
|
||||
DATA_PACKET_FIELD(_data_packet_field_shorts, 3),
|
||||
DATA_PACKET_FIELD(_data_packet_field_pad, 2),
|
||||
DATA_PACKET_FIELD_END,
|
||||
#ifdef HALO_LINUX
|
||||
DATA_PACKET_FIELD(_data_packet_field_array, 4),
|
||||
DATA_PACKET_FIELD(_data_packet_field_shorts, 22),
|
||||
DATA_PACKET_FIELD_END,
|
||||
DATA_PACKET_FIELD(_data_packet_field_pad, 2),
|
||||
#endif
|
||||
DATA_PACKET_FIELD_END,
|
||||
},
|
||||
NETWORK_GAME_MESSAGE_DEFINITION(client_game_update, "message_client_game_update_packet", message_client_game_update),
|
||||
|
||||
@@ -628,6 +628,9 @@ struct message_client_game_update
|
||||
short unknown04;
|
||||
short player_count;
|
||||
struct player_action actions[MAXIMUM_PLAYERS_PER_MACHINE];
|
||||
#ifdef HALO_LINUX
|
||||
PLAYER_ACTION_VR_TAIL(MAXIMUM_PLAYERS_PER_MACHINE)
|
||||
#endif
|
||||
};
|
||||
|
||||
struct server_update
|
||||
@@ -645,6 +648,9 @@ struct message_server_game_update
|
||||
word unknown0C;
|
||||
word player_count;
|
||||
byte player_updates[MAXIMUM_NETWORK_PLAYER_COUNT * PLAYER_UPDATE_SIZE];
|
||||
#ifdef HALO_LINUX
|
||||
PLAYER_ACTION_VR_TAIL(MAXIMUM_VR_PLAYERS_PER_UPDATE)
|
||||
#endif
|
||||
};
|
||||
|
||||
struct network_machine
|
||||
@@ -1706,6 +1712,23 @@ void network_game_server_handle_client_update_packet(
|
||||
}
|
||||
|
||||
update_server_handle_client_update(machine->machine_index, actions);
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* its players' VR blocks (game/players.h) */
|
||||
struct player_action_vr vr[MAXIMUM_PLAYERS_PER_MACHINE];
|
||||
short entry;
|
||||
|
||||
csmemset(vr, 0, sizeof(vr));
|
||||
for (entry = 0; entry < message_packet->vr_count && entry < MAXIMUM_PLAYERS_PER_MACHINE; entry++)
|
||||
{
|
||||
short slot = message_packet->vr_entries[entry].player;
|
||||
|
||||
if (slot >= 0 && slot < message_packet->player_count)
|
||||
vr[slot] = message_packet->vr_entries[entry].vr;
|
||||
}
|
||||
update_server_handle_client_vr(machine->machine_index, vr);
|
||||
}
|
||||
#endif
|
||||
|
||||
machine->last_received_update_sequence_number =
|
||||
message_packet->update_number & CLIENT_UPDATE_SEQUENCE_NUMBER_MASK;
|
||||
@@ -1798,6 +1821,25 @@ void network_game_server_update_ticks(
|
||||
game_update.player_updates,
|
||||
update.player_updates,
|
||||
update.player_count * PLAYER_UPDATE_SIZE);
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* the VR players' blocks (game/players.h) */
|
||||
struct player_action_vr const *vr = update_server_get_update_vr(update_number);
|
||||
short player_index;
|
||||
|
||||
game_update.vr_count = 0;
|
||||
game_update.vr_pad = 0;
|
||||
for (player_index = 0; vr && player_index < (short)update.player_count; player_index++)
|
||||
{
|
||||
if (vr[player_index].flags && game_update.vr_count < MAXIMUM_VR_PLAYERS_PER_UPDATE)
|
||||
{
|
||||
game_update.vr_entries[game_update.vr_count].player = player_index;
|
||||
game_update.vr_entries[game_update.vr_count].vr = vr[player_index];
|
||||
game_update.vr_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
message = create_network_game_message(
|
||||
_message_server_game_update,
|
||||
|
||||
@@ -424,6 +424,7 @@ struct message_client_game_update
|
||||
#ifdef HALO_LINUX
|
||||
/* a machine's players, which 16 players / 4 machines only happened to give */
|
||||
struct player_action actions[MAXIMUM_LOCAL_PLAYERS];
|
||||
PLAYER_ACTION_VR_TAIL(MAXIMUM_LOCAL_PLAYERS)
|
||||
#else
|
||||
struct player_action actions[MAXIMUM_NUMBER_OF_PLAYERS / MAXIMUM_NETWORK_MACHINE_COUNT];
|
||||
#endif
|
||||
|
||||
+33
-36
@@ -1013,8 +1013,8 @@ short unit_update_animation(
|
||||
|
||||
static boolean unit_vectors_are_valid(long unit_index);
|
||||
static void unit_throw_grenade_release(long unit_index, boolean premature);
|
||||
#ifdef HALO_ANDROID
|
||||
static short unit_vr_grenade_player(long unit_index);
|
||||
#ifdef HALO_LINUX
|
||||
static struct player_action_vr const *unit_vr_action(long unit_index);
|
||||
#endif
|
||||
|
||||
static void unit_seat_update(long object_index);
|
||||
@@ -5783,14 +5783,14 @@ boolean unit_update(
|
||||
break;
|
||||
case _unit_grenade_throw_in_hand:
|
||||
++unit->unit.grenade_throw_ticks;
|
||||
#ifdef HALO_ANDROID
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* VR: held while the trigger is, and thrown as it lets go */
|
||||
short vr_local_player_index = unit_vr_grenade_player(unit_index);
|
||||
struct player_action_vr const *vr_action = unit_vr_action(unit_index);
|
||||
|
||||
if (vr_local_player_index != NONE)
|
||||
if (vr_action)
|
||||
{
|
||||
if (!halo_vr_grenade_held(vr_local_player_index))
|
||||
if (!TEST_FLAG(vr_action->flags, _player_action_vr_grenade_held_bit))
|
||||
unit_throw_grenade_release(unit_index, FALSE);
|
||||
break;
|
||||
}
|
||||
@@ -8948,14 +8948,16 @@ void unit_cause_player_melee_damage(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HALO_ANDROID
|
||||
if (unit->unit.player_index!=NONE)
|
||||
#ifdef HALO_LINUX
|
||||
{
|
||||
/* VR: the swing's weight, not the run's */
|
||||
real swing = halo_vr_melee_strength();
|
||||
struct player_action_vr const *vr_action = unit_vr_action(unit_index);
|
||||
|
||||
if (swing>damage_data.scale)
|
||||
damage_data.scale = swing;
|
||||
if (vr_action && TEST_FLAG(vr_action->flags, _player_action_vr_melee_bit) &&
|
||||
player_action_vr_direction(vr_action->melee_strength)>damage_data.scale)
|
||||
{
|
||||
damage_data.scale = player_action_vr_direction(vr_action->melee_strength);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (unit->object.type==_object_type_biped &&
|
||||
@@ -11096,19 +11098,17 @@ static boolean unit_vectors_are_valid(
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef HALO_ANDROID
|
||||
/* VR: the local player whose grenade the left hand holds and throws
|
||||
(halo_vr_grenade_held), or NONE */
|
||||
static short unit_vr_grenade_player(
|
||||
#ifdef HALO_LINUX
|
||||
/* VR: the VR block of the input of the player whose unit this is
|
||||
(game/players.h), or NULL: the same on every machine in a game */
|
||||
static struct player_action_vr const *unit_vr_action(
|
||||
long unit_index)
|
||||
{
|
||||
long player_index = player_index_from_unit_index(unit_index);
|
||||
struct player_datum *player;
|
||||
|
||||
if (!halo_vr_active() || player_index == NONE)
|
||||
return NONE;
|
||||
player = player_get(player_index);
|
||||
return player->unit_index == unit_index ? player->local_player_index : NONE;
|
||||
if (player_index == NONE || player_get(player_index)->unit_index != unit_index)
|
||||
return NULL;
|
||||
return player_action_vr_get(player_index);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11120,12 +11120,12 @@ static void unit_throw_grenade_release(
|
||||
|
||||
struct unit_datum *unit = unit_get(unit_index);
|
||||
struct unit_definition *unit_definition = unit_definition_get(unit->definition_index);
|
||||
#ifdef HALO_ANDROID
|
||||
short vr_local_player_index = unit_vr_grenade_player(unit_index);
|
||||
#ifdef HALO_LINUX
|
||||
struct player_action_vr const *vr_action = unit_vr_action(unit_index);
|
||||
boolean vr_thrown = FALSE;
|
||||
|
||||
/* VR: the grenade stays in the hand while the trigger holds it */
|
||||
if (vr_local_player_index != NONE && halo_vr_grenade_held(vr_local_player_index))
|
||||
if (vr_action && TEST_FLAG(vr_action->flags, _player_action_vr_grenade_held_bit))
|
||||
return;
|
||||
#endif
|
||||
|
||||
@@ -11182,24 +11182,21 @@ static void unit_throw_grenade_release(
|
||||
|
||||
{
|
||||
real scale = unit_definition->unit.grenade_velocity/TICKS_PER_SECOND;
|
||||
#ifdef HALO_ANDROID
|
||||
float vr_origin[3], vr_direction[3], vr_strength;
|
||||
|
||||
#ifdef HALO_LINUX
|
||||
/* VR: thrown by the hand, from it, its way and as hard */
|
||||
if (vr_local_player_index != NONE &&
|
||||
halo_vr_grenade_throw(vr_local_player_index, vr_origin, vr_direction, &vr_strength))
|
||||
if (vr_action && TEST_FLAG(vr_action->flags, _player_action_vr_grenade_thrown_bit))
|
||||
{
|
||||
real_point3d origin;
|
||||
real_vector3d direction;
|
||||
|
||||
origin.x = vr_origin[0];
|
||||
origin.y = vr_origin[1];
|
||||
origin.z = vr_origin[2];
|
||||
direction.i = vr_direction[0];
|
||||
direction.j = vr_direction[1];
|
||||
direction.k = vr_direction[2];
|
||||
unit_get_camera_position(unit_index, &origin);
|
||||
origin.x += player_action_vr_offset(vr_action->grenade_offset[0]);
|
||||
origin.y += player_action_vr_offset(vr_action->grenade_offset[1]);
|
||||
origin.z += player_action_vr_offset(vr_action->grenade_offset[2]);
|
||||
player_action_vr_get_direction(vr_action->grenade_direction, &direction);
|
||||
object_translate(grenade_index, &origin, NULL);
|
||||
scale_vector3d(&direction, scale * vr_strength, &initial_velocity);
|
||||
scale_vector3d(&direction,
|
||||
scale * player_action_vr_direction(vr_action->grenade_strength), &initial_velocity);
|
||||
vr_thrown = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -11208,7 +11205,7 @@ static void unit_throw_grenade_release(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HALO_ANDROID
|
||||
#ifdef HALO_LINUX
|
||||
if (vr_thrown)
|
||||
premature = FALSE;
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user