mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-23 10:00:30 +02:00
681 lines
16 KiB
C
681 lines
16 KiB
C
/*
|
|
DIRECTOR.C
|
|
|
|
symbols in this file:
|
|
000747D0 0040:
|
|
_director_get (0000)
|
|
00074810 0020:
|
|
_director_initialize (0000)
|
|
00074830 0010:
|
|
_director_dispose (0000)
|
|
00074840 0050:
|
|
_director_inhibit_facing (0000)
|
|
00074890 0050:
|
|
_director_inhibit_input (0000)
|
|
000748E0 0050:
|
|
_director_inhibited_facing (0000)
|
|
00074930 0050:
|
|
_director_inhibited_input (0000)
|
|
00074980 0050:
|
|
_director_set_mode (0000)
|
|
000749D0 00b0:
|
|
_director_save_camera (0000)
|
|
00074A80 00a0:
|
|
_director_get_perspective (0000)
|
|
00074B20 00f0:
|
|
_director_desired_perspective (0000)
|
|
00074C10 0060:
|
|
_director_set_camera (0000)
|
|
00074C70 0070:
|
|
_director_initialize_variables (0000)
|
|
00074CE0 0220:
|
|
_director_process_variables (0000)
|
|
00074F00 0070:
|
|
_director_dispose_from_old_map (0000)
|
|
00074F70 0150:
|
|
_director_load_camera (0000)
|
|
000750C0 0130:
|
|
_director_rotate_cameras (0000)
|
|
000751F0 0060:
|
|
_director_camera_deterministic (0000)
|
|
00075250 00d0:
|
|
_director_choose_game_perspective (0000)
|
|
00075320 0130:
|
|
_director_script_camera (0000)
|
|
00075450 01c0:
|
|
_director_choose_camera_game (0000)
|
|
00075610 00b0:
|
|
_director_choose_camera_editor (0000)
|
|
000756C0 00c0:
|
|
_director_choose_camera_script_camera_record (0000)
|
|
00075780 03c0:
|
|
_director_update_controls (0000)
|
|
00075B40 0050:
|
|
_director_choose_camera (0000)
|
|
00075B90 00d0:
|
|
_director_initialize_for_new_map (0000)
|
|
00075C60 01f0:
|
|
_director_update (0000)
|
|
00075E50 0020:
|
|
_director_initialize_for_saved_game (0000)
|
|
00256B18 0008:
|
|
_director_game_camera_modes (0000)
|
|
00256B20 0008:
|
|
_director_script_camera_record_camera_modes (0000)
|
|
00256B28 0004:
|
|
__real@3cf5c28f (0000)
|
|
00256B2C 0004:
|
|
_friction (0000)
|
|
00256B30 0004:
|
|
__real@41c80000 (0000)
|
|
00256B34 0004:
|
|
__real@3fa66666 (0000)
|
|
00256B38 000d:
|
|
??_C@_0N@PCFDPHGK@first?5person?$AA@ (0000)
|
|
00256B48 0007:
|
|
??_C@_06GIFLLBB@editor?$AA@ (0000)
|
|
00256B50 0007:
|
|
??_C@_06CPNKLHAC@flying?$AA@ (0000)
|
|
00256B58 0009:
|
|
??_C@_08GFACNFFL@orbiting?$AA@ (0000)
|
|
00256B64 000a:
|
|
??_C@_09BEIPBMDN@following?$AA@ (0000)
|
|
00256B70 004c:
|
|
??_C@_0EM@JCKEKCNI@local_player_index?$DO?$DN0?5?$CG?$CG?5local_p@ (0000)
|
|
00256BBC 0021:
|
|
??_C@_0CB@MLDELAOE@c?3?2halo?2SOURCE?2camera?2director?4c@ (0000)
|
|
00256BE0 0013:
|
|
??_C@_0BD@CNMFAHOJ@director?5scripting?$AA@ (0000)
|
|
00256BF4 002e:
|
|
??_C@_0CO@JGFKNOPP@mode?$DO?$DN0?5?$CG?$CG?5mode?$DMNUMBER_OF_DIRECT@ (0000)
|
|
00256C24 0004:
|
|
??_C@_03PPOCCAPH@?$CFf?6?$AA@ (0000)
|
|
00256C28 000a:
|
|
??_C@_09MALOBAAJ@?$CFf?5?$CFf?5?$CFf?6?$AA@ (0000)
|
|
00256C34 000e:
|
|
??_C@_0O@EOBEHDJM@d?3?2camera?4txt?$AA@ (0000)
|
|
00256C44 000a:
|
|
??_C@_09LKGGBKMJ@?$CFs?5camera?$AA@ (0000)
|
|
00256C50 0004:
|
|
__real@bb4de32e (0000)
|
|
00256C54 0004:
|
|
__real@b851b717 (0000)
|
|
00256C58 0004:
|
|
__real@3851b717 (0000)
|
|
00256C5C 0004:
|
|
__real@37a4b5be (0000)
|
|
00256C60 0004:
|
|
__real@b824b5be (0000)
|
|
002DCBA0 0018:
|
|
_director_camera_mode_names (0000)
|
|
002DCBB8 0070:
|
|
_variables (0000)
|
|
0031D048 03ea:
|
|
_director_globals (0000)
|
|
_director_camera_switch_fast (03e8)
|
|
*/
|
|
|
|
/* ---------- headers */
|
|
|
|
#include "director.h"
|
|
|
|
#include "dead_camera.h"
|
|
#include "editor_flying_camera.h"
|
|
#include "first_person_camera.h"
|
|
#include "flying_camera.h"
|
|
#include "following_camera.h"
|
|
#include "observer.h"
|
|
#include "orbiting_camera.h"
|
|
|
|
#include "editor/editor_stubs.h"
|
|
#include "game/player_control.h"
|
|
#include "game/players.h"
|
|
#include "main/console.h"
|
|
#include "saved games/game_state.h"
|
|
|
|
#include "units/unit_definitions.h"
|
|
#include "units/units.h"
|
|
|
|
/* ---------- constants */
|
|
|
|
/* ---------- macros */
|
|
|
|
/* ---------- structures */
|
|
|
|
/* ---------- prototypes */
|
|
|
|
void scripted_camera_update(
|
|
void *camera,
|
|
void *command,
|
|
void *result);
|
|
|
|
/* ---------- globals */
|
|
|
|
short const director_game_camera_modes[3] =
|
|
{
|
|
_camera_first_person,
|
|
_camera_flying,
|
|
_camera_following
|
|
};
|
|
|
|
short const director_script_camera_record_camera_modes[4] =
|
|
{
|
|
_camera_first_person,
|
|
_camera_flying,
|
|
_camera_following,
|
|
_camera_orbiting
|
|
};
|
|
|
|
real const friction = 5.f;
|
|
|
|
char const *director_camera_mode_names[NUMBER_OF_DIRECTOR_CAMERA_MODES] =
|
|
{
|
|
"following",
|
|
"orbiting",
|
|
"flying",
|
|
"editor",
|
|
"first person"
|
|
};
|
|
|
|
struct director_variable_definition variables[NUMBER_OF_DIRECTOR_VARIABLES] =
|
|
{
|
|
{ 5, 4, NONE, { 0, 0 }, 0.15f, 0.f, -REAL_MAX, REAL_MAX, TRUE, { 0, 0, 0 } },
|
|
{ 6, 7, NONE, { 0, 0 }, 0.075f, 0.f, -REAL_MAX, REAL_MAX, FALSE, { 0, 0, 0 } },
|
|
{ 1, 0, NONE, { 0, 0 }, 0.075f, 0.f, -REAL_MAX, REAL_MAX, TRUE, { 0, 0, 0 } },
|
|
{ 3, 2, NONE, { 0, 0 }, 0.075f, 0.f, -REAL_MAX, REAL_MAX, TRUE, { 0, 0, 0 } }
|
|
};
|
|
|
|
struct director_globals director_globals;
|
|
boolean director_camera_switch_fast;
|
|
|
|
/* ---------- public code */
|
|
|
|
static struct director *director_get(
|
|
short local_player_index)
|
|
{
|
|
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 179, local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
|
|
return &director_globals.local_players[local_player_index];
|
|
}
|
|
|
|
void director_initialize(
|
|
void)
|
|
{
|
|
director_camera_scripted = game_state_malloc("director scripting", NULL, sizeof(*director_camera_scripted));
|
|
director_camera_scripted->camera_scripted = FALSE;
|
|
return;
|
|
}
|
|
|
|
void director_dispose(
|
|
void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void director_dispose_from_old_map(
|
|
void)
|
|
{
|
|
short local_player_index;
|
|
|
|
for (local_player_index = 0; local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS; local_player_index++)
|
|
{
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
director->camera_proc = NULL;
|
|
director->debug_input_scale = 1.f;
|
|
director->debug_controls = FALSE;
|
|
}
|
|
|
|
director_camera_scripted->camera_scripted = FALSE;
|
|
return;
|
|
}
|
|
|
|
void director_inhibit_facing(
|
|
short local_player_index)
|
|
{
|
|
director_get(local_player_index)->inhibited_facing = TRUE;
|
|
return;
|
|
}
|
|
|
|
void director_inhibit_input(
|
|
short local_player_index)
|
|
{
|
|
director_get(local_player_index)->inhibited_input = TRUE;
|
|
return;
|
|
}
|
|
|
|
boolean director_inhibited_facing(
|
|
short local_player_index)
|
|
{
|
|
return director_get(local_player_index)->inhibited_facing;
|
|
}
|
|
|
|
boolean director_inhibited_input(
|
|
short local_player_index)
|
|
{
|
|
return director_get(local_player_index)->inhibited_input;
|
|
}
|
|
|
|
director_perspective director_get_perspective(
|
|
short local_player_index)
|
|
{
|
|
struct director *camera;
|
|
|
|
camera = director_get(local_player_index);
|
|
|
|
if (camera->camera_proc == first_person_camera_update)
|
|
{
|
|
if (camera->camera_change_pause == 0.f)
|
|
camera->perspective = 0;
|
|
}
|
|
else if (camera->camera_proc == following_camera_update)
|
|
{
|
|
camera->perspective = 1;
|
|
}
|
|
else if (camera->camera_proc == scripted_camera_update)
|
|
{
|
|
camera->perspective = 2;
|
|
}
|
|
else
|
|
{
|
|
camera->perspective = 3;
|
|
}
|
|
|
|
return camera->perspective;
|
|
}
|
|
|
|
short director_desired_perspective(
|
|
long unit_index,
|
|
director_perspective *perspective)
|
|
{
|
|
short following = FALSE;
|
|
|
|
*perspective = 0;
|
|
if (unit_index != NONE)
|
|
{
|
|
struct unit_datum *unit = unit_get(unit_index);
|
|
if (unit->object.parent_object_index != NONE)
|
|
{
|
|
struct object_datum *parent_object = object_get(unit->object.parent_object_index);
|
|
if (TEST_FLAG(_object_mask_unit, parent_object->object.type))
|
|
{
|
|
boolean third_person_on_enter;
|
|
struct unit_seat *seat = TAG_BLOCK_GET_ELEMENT(
|
|
&unit_definition_get(parent_object->definition_index)->unit.seats,
|
|
unit->unit.parent_seat_index,
|
|
struct unit_seat);
|
|
|
|
third_person_on_enter = TEST_FLAG(seat->flags, _unit_seat_third_person_on_enter_bit);
|
|
if (TEST_FLAG(seat->flags, _unit_seat_third_person_camera_bit))
|
|
following = TRUE;
|
|
if (third_person_on_enter)
|
|
{
|
|
if (unit->unit.animation.state == _unit_state_entering_seat)
|
|
*perspective = 1;
|
|
else if (unit->unit.animation.state == _unit_state_exiting_seat)
|
|
*perspective = 3;
|
|
else
|
|
*perspective = 2;
|
|
}
|
|
else
|
|
{
|
|
*perspective = 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*perspective = 2;
|
|
}
|
|
}
|
|
|
|
if (*perspective == 1 || *perspective == 3)
|
|
following = TRUE;
|
|
}
|
|
|
|
return following;
|
|
}
|
|
|
|
void director_set_mode(
|
|
short mode)
|
|
{
|
|
match_assert("c:\\halo\\SOURCE\\camera\\director.c", 384, mode>=0 && mode<NUMBER_OF_DIRECTOR_GAME_MODES);
|
|
if (director_globals.game_mode != mode)
|
|
{
|
|
director_globals.game_mode = mode;
|
|
director_globals.initialize_camera = TRUE;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void director_save_camera(
|
|
void)
|
|
{
|
|
FILE *file;
|
|
|
|
file = fopen("d:\\camera.txt", "w");
|
|
if (file)
|
|
{
|
|
struct observer_result const *camera;
|
|
|
|
camera = observer_get_camera(0);
|
|
fprintf(file, "%f %f %f\n", camera->position.x, camera->position.y, camera->position.z);
|
|
fprintf(file, "%f %f %f\n", camera->forward.i, camera->forward.j, camera->forward.k);
|
|
fprintf(file, "%f %f %f\n", camera->up.i, camera->up.j, camera->up.k);
|
|
fprintf(file, "%f\n", camera->field_of_view);
|
|
fclose(file);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_set_camera(
|
|
short local_player_index,
|
|
director_camera_update_proc camera_proc,
|
|
boolean interpolate)
|
|
{
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
director->camera_proc = camera_proc;
|
|
director->debug_input_scale = 1.f;
|
|
director->debug_controls = FALSE;
|
|
if (interpolate)
|
|
director->camera_change_pause = 1.f;
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_initialize_variables(
|
|
short local_player_index)
|
|
{
|
|
short variable_index;
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
for (variable_index = 0;
|
|
variable_index < NUMBER_OF_DIRECTOR_VARIABLES;
|
|
variable_index++)
|
|
{
|
|
director->debug_variables[variable_index].value = variables[variable_index].initial_value;
|
|
director->debug_variables[variable_index].delta = 0.f;
|
|
director->debug_variables[variable_index].velocity = 0.f;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_rotate_cameras(
|
|
short local_player_index,
|
|
short const *camera_modes,
|
|
short camera_mode_count)
|
|
{
|
|
short camera_mode;
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
director->camera_mode_index = (director->camera_mode_index + 1) % camera_mode_count;
|
|
camera_mode = camera_modes[director->camera_mode_index];
|
|
switch (camera_mode)
|
|
{
|
|
case _camera_following:
|
|
following_camera_new((struct following_camera *)director->camera_data);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)following_camera_update,
|
|
TRUE);
|
|
break;
|
|
|
|
case _camera_orbiting:
|
|
orbiting_camera_new(
|
|
(struct orbiting_camera *)director->camera_data,
|
|
director->command.focus_distance,
|
|
&director->command.forward);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)orbiting_camera_update,
|
|
TRUE);
|
|
break;
|
|
|
|
case _camera_flying:
|
|
flying_camera_new_from_point_and_vector(
|
|
(struct flying_camera *)director->camera_data,
|
|
&director->command.focus_position,
|
|
&director->command.forward);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)flying_camera_update,
|
|
TRUE);
|
|
break;
|
|
|
|
case _camera_editor:
|
|
break;
|
|
|
|
case _camera_first_person:
|
|
first_person_camera_new((struct first_person_camera *)director->camera_data);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)first_person_camera_update,
|
|
TRUE);
|
|
break;
|
|
|
|
default:
|
|
display_assert(NULL, "c:\\halo\\SOURCE\\camera\\director.c", 512, TRUE);
|
|
system_exit(NONE);
|
|
break;
|
|
}
|
|
|
|
console_printf(
|
|
FALSE,
|
|
"%s camera",
|
|
director_camera_mode_names[camera_modes[director->camera_mode_index]]);
|
|
return;
|
|
}
|
|
|
|
static void director_choose_game_perspective(
|
|
short local_player_index,
|
|
boolean force)
|
|
{
|
|
director_perspective perspective;
|
|
short following;
|
|
long unit_index;
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
unit_index = player_control_get_unit_index(local_player_index);
|
|
following = director_desired_perspective(unit_index, &perspective);
|
|
if (force || director->seat_state != perspective)
|
|
{
|
|
if (following == TRUE)
|
|
{
|
|
if (force || director->camera_proc == (director_camera_update_proc)first_person_camera_update)
|
|
{
|
|
following_camera_new((struct following_camera *)director->camera_data);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)following_camera_update,
|
|
!force);
|
|
}
|
|
}
|
|
else if (force || director->camera_proc == (director_camera_update_proc)following_camera_update)
|
|
{
|
|
first_person_camera_new((struct first_person_camera *)director->camera_data);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)first_person_camera_update,
|
|
!force);
|
|
}
|
|
|
|
director->seat_state = perspective;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_choose_camera_game(
|
|
short local_player_index,
|
|
boolean initialize,
|
|
boolean key)
|
|
{
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
if (initialize)
|
|
{
|
|
first_person_camera_new((struct first_person_camera *)director->camera_data);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)first_person_camera_update,
|
|
FALSE);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
struct player_datum *player = player_get(local_player_get_player_index(local_player_index));
|
|
boolean use_dead_camera = player->unit_index == NONE && player->statistics.deaths > 0;
|
|
|
|
if (key)
|
|
director_rotate_cameras(local_player_index, director_game_camera_modes, 3);
|
|
if (!director_camera_scripted->camera_scripted)
|
|
{
|
|
director_choose_game_perspective(local_player_index, initialize);
|
|
if (use_dead_camera)
|
|
{
|
|
if (director->camera_proc != (director_camera_update_proc)dead_camera_update)
|
|
{
|
|
dead_camera_new(
|
|
(struct dead_camera *)director->camera_data,
|
|
local_player_index,
|
|
NONE);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)dead_camera_update,
|
|
TRUE);
|
|
}
|
|
}
|
|
else if (director->camera_proc == (director_camera_update_proc)dead_camera_update)
|
|
{
|
|
director_choose_game_perspective(local_player_index, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_choose_camera_editor(
|
|
short local_player_index,
|
|
boolean initialize,
|
|
boolean key)
|
|
{
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
if (initialize || director->camera_proc != (director_camera_update_proc)editor_camera_update)
|
|
{
|
|
editor_camera_new(
|
|
(struct flying_camera *)director->camera_data,
|
|
local_player_index);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)editor_camera_update,
|
|
FALSE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_choose_camera_script_camera_record(
|
|
short local_player_index,
|
|
boolean initialize,
|
|
boolean key)
|
|
{
|
|
if (initialize)
|
|
{
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
first_person_camera_new((struct first_person_camera *)director->camera_data);
|
|
director_set_camera(
|
|
local_player_index,
|
|
(director_camera_update_proc)first_person_camera_update,
|
|
FALSE);
|
|
}
|
|
else if (key)
|
|
{
|
|
director_rotate_cameras(
|
|
local_player_index,
|
|
director_script_camera_record_camera_modes,
|
|
4);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void director_choose_camera(
|
|
short local_player_index,
|
|
boolean initialize,
|
|
boolean key)
|
|
{
|
|
switch (director_globals.game_mode)
|
|
{
|
|
case _director_mode_game:
|
|
case _director_mode_netgame:
|
|
director_choose_camera_game(local_player_index, initialize, key);
|
|
return;
|
|
|
|
case _director_mode_editor:
|
|
director_choose_camera_editor(local_player_index, initialize, key);
|
|
return;
|
|
|
|
case _director_mode_script_camera_record:
|
|
director_choose_camera_script_camera_record(local_player_index, initialize, key);
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void director_initialize_for_new_map(
|
|
void)
|
|
{
|
|
short local_player_index;
|
|
|
|
director_globals.game_mode = game_in_editor() ? _director_mode_editor : _director_mode_game;
|
|
director_globals.initialize_camera = FALSE;
|
|
for (local_player_index = 0;
|
|
local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS;
|
|
local_player_index++)
|
|
{
|
|
struct director *director = director_get(local_player_index);
|
|
|
|
director->bored = FALSE;
|
|
director->bored_time = 0;
|
|
director->camera_change_pause = 0.f;
|
|
director_choose_camera(local_player_index, TRUE, FALSE);
|
|
director_initialize_variables(local_player_index);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void director_initialize_for_saved_game(
|
|
void)
|
|
{
|
|
director_initialize_for_new_map();
|
|
director_script_camera(director_camera_scripted->camera_scripted);
|
|
|
|
return;
|
|
}
|
|
|
|
short director_camera_deterministic(
|
|
long unit_index,
|
|
real_point3d *position,
|
|
real_vector3d *forward)
|
|
{
|
|
director_perspective perspective;
|
|
short following;
|
|
|
|
following = director_desired_perspective(unit_index, &perspective);
|
|
if (!following)
|
|
first_person_camera_deterministic(unit_index, position, forward);
|
|
else
|
|
following_camera_deterministic(unit_index, position, forward);
|
|
|
|
return following;
|
|
}
|
|
|
|
/* ---------- private code */
|