diff --git a/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.fov_viewmodels.xml b/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.fov_viewmodels.xml
index 1cea9b97..faf580b8 100644
--- a/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.fov_viewmodels.xml
+++ b/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.fov_viewmodels.xml
@@ -67,8 +67,8 @@
-
-
+
+
diff --git a/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.xml b/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.xml
index 7d4d8d36..0173ec76 100644
--- a/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.xml
+++ b/port/assets/menus/ce/main_menu.settings_select.player_setup.player_profile_edit.video_settings.xml
@@ -155,7 +155,6 @@
-
+
-
diff --git a/port/linux/README.md b/port/linux/README.md
index 0c621fde..bbfcd2aa 100644
--- a/port/linux/README.md
+++ b/port/linux/README.md
@@ -316,21 +316,6 @@ from the next main menu.
Each setting has an environment variable. The environment variable changes
the setting for one start of the game. It has priority over the file.
-Video Setup's **FOV AND VIEWMODELS** category offers optional world and
-weapon field of view settings and first person visibility. **DEFAULT** keeps
-the authored world projection. **DEFAULT** for the weapon keeps its original
-view, and viewmodels start **ON**. A chosen weapon angle is that FOV. OK
-saves and applies changes. Cancel discards them. The menu offers 80 to 150
-degrees in steps of five. The config file accepts 20 to 150 degrees,
-including fractional values, or zero for Default.
-Angles are horizontal at 16:9; other aspect ratios retain the same vertical
-view. World FOV applies to on-foot first-person views, preserving authored
-vehicle, death and cinematic cameras. Completed scopes keep their native
-view with wider FOV; a narrower FOV also narrows the scope. Aiming reticles
-scale with the world projection, while scope artwork keeps its layout.
-Viewmodel FOV also applies to attached visuals. Hiding viewmodels changes
-only their display; firing, animation, sound and world lights continue.
-
| Setting | Default | Environment variable | Function |
| --- | --- | --- | --- |
| `display.mode` | `""` | `HALO_DISPLAY_MODE` | `"fullscreen"`: the display, taken at the mode of `display.resolution` (the nearest the display has), or at its desktop mode. `"borderless"`: a window over the whole desktop, whose mode does not change. `"windowed"`: a window of `display.window_size`. Empty: `display.fullscreen` decides (`true`: borderless). F11 changes between the window and the fullscreen mode. Video Setup sets it. |
@@ -345,9 +330,9 @@ only their display; firing, animation, sound and world lights continue.
| `debug.gpu_flush_draws` | `-1` | `HALO_GPU_FLUSH_DRAWS` | Flush the GPU's pipeline every this many draws. `-1`: every 3 on Intel graphics with Mesa's driver, which can otherwise hang in the game's long runs of small draws and reset the desktop's graphics too. `0`: never. |
| `display.interpolation` | `true` | `HALO_INTERPOLATION` | `true`: one frame for each refresh of the display. `false`: 30 frames each second, as on the Xbox. Refer to "Frame rate". |
| `display.direct_camera` | `true` | `HALO_DIRECT_CAMERA` | `true`: in first person, on foot, the view points where the player aims in each frame, not where the last tick left it. Refer to "Frame rate". |
-| `display.fov` | `0.0` | `HALO_FOV` | On-foot first-person horizontal FOV at 16:9, from 20 to 150 degrees. `0` keeps the authored view. Video Setup's FOV and Viewmodels screen sets it. |
-| `display.viewmodel_fov` | `0.0` | `HALO_VIEWMODEL_FOV` | Weapon and hands horizontal FOV at 16:9, 20 to 150 degrees. `0` is Default and keeps the original weapon view. A chosen angle is that FOV. |
-| `display.viewmodel_visible` | `true` | `HALO_VIEWMODEL_VIS` | Show first-person weapons, hands and attached visuals. This does not change gameplay or other players' models. |
+| `display.fov` | `0.0` | `HALO_FOV` | The first-person view's field of view on foot, in degrees across at 16:9, from 20 to 150. `0`: the stock view. Refer to "Field of view". |
+| `display.viewmodel_fov` | `0.0` | `HALO_VIEWMODEL_FOV` | The first-person weapon's and hands' field of view, in degrees across at 16:9, from 20 to 150. `0`: the weapon's stock view, also when `display.fov` widens the world. Refer to "Field of view". |
+| `display.viewmodel_visible` | `true` | `HALO_VIEWMODEL_VISIBLE` | `true`: the first-person weapon, hands and what is attached to them are drawn. `false`: they are not; firing, animation, sound and lights go on, and other players' models are drawn. |
| `display.high_res_hud` | `true` | `HALO_HIGH_RES_HUD` | `true`: the HUD (meters, counters, panels and their outlines, the motion sensor, reticles, waypoints, scopes) is drawn from the high-res assets in `port/assets/hud`, 8x the size of the maps' bitmaps. The bitmaps with English text keep the maps' own. `false`: the maps' own bitmaps. |
| `display.high_res_text` | `true` | `HALO_HIGH_RES_TEXT` | `true`: the menus' and HUD's text is drawn with the fonts in `port/assets/fonts` (Overpass, in place of the maps' Interstate) at the resolution the game draws at, laid out as before, and the menus' titles are drawn from the high-res pictures in `port/assets/titles`. `false`: the maps' bitmap fonts and titles. |
| `display.shadow_resolution` | `128` | `HALO_SHADOW_RESOLUTION` | The size of the maps that the shadows of the objects are drawn in, in pixels each way: `128`, `256`, `512` or `1024` (other values go down to one of these). The game draws the shadow of each object into a map of 128x128 pixels, blurs it and projects it onto the ground. On a large screen, the edges of these shadows show steps that move when the object moves. A larger map makes the edges smooth; the blur is made wider to match, so the shadows are as soft as on the Xbox. Each doubling adds two passes of the blur. `128`: as on the Xbox. |
@@ -489,6 +474,29 @@ the world (such as `rasterizer_wireframe`). Refer to `NETCODE.md`.
The frame rate shows at the bottom right of the screen. It is the mean over
half a second.
+## Field of view
+
+Video Setup's FOV AND VIEWMODELS screen sets the field of view of the
+first-person view (`display.fov`) and of the weapon and hands
+(`display.viewmodel_fov`), from 80 to 150 degrees in steps of 5, and can
+hide the weapon (`display.viewmodel_visible`). DEFAULT, the setting's `0`,
+keeps the stock view. `config.toml` takes any angle from 20 to 150.
+
+- An angle is across the screen at 16:9. Another shape keeps the same
+ angle up and down, as the stock view does.
+- The field of view applies on foot in first person only. Vehicles, death,
+ cinematics and scripted cameras keep their own view.
+- A scope's zoom levels keep their stock view: the extra width fades out as
+ the zoom comes in. A view narrower than the stock one narrows the zoom
+ too.
+- The reticles scale with the view, so that they stay on the aim. The
+ scopes' pictures keep their place.
+- By default the weapon keeps its stock view when the world is wider:
+ arms and a gun right against the camera stretch at a wide angle.
+
+Only this machine's view changes. Nothing the machines send each other
+changes, so players with different settings play together.
+
## System link
The Xbox game lets 16 players on 4 machines play a system link game. This
diff --git a/port/linux/game/render_fov.c b/port/linux/game/render_fov.c
deleted file mode 100644
index cfb65b6e..00000000
--- a/port/linux/game/render_fov.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* FOV in horizontal degrees at 16:9. The observer, its transitions and the
-network's camera values remain authored; only the local render view changes.
-Default follows the original projection exactly. */
-#include "cseries.h"
-#include "render_fov.h"
-#include "camera/director.h"
-#include "cutscene/cinematics.h"
-#include "game/players.h"
-#include "objects/objects.h"
-#include "units/units.h"
-#include "units/unit_definitions.h"
-#include "items/weapons.h"
-#include "render/render_cameras.h"
-
-#include
-
-double config_real(const char *name);
-unsigned long config_changes(void);
-
-static real reticle_scales[MAXIMUM_LOCAL_PLAYERS];
-static real authored_vertical[MAXIMUM_LOCAL_PLAYERS];
-
-static float render_fov_adjust(short local_player_index, float native_vertical_field_of_view)
-{
- static boolean initialized;
- static unsigned long read_at;
- static real requested_tangent;
- unsigned long changes = config_changes();
- long unit_index, weapon_index;
- struct unit_datum *unit;
- real unzoomed_angle, unzoomed_tangent, native_tangent, adjusted_tangent;
-
- if (!initialized || read_at != changes)
- {
- double degrees = config_real("display.fov");
-
- initialized = TRUE;
- read_at = changes;
- requested_tangent = isfinite(degrees) && degrees >= 20.0 && degrees <= 150.0 ?
- (real)(tan(degrees * 3.14159265358979323846 / 360.0) * (9.0 / 16.0)) : 0.0f;
- }
- if (!requested_tangent || local_player_index < 0 || local_player_index >= MAXIMUM_LOCAL_PLAYERS ||
- cinematic_in_progress() || (director_camera_scripted && *director_camera_scripted) ||
- director_get_perspective(local_player_index) != _director_perspective_first_person ||
- director_inhibited_facing(local_player_index))
- {
- return native_vertical_field_of_view;
- }
- unit_index = player_control_get_unit_index(local_player_index);
- if (unit_index == NONE)
- return native_vertical_field_of_view;
- unit = unit_try_and_get(unit_index);
- if (!unit || unit->object.parent_object_index != NONE || TEST_FLAG(unit->object.damage_flags, _object_dead_bit))
- return native_vertical_field_of_view;
-
- unzoomed_angle = unit_definition_get(unit->definition_index)->unit.camera_field_of_view;
- if (!(unzoomed_angle >= 0.001f && unzoomed_angle <= _pi / 2.0f) ||
- !(native_vertical_field_of_view > 0.0f && native_vertical_field_of_view < _pi))
- {
- return native_vertical_field_of_view;
- }
- unzoomed_tangent = 0.75f * render_camera_get_adjusted_field_of_view_tangent(unzoomed_angle);
- native_tangent = tanf(native_vertical_field_of_view * 0.5f);
- if (requested_tangent < unzoomed_tangent)
- {
- /* A narrow base view must not become wider when zoom is pressed. */
- adjusted_tangent = native_tangent * (requested_tangent / unzoomed_tangent);
- }
- else
- {
- real blend = 1.0f;
-
- weapon_index = unit_inventory_get_weapon(unit_index, unit->unit.current_weapon_index);
- if (weapon_index != NONE)
- {
- real scoped_angle = weapon_get_field_of_view(weapon_index, unzoomed_angle, 0);
-
- if (scoped_angle > 0.0f && scoped_angle < unzoomed_angle)
- {
- real scoped_tangent = 0.75f * render_camera_get_adjusted_field_of_view_tangent(scoped_angle);
- /* The observer's atan/tan round trip can land just above
- the endpoint. Keep a completed scope's original angle exactly. */
- if (native_tangent <= scoped_tangent * 1.000001f)
- return native_vertical_field_of_view;
-
- /* Fade the extra width along the observer's existing scope
- transition. Every completed scope level keeps its stock view. */
- blend = PIN((native_tangent - scoped_tangent) /
- (unzoomed_tangent - scoped_tangent), 0.0f, 1.0f);
- }
- }
- if (blend == 0.0f)
- return native_vertical_field_of_view;
- adjusted_tangent = native_tangent + (requested_tangent - unzoomed_tangent) * blend;
- }
- return 2.0f * atanf(adjusted_tangent);
-}
-
-float render_fov_vertical(short local_player_index, float native_vertical_field_of_view)
-{
- real adjusted = render_fov_adjust(local_player_index, native_vertical_field_of_view);
-
- if (local_player_index >= 0 && local_player_index < MAXIMUM_LOCAL_PLAYERS)
- {
- real scale = 1.0f;
-
- if (adjusted != native_vertical_field_of_view &&
- native_vertical_field_of_view > 0.0f && native_vertical_field_of_view < _pi &&
- adjusted > 0.0f && adjusted < _pi)
- {
- scale = tanf(native_vertical_field_of_view * 0.5f) / tanf(adjusted * 0.5f);
- if (!isfinite(scale) || scale <= 0.0f) scale = 1.0f;
- }
- /* Record the projection used for this view, including its native zoom
- * transition. A temporary viewmodel projection must not affect the HUD. */
- reticle_scales[local_player_index] = scale;
- /* A widened world view. The weapon can return to this frame's own angle. */
- authored_vertical[local_player_index] =
- adjusted != native_vertical_field_of_view ? native_vertical_field_of_view : 0.0f;
- }
- return adjusted;
-}
-
-float render_fov_authored_vertical(short local_player_index)
-{
- if (local_player_index < 0 || local_player_index >= MAXIMUM_LOCAL_PLAYERS)
- return 0.0f;
- return authored_vertical[local_player_index];
-}
-
-float render_fov_reticle_scale(short local_player_index)
-{
- if (local_player_index < 0 || local_player_index >= MAXIMUM_LOCAL_PLAYERS ||
- reticle_scales[local_player_index] == 0.0f) return 1.0f;
- return reticle_scales[local_player_index];
-}
diff --git a/port/linux/game/render_fov.h b/port/linux/game/render_fov.h
deleted file mode 100644
index 024a98b8..00000000
--- a/port/linux/game/render_fov.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* A local display adjustment, after the observer and before either render
-camera's projection and visibility frustum are built. */
-#ifndef RENDER_FOV_H
-#define RENDER_FOV_H
-
-float render_fov_vertical(short local_player_index, float native_vertical_field_of_view);
-/* HUD pixel ratio relative to the native projection of the last local view. */
-float render_fov_reticle_scale(short local_player_index);
-/* The view's own vertical angle when the world FOV replaced it, else 0. */
-float render_fov_authored_vertical(short local_player_index);
-
-#endif
diff --git a/port/linux/game/view_fov.c b/port/linux/game/view_fov.c
new file mode 100644
index 00000000..c6f3f6ac
--- /dev/null
+++ b/port/linux/game/view_fov.c
@@ -0,0 +1,269 @@
+/*
+VIEW_FOV.C
+
+The first-person view's field of view (display.fov, display.viewmodel_fov)
+and whether the weapon is drawn (display.viewmodel_visible), the local
+render view only: the observer, its transitions and what the network sends
+keep the game's own camera. Each angle is horizontal at 16:9 (the vertical
+angle is kept, so other shapes of window widen or narrow as the stock view
+does), and 0 keeps the stock view. Called from the game's camera
+(main.c's set_window_camera_values), its HUD (hud_draw.c) and the passes
+that draw the first-person weapon (rasterizer and render sources).
+*/
+
+#include "cseries.h"
+#include "view_fov.h"
+#include "camera/director.h"
+#include "cutscene/cinematics.h"
+#include "game/players.h"
+#include "items/weapons.h"
+#include "objects/objects.h"
+#include "rasterizer/rasterizer.h"
+#include "rasterizer/xbox/rasterizer_xbox_internal.h"
+#include "render/render.h"
+#include "render/render_cameras.h"
+#include "render/render_cameras_internal.h"
+#include "units/unit_definitions.h"
+#include "units/units.h"
+
+#include
+
+/* (the window's rasterizer target, as the rasterizer's sources number it) */
+enum
+{
+ _rasterizer_target_render_primary = 0
+};
+
+double config_real(const char *name);
+int config_boolean(const char *name);
+unsigned long config_changes(void);
+
+/* ---------- the world's field of view */
+
+static real reticle_scales[MAXIMUM_LOCAL_PLAYERS];
+static real authored_vertical[MAXIMUM_LOCAL_PLAYERS];
+
+/* the view's vertical angle for display.fov: the game's own in a vehicle,
+dead, in a cinematic, a scripted camera or a view the director holds, and
+at a scope's full zoom; between, the zoom's own transition */
+static real render_fov_adjust(short local_player_index, real native_vertical_field_of_view)
+{
+ static boolean initialized;
+ static unsigned long read_at;
+ static real requested_tangent;
+ unsigned long changes = config_changes();
+ long unit_index, weapon_index;
+ struct unit_datum *unit;
+ real unzoomed_angle, unzoomed_tangent, native_tangent, adjusted_tangent;
+
+ if (!initialized || read_at != changes)
+ {
+ double degrees = config_real("display.fov");
+
+ initialized = TRUE;
+ read_at = changes;
+ requested_tangent = degrees >= 20.0 && degrees <= 150.0 ?
+ (real)(tan(degrees * _pi / 360.0) * (9.0 / 16.0)) : 0.0f;
+ }
+ if (!requested_tangent || local_player_index < 0 || local_player_index >= MAXIMUM_LOCAL_PLAYERS ||
+ cinematic_in_progress() || (director_camera_scripted && *director_camera_scripted) ||
+ director_get_perspective(local_player_index) != _director_perspective_first_person ||
+ director_inhibited_facing(local_player_index))
+ {
+ return native_vertical_field_of_view;
+ }
+ unit_index = player_control_get_unit_index(local_player_index);
+ if (unit_index == NONE)
+ return native_vertical_field_of_view;
+ unit = unit_try_and_get(unit_index);
+ if (!unit || unit->object.parent_object_index != NONE || TEST_FLAG(unit->object.damage_flags, _object_dead_bit))
+ return native_vertical_field_of_view;
+
+ unzoomed_angle = unit_definition_get(unit->definition_index)->unit.camera_field_of_view;
+ if (!(unzoomed_angle >= 0.001f && unzoomed_angle <= _pi / 2.0f) ||
+ !(native_vertical_field_of_view > 0.0f && native_vertical_field_of_view < _pi))
+ {
+ return native_vertical_field_of_view;
+ }
+ unzoomed_tangent = 0.75f * render_camera_get_adjusted_field_of_view_tangent(unzoomed_angle);
+ native_tangent = tanf(native_vertical_field_of_view * 0.5f);
+ if (requested_tangent < unzoomed_tangent)
+ {
+ /* (a view narrower than the stock one: the zoom narrows it further) */
+ adjusted_tangent = native_tangent * (requested_tangent / unzoomed_tangent);
+ }
+ else
+ {
+ real blend = 1.0f;
+
+ weapon_index = unit_inventory_get_weapon(unit_index, unit->unit.current_weapon_index);
+ if (weapon_index != NONE)
+ {
+ real scoped_angle = weapon_get_field_of_view(weapon_index, unzoomed_angle, 0);
+
+ if (scoped_angle > 0.0f && scoped_angle < unzoomed_angle)
+ {
+ real scoped_tangent = 0.75f * render_camera_get_adjusted_field_of_view_tangent(scoped_angle);
+ /* (a scope's full zoom keeps its stock angle exactly: the
+ observer's arctangent and tangent can land just above it) */
+ if (native_tangent <= scoped_tangent * 1.000001f)
+ return native_vertical_field_of_view;
+
+ /* (the extra width fades out along the scope's own
+ transition, so every zoom level reached is the stock view) */
+ blend = PIN((native_tangent - scoped_tangent) /
+ (unzoomed_tangent - scoped_tangent), 0.0f, 1.0f);
+ }
+ }
+ if (blend == 0.0f)
+ return native_vertical_field_of_view;
+ adjusted_tangent = native_tangent + (requested_tangent - unzoomed_tangent) * blend;
+ }
+ return 2.0f * atanf(adjusted_tangent);
+}
+
+real render_fov_vertical(short local_player_index, real native_vertical_field_of_view)
+{
+ real adjusted = render_fov_adjust(local_player_index, native_vertical_field_of_view);
+
+ if (local_player_index >= 0 && local_player_index < MAXIMUM_LOCAL_PLAYERS)
+ {
+ real scale = 1.0f;
+
+ if (adjusted != native_vertical_field_of_view &&
+ native_vertical_field_of_view > 0.0f && native_vertical_field_of_view < _pi &&
+ adjusted > 0.0f && adjusted < _pi)
+ {
+ scale = tanf(native_vertical_field_of_view * 0.5f) / tanf(adjusted * 0.5f);
+ if (!(scale > 0.0f && scale < 1000.0f))
+ scale = 1.0f;
+ }
+ /* (the view's projection, the zoom's transition too, for the HUD:
+ the weapon's own projection, viewmodel_projection_begin, is not it) */
+ reticle_scales[local_player_index] = scale;
+ /* (a widened view's own angle, which the weapon keeps by default) */
+ authored_vertical[local_player_index] =
+ adjusted != native_vertical_field_of_view ? native_vertical_field_of_view : 0.0f;
+ }
+ return adjusted;
+}
+
+real render_fov_authored_vertical(short local_player_index)
+{
+ if (local_player_index < 0 || local_player_index >= MAXIMUM_LOCAL_PLAYERS)
+ return 0.0f;
+ return authored_vertical[local_player_index];
+}
+
+real render_fov_reticle_scale(short local_player_index)
+{
+ if (local_player_index < 0 || local_player_index >= MAXIMUM_LOCAL_PLAYERS ||
+ reticle_scales[local_player_index] == 0.0f)
+ {
+ return 1.0f;
+ }
+ return reticle_scales[local_player_index];
+}
+
+/* ---------- the first-person weapon's */
+
+/* how deep the weapon's passes nest, and whether the outermost changed the
+view (the cameras and frustums it saved) */
+static unsigned long projection_depth;
+static boolean projection_applied;
+static struct render_camera saved_render_camera, saved_rasterizer_camera;
+static struct render_frustum saved_render_frustum, saved_rasterizer_frustum;
+
+static real viewmodel_vertical(void)
+{
+ static boolean initialized;
+ static unsigned long read_at;
+ static real angle;
+ unsigned long changes = config_changes();
+
+ if (!initialized || read_at != changes)
+ {
+ double degrees = config_real("display.viewmodel_fov");
+
+ angle = degrees >= 20.0 && degrees <= 150.0 ?
+ (real)(2.0 * atan(tan(degrees * _pi / 360.0) * (9.0 / 16.0))) : 0.0f;
+ initialized = TRUE;
+ read_at = changes;
+ }
+ return angle;
+}
+
+void viewmodel_projection_begin(void)
+{
+ real angle;
+ real_rectangle2d render_bounds, rasterizer_bounds;
+
+ if (projection_depth++ != 0)
+ return;
+ projection_applied = FALSE;
+ /* (display.viewmodel_fov's angle; by default the view's own, from before
+ display.fov widened it: arms and a gun right against the camera stretch
+ at a wide angle) */
+ angle = viewmodel_vertical();
+ if (!angle)
+ angle = render_fov_authored_vertical(render.local_player_index);
+ if (!angle || render.local_player_index < 0 || render.local_player_index >= MAXIMUM_LOCAL_PLAYERS ||
+ global_window_parameters.rasterizer_target != _rasterizer_target_render_primary ||
+ cinematic_in_progress() || (director_camera_scripted && *director_camera_scripted) ||
+ director_get_perspective(render.local_player_index) != _director_perspective_first_person ||
+ director_inhibited_facing(render.local_player_index))
+ {
+ return;
+ }
+
+ saved_render_camera = render.camera;
+ saved_render_frustum = render.frustum;
+ saved_rasterizer_camera = global_window_parameters.camera;
+ saved_rasterizer_frustum = global_window_parameters.frustum;
+ /* (the frustums' own bounds, the view's crop of a split screen: the
+ visibility and the projection change together, the weapon's pose and
+ markers do not; get_projection_bounds' slopes are not bounds) */
+ render_bounds = saved_render_frustum.frustum_bounds;
+ rasterizer_bounds = saved_rasterizer_frustum.frustum_bounds;
+ render.camera.vertical_field_of_view = angle;
+ global_window_parameters.camera.vertical_field_of_view = angle;
+ render_camera_build_frustum(&render.camera, &render_bounds, &render.frustum, TRUE);
+ render_camera_build_frustum(&global_window_parameters.camera, &rasterizer_bounds,
+ &global_window_parameters.frustum, TRUE);
+ projection_applied = TRUE;
+ rasterizer_set_frustum_z(0.0f, 0.0f);
+}
+
+void viewmodel_projection_end(void)
+{
+ if (!projection_depth || --projection_depth || !projection_applied)
+ return;
+ render.camera = saved_render_camera;
+ render.frustum = saved_render_frustum;
+ global_window_parameters.camera = saved_rasterizer_camera;
+ global_window_parameters.frustum = saved_rasterizer_frustum;
+ projection_applied = FALSE;
+ rasterizer_set_frustum_z(0.0f, 0.0f);
+}
+
+/* ---------- whether the first-person weapon is drawn */
+
+boolean viewmodel_is_visible(void)
+{
+ static boolean initialized, visible;
+ static unsigned long read_at;
+ unsigned long changes = config_changes();
+
+ if (!initialized || read_at != changes)
+ {
+ visible = config_boolean("display.viewmodel_visible") != 0;
+ initialized = TRUE;
+ read_at = changes;
+ }
+ return visible;
+}
+
+boolean viewmodel_draws_geometry(boolean first_person)
+{
+ return !first_person || viewmodel_is_visible();
+}
diff --git a/port/linux/game/view_fov.h b/port/linux/game/view_fov.h
new file mode 100644
index 00000000..6f410e0a
--- /dev/null
+++ b/port/linux/game/view_fov.h
@@ -0,0 +1,31 @@
+/*
+VIEW_FOV.H
+
+The first-person view's field of view and weapon (view_fov.c).
+*/
+
+#ifndef VIEW_FOV_H
+#define VIEW_FOV_H
+
+/* the vertical angle the local player's world view is drawn at (display.fov,
+after the observer and before the projection and the visibility frustum
+are built), from the game's own */
+real render_fov_vertical(short local_player_index, real native_vertical_field_of_view);
+/* how much the reticle shrinks or grows to stay on its aim at that view (the
+last local view's own projection against the game's): 1 for the stock view */
+real render_fov_reticle_scale(short local_player_index);
+/* the view's own vertical angle when display.fov widened it, else 0 */
+real render_fov_authored_vertical(short local_player_index);
+
+/* the first-person weapon's projection (display.viewmodel_fov) around its
+passes: balanced and nestable, the current local render view only */
+void viewmodel_projection_begin(void);
+void viewmodel_projection_end(void);
+
+/* whether the first-person weapon, hands and attached visuals are drawn
+(display.viewmodel_visible); its firing, sounds and lights go on either way */
+boolean viewmodel_is_visible(void);
+/* whether a pass draws: not one of the first-person weapon's that is hidden */
+boolean viewmodel_draws_geometry(boolean first_person);
+
+#endif
diff --git a/port/linux/game/viewmodel_fov.c b/port/linux/game/viewmodel_fov.c
deleted file mode 100644
index d049a836..00000000
--- a/port/linux/game/viewmodel_fov.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "cseries.h"
-#include "viewmodel_fov.h"
-#include "render_fov.h"
-#include "camera/director.h"
-#include "cutscene/cinematics.h"
-#include "game/players.h"
-#include "render/render.h"
-#include "render/render_cameras.h"
-#include "render/render_cameras_internal.h"
-#include "rasterizer/rasterizer.h"
-#include "rasterizer/xbox/rasterizer_xbox_internal.h"
-#include
-
-double config_real(const char *name);
-unsigned long config_changes(void);
-
-static unsigned projection_depth;
-static boolean projection_applied;
-static struct render_camera saved_render_camera, saved_rasterizer_camera;
-static struct render_frustum saved_render_frustum, saved_rasterizer_frustum;
-
-static real viewmodel_vertical(void)
-{
- static boolean initialized;
- static unsigned long read_at;
- static real angle;
- unsigned long changes = config_changes();
- if (!initialized || read_at != changes)
- {
- double degrees = config_real("display.viewmodel_fov");
- angle = isfinite(degrees) && degrees >= 20.0 && degrees <= 150.0 ?
- (real)(2.0 * atan(tan(degrees * 3.14159265358979323846 / 360.0) * (9.0 / 16.0))) : 0.0f;
- initialized = TRUE;
- read_at = changes;
- }
- return angle;
-}
-
-void viewmodel_projection_begin(void)
-{
- real angle;
- real_rectangle2d render_bounds, rasterizer_bounds;
- if (projection_depth++ != 0) return;
- projection_applied = FALSE;
- angle = viewmodel_vertical();
- /* Default keeps the weapon at this frame's own angle. A chosen angle
- is that FOV and is left as it is. A wide world view stretches arms
- and a gun that sit against the camera, so Default does not follow it. */
- if (!angle)
- angle = render_fov_authored_vertical(render.local_player_index);
- if (!angle || render.local_player_index < 0 || render.local_player_index >= MAXIMUM_LOCAL_PLAYERS ||
- global_window_parameters.rasterizer_target != 0 /* primary view */ ||
- cinematic_in_progress() || (director_camera_scripted && *director_camera_scripted) ||
- director_get_perspective(render.local_player_index) != _director_perspective_first_person ||
- director_inhibited_facing(render.local_player_index)) return;
-
- saved_render_camera = render.camera;
- saved_render_frustum = render.frustum;
- saved_rasterizer_camera = global_window_parameters.camera;
- saved_rasterizer_frustum = global_window_parameters.frustum;
- /* Retain cropped/tiled viewport bounds. CPU visibility and GPU projection
- change together; pose, weapon markers and gameplay values stay put. */
- /* The builder takes normalized crop bounds. get_projection_bounds instead
- returns signed view-space ray slopes, which would invert/rescale the view. */
- render_bounds = saved_render_frustum.frustum_bounds;
- rasterizer_bounds = saved_rasterizer_frustum.frustum_bounds;
- render.camera.vertical_field_of_view = angle;
- global_window_parameters.camera.vertical_field_of_view = angle;
- render_camera_build_frustum(&render.camera, &render_bounds, &render.frustum, TRUE);
- render_camera_build_frustum(&global_window_parameters.camera, &rasterizer_bounds,
- &global_window_parameters.frustum, TRUE);
- projection_applied = TRUE;
- rasterizer_set_frustum_z(0.0f, 0.0f);
-}
-
-void viewmodel_projection_end(void)
-{
- if (!projection_depth || --projection_depth || !projection_applied) return;
- render.camera = saved_render_camera;
- render.frustum = saved_render_frustum;
- global_window_parameters.camera = saved_rasterizer_camera;
- global_window_parameters.frustum = saved_rasterizer_frustum;
- projection_applied = FALSE;
- rasterizer_set_frustum_z(0.0f, 0.0f);
-}
diff --git a/port/linux/game/viewmodel_fov.h b/port/linux/game/viewmodel_fov.h
deleted file mode 100644
index f3fc9471..00000000
--- a/port/linux/game/viewmodel_fov.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef VIEWMODEL_FOV_H
-#define VIEWMODEL_FOV_H
-/* Balanced, nestable scopes change only the current local render view. */
-void viewmodel_projection_begin(void);
-void viewmodel_projection_end(void);
-#endif
diff --git a/port/linux/game/viewmodel_visibility.c b/port/linux/game/viewmodel_visibility.c
deleted file mode 100644
index 09f8d860..00000000
--- a/port/linux/game/viewmodel_visibility.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "viewmodel_visibility.h"
-
-int config_boolean(const char *name);
-unsigned long config_changes(void);
-
-int viewmodel_is_visible(void)
-{
- static int initialized, visible;
- static unsigned long read_at;
- unsigned long changes = config_changes();
- if (!initialized || read_at != changes)
- {
- visible = config_boolean("display.viewmodel_visible");
- initialized = 1;
- read_at = changes;
- }
- return visible;
-}
-
-int viewmodel_draws_geometry(int first_person)
-{
- return !first_person || viewmodel_is_visible();
-}
diff --git a/port/linux/game/viewmodel_visibility.h b/port/linux/game/viewmodel_visibility.h
deleted file mode 100644
index 40e08b6b..00000000
--- a/port/linux/game/viewmodel_visibility.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef VIEWMODEL_VISIBILITY_H
-#define VIEWMODEL_VISIBILITY_H
-/* Display only: weapon updates, sounds, gameplay and world lights continue. */
-int viewmodel_is_visible(void);
-int viewmodel_draws_geometry(int first_person);
-#endif
diff --git a/port/linux/include/math.h b/port/linux/include/math.h
index 84d84dc3..63f92edc 100644
--- a/port/linux/include/math.h
+++ b/port/linux/include/math.h
@@ -11,12 +11,6 @@ strnlen() cannot collide with the game's own), which hides glibc's M_*.
#include_next
-/* glibc hides the C99 classification macros in the game's ISO C89 mode.
-Use the compiler's classification, not a call to a nonexistent libm symbol. */
-#ifndef isfinite
-#define isfinite(value) __builtin_isfinite(value)
-#endif
-
#ifndef M_PI
#define M_E 2.71828182845904523536
#define M_LOG2E 1.44269504088896340736
diff --git a/port/linux/src/port_config.c b/port/linux/src/port_config.c
index d4457cc3..83254e68 100644
--- a/port/linux/src/port_config.c
+++ b/port/linux/src/port_config.c
@@ -113,15 +113,16 @@ static const struct config_setting config_settings[] =
"where the last tick left it: the view turns the frame the mouse moves,\n"
"not up to two ticks (66 ms) later." },
{ "display.fov", _config_real, "0.0", "HALO_FOV", _environment_value, _platform_all,
- "On-foot first-person horizontal FOV at 16:9, in degrees (20-150);\n"
- "0 keeps the authored view. Other cameras keep their own FOV." },
+ "The first-person view's field of view on foot, in degrees across at\n"
+ "16:9 (20 to 150); 0 keeps the stock view. Vehicles, cinematics and\n"
+ "scripted cameras keep their own." },
{ "display.viewmodel_fov", _config_real, "0.0", "HALO_VIEWMODEL_FOV", _environment_value, _platform_all,
- "Weapon and hands horizontal FOV at 16:9, in degrees (20 to 150);\n"
- "0 is Default and keeps the original weapon view. A chosen angle is\n"
- "that FOV. Attached visuals use the same projection." },
- { "display.viewmodel_visible", _config_boolean, "true", "HALO_VIEWMODEL_VIS", _environment_value, _platform_all,
- "Draw the first-person weapon, hands and attached visuals. Turning\n"
- "this off does not change firing, animation, sound or world lights." },
+ "The first-person weapon's and hands' field of view, in degrees across\n"
+ "at 16:9 (20 to 150); 0 keeps the weapon's stock view, also when\n"
+ "display.fov widens the world." },
+ { "display.viewmodel_visible", _config_boolean, "true", "HALO_VIEWMODEL_VISIBLE", _environment_value, _platform_all,
+ "Draw the first-person weapon, hands and what is attached to them.\n"
+ "Off, they are not drawn; firing, animation, sound and lights go on." },
{ "display.high_res_hud", _config_boolean, "true", "HALO_HIGH_RES_HUD", _environment_value, _platform_all,
"Draw the HUD (meters, counters, panels, motion sensor, reticles,\n"
"waypoints, scopes) from the high-res assets (8x the maps' bitmaps);\n"
diff --git a/source/interface/first_person_weapons.c b/source/interface/first_person_weapons.c
index de7df2fa..733f71cf 100644
--- a/source/interface/first_person_weapons.c
+++ b/source/interface/first_person_weapons.c
@@ -100,7 +100,6 @@ symbols in this file:
#define REAL_MATH_EXTERNAL_REAL_LOCAL_RANDOM
#define REAL_MATH_EXTERNAL_REAL_LOCAL_RANDOM_RANGE
#include "interface/first_person_weapons.h"
-#include "viewmodel_visibility.h"
#include "cache/predicted_resources.h"
#include "camera/director.h"
@@ -125,6 +124,7 @@ symbols in this file:
#include "sound/game_sound.h"
#include "sound/sound_manager.h"
#include "units/units.h"
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -470,6 +470,7 @@ long first_person_weapon_get_local_index(
void first_person_weapon_draw(
void)
{
+ /* port: not drawn with display.viewmodel_visible off (view_fov.c) */
if (!viewmodel_is_visible())
return;
if (render.local_player_index!=NONE)
diff --git a/source/interface/hud_draw.c b/source/interface/hud_draw.c
index ff62d705..4e6436f2 100644
--- a/source/interface/hud_draw.c
+++ b/source/interface/hud_draw.c
@@ -95,7 +95,6 @@ symbols in this file:
#include "game/players.h"
#include "interface/hud_definitions.h"
#include "interface/hud_draw.h"
-#include "render_fov.h"
#include "interface/interface.h"
#include "interface/unit_hud_interface_definition.h"
#include "items/weapon_definitions.h"
@@ -107,6 +106,7 @@ symbols in this file:
#include "units/units.h"
#include "cache_file_formats.h" /* port: port/linux/game/cache_file_formats.c */
#include "custom_edition_cache.h"
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -397,7 +397,7 @@ static void hud_draw_bitmap_internal(
real_vector2d const *xy_scale,
real theta,
pixel32 color,
- real reticle_scale);
+ real reticle_scale); /* port: (display.fov, view_fov.c) */
static void hud_draw_bitmap_with_meter(
void *meter_parameters,
struct bitmap_data const *bitmap,
@@ -1592,8 +1592,9 @@ static void hud_draw_bitmap_internal(
real center_y = (render.camera.window_bounds.y1 + render.camera.window_bounds.y0) / 2 -
render.camera.viewport_bounds.y0;
- /* Transform the complete authored reticle about its aiming anchor:
- * offsets and separate sprites must shrink along with their artwork. */
+ /* port: the reticle scaled about the view's centre, where it aims,
+ with display.fov (view_fov.c): its offsets and separate pieces
+ shrink with its picture */
for (vertex_index = 0; vertex_index < 4; vertex_index++)
{
vertices[vertex_index].position.x = center_x +
@@ -1687,6 +1688,7 @@ static void hud_draw_bitmap_with_meter(
&xy_scale,
theta,
color,
+ /* port: a reticle at the centre keeps to its aim (view_fov.c) */
is_crosshair_bitmap && absolute_placement->corner == _hud_anchor_center ?
render_fov_reticle_scale(render.local_player_index) : 1.0f);
diff --git a/source/interface/hud_weapon.c b/source/interface/hud_weapon.c
index 058a4bfc..4462270e 100644
--- a/source/interface/hud_weapon.c
+++ b/source/interface/hud_weapon.c
@@ -1292,6 +1292,7 @@ static void crosshairs_draw(
color,
in_multiplayer,
interface_bitmap,
+ /* port: not scaled with display.fov (view_fov.c) */
FALSE);
}
else
@@ -1308,7 +1309,9 @@ static void crosshairs_draw(
color,
in_multiplayer,
bitmap_group->type == _bitmap_group_type_interface_bitmaps,
- /* Scope artwork keeps its authored layout. */
+ /* port: a reticle, scaled with display.fov
+ (view_fov.c); a scope's picture keeps its
+ place */
state_index != _crosshair_state_zoom);
}
}
diff --git a/source/main/main.c b/source/main/main.c
index 3ea113d5..db4a3210 100644
--- a/source/main/main.c
+++ b/source/main/main.c
@@ -393,7 +393,7 @@ symbols in this file:
#include "text/font_group.h"
#include "tag_files/files.h"
#include "custom_edition_cache.h" /* port: custom_edition_level_name */
-#include "render_fov.h" /* port: local world FOV, before projection and culling */
+#include "view_fov.h" /* port: display.fov, before the projection and culling */
#if defined(HALO_WINDOWS) || defined(HALO_ANDROID) || defined(__linux__)
#define HALO_NATIVE_BUILD_INFO 1
@@ -1152,6 +1152,7 @@ void set_window_camera_values(
window->rasterizer_camera.position = observer->position;
window->rasterizer_camera.forward = observer->forward;
window->rasterizer_camera.up = observer->up;
+ /* port: display.fov's view, the local render view only (view_fov.c) */
window->rasterizer_camera.vertical_field_of_view =
render_fov_vertical(window->local_player_index, 2.0f * arctangent(
0.75f * render_camera_get_adjusted_field_of_view_tangent(
diff --git a/source/rasterizer/rasterizer_lights.c b/source/rasterizer/rasterizer_lights.c
index ef91f729..61662307 100644
--- a/source/rasterizer/rasterizer_lights.c
+++ b/source/rasterizer/rasterizer_lights.c
@@ -81,8 +81,6 @@ symbols in this file:
/* ---------- headers */
#include "cseries.h"
-#include "viewmodel_fov.h"
-#include "viewmodel_visibility.h"
#include "errors.h"
#include "bitmaps/bitmaps.h"
#include "interface/hud_draw.h"
@@ -104,6 +102,7 @@ symbols in this file:
#include
#include "rasterizer/xbox/rasterizer_xbox.h"
#include "main/main.h"
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -548,7 +547,8 @@ void rasterizer_lens_flare_submit(
268,
(parameters->compressed_window_index&_lens_flare_window_index_mask)==global_window_parameters.window_index);
- if (!viewmodel_draws_geometry(parameters->compressed_window_index & _lens_flare_first_person_weapon_flag))
+ /* port: not the first-person weapon's with it hidden (view_fov.c) */
+ if (!viewmodel_draws_geometry((parameters->compressed_window_index & _lens_flare_first_person_weapon_flag) != 0))
return;
if (rasterizer_debug_options.draw_lens_flares && !screenshot_in_progress() &&
global_window_parameters.rasterizer_target==_rasterizer_target_render_primary)
@@ -568,12 +568,15 @@ void rasterizer_lens_flare_submit(
screen): its occlusion test would count no pixels, so it would not
be drawn, and a level of many lights (Halo PC's maps) tested
hundreds a frame, each a draw of its own (the sphere takes in the
- test's offset point and size, rasterizer_lens_flares_submit_occlusion_tests) */
+ test's offset point and size, rasterizer_lens_flares_submit_occlusion_tests).
+ Not the first-person weapon's: it is drawn at the weapon's own
+ projection (display.viewmodel_fov, view_fov.c), not this frustum's */
if ((parameters->definition->far_fade_distance==0.0f ||
camera_distancedefinition->far_fade_distance) &&
(parameters->compressed_light_color&LENS_FLARE_LIGHT_COLOR_ALPHA_MASK)>0 &&
+ ((parameters->compressed_window_index&_lens_flare_first_person_weapon_flag) ||
render_frustum_sphere_visible(&global_window_parameters.frustum, ¶meters->position,
- 3.0f * parameters->definition->occlusion_radius))
+ 3.0f * parameters->definition->occlusion_radius)))
{
struct rasterizer_lens_flare_submit_parameters *lens_flare_parameters=
lens_flare_parameters_get((short)local_lens_flare_count++);
@@ -861,11 +864,15 @@ void rasterizer_lens_flares_submit_occlusion_tests(
if ((lens_flare_parameters->compressed_window_index & _lens_flare_window_index_mask) ==
global_window_parameters.window_index)
{
- boolean first_person = (lens_flare_parameters->compressed_window_index & _lens_flare_first_person_weapon_flag) != 0;
- if (first_person) viewmodel_projection_begin();
+ boolean first_person = (lens_flare_parameters->compressed_window_index &
+ _lens_flare_first_person_weapon_flag) != 0;
real occlusion_radius = definition->occlusion_radius;
real_point3d occlusion_point;
+ /* port: the first-person weapon's projection (view_fov.c) */
+ if (first_person)
+ viewmodel_projection_begin();
+
switch (definition->occlusion_offset_direction)
{
case _lens_flare_occlusion_offset_direction_toward_viewer:
@@ -900,7 +907,8 @@ void rasterizer_lens_flares_submit_occlusion_tests(
occlusion_radius,
lens_flare_index);
- if (first_person) viewmodel_projection_end();
+ if (first_person)
+ viewmodel_projection_end();
}
}
@@ -935,10 +943,14 @@ void rasterizer_lens_flares_draw(
if ((lens_flare_parameters->compressed_window_index & _lens_flare_window_index_mask) ==
global_window_parameters.window_index)
{
- boolean first_person = (lens_flare_parameters->compressed_window_index & _lens_flare_first_person_weapon_flag) != 0;
- if (first_person) viewmodel_projection_begin();
+ boolean first_person = (lens_flare_parameters->compressed_window_index &
+ _lens_flare_first_person_weapon_flag) != 0;
struct lens_flare_definition *definition = lens_flare_parameters->definition;
+ /* port: the first-person weapon's projection (view_fov.c) */
+ if (first_person)
+ viewmodel_projection_begin();
+
if (lens_flare_parameters->internal__occlusion_pixels > 0 &&
LENS_FLARE_LIGHT_COLOR_ALPHA(lens_flare_parameters->compressed_light_color) > 0 &&
definition->reflections.count > 0)
@@ -1180,7 +1192,8 @@ void rasterizer_lens_flares_draw(
}
}
- if (first_person) viewmodel_projection_end();
+ if (first_person)
+ viewmodel_projection_end();
}
}
diff --git a/source/rasterizer/rasterizer_transparent_geometry.c b/source/rasterizer/rasterizer_transparent_geometry.c
index f5534842..f5154ee3 100644
--- a/source/rasterizer/rasterizer_transparent_geometry.c
+++ b/source/rasterizer/rasterizer_transparent_geometry.c
@@ -83,7 +83,6 @@ symbols in this file:
/* ---------- headers */
#include "cseries.h"
-#include "viewmodel_fov.h"
#include "cseries/errors.h"
#include "rasterizer.h"
#include "rasterizer_console_vars.h"
@@ -93,6 +92,7 @@ symbols in this file:
#include "rasterizer/xbox/rasterizer_xbox_state.h"
#include "shaders/shader_definitions.h"
#include "shaders/shaders.h"
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -587,6 +587,7 @@ void rasterizer_transparent_geometry_draw(
global_window_parameters.rasterizer_target==_rasterizer_target_render_primary);
if (!first_person_flag)
{
+ /* port: the first-person weapon's projection (view_fov.c) */
viewmodel_projection_begin();
rasterizer_set_stencil_mode(0);
rasterizer_set_frustum_z(
@@ -615,7 +616,7 @@ void rasterizer_transparent_geometry_draw(
rasterizer_debug_options.transparent_pixel_counter_active = FALSE;
if (first_person_flag)
{
- viewmodel_projection_end();
+ viewmodel_projection_end(); /* port: (view_fov.c) */
rasterizer_set_frustum_z(0.0f, 0.0f);
}
}
diff --git a/source/rasterizer/xbox/rasterizer_xbox_models.c b/source/rasterizer/xbox/rasterizer_xbox_models.c
index e2135da0..f205c9f8 100644
--- a/source/rasterizer/xbox/rasterizer_xbox_models.c
+++ b/source/rasterizer/xbox/rasterizer_xbox_models.c
@@ -111,7 +111,6 @@ symbols in this file:
#include "rasterizer/rasterizer_models.h"
#include "rasterizer/rasterizer_transparent_geometry.h"
#include "render/render.h"
-#include "viewmodel_fov.h"
#include "shaders/shader_definitions.h"
#include "shaders/shaders.h"
@@ -124,6 +123,7 @@ symbols in this file:
#include "rasterizer/xbox/rasterizer_xbox_draw_primitives.h"
#include "rasterizer/xbox/rasterizer_xbox_internal.h"
#include "rasterizer/xbox/rasterizer_xbox_models.h"
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -616,7 +616,7 @@ void _rasterizer_model_end(
!local_do_not_change_z_stencil_states)
{
rasterizer_set_stencil_mode(RASTERIZER_STENCIL_MODE_REJECT);
- viewmodel_projection_end();
+ viewmodel_projection_end(); /* port: (view_fov.c) */
rasterizer_set_frustum_z(0.0f, 0.0f);
}
local_parameters = NULL;
@@ -645,6 +645,7 @@ void _rasterizer_model_begin(
!do_not_change_z_stencil_states)
{
rasterizer_set_stencil_mode(RASTERIZER_STENCIL_MODE_WRITE);
+ /* port: the first-person weapon's projection (view_fov.c) */
viewmodel_projection_begin();
rasterizer_set_frustum_z(
rasterizer_globals.first_person_weapon_near_clip_distance,
diff --git a/source/render/render_particles.c b/source/render/render_particles.c
index 9d71f4e2..cfce7009 100644
--- a/source/render/render_particles.c
+++ b/source/render/render_particles.c
@@ -22,7 +22,6 @@ symbols in this file:
#include "effects/particles.h"
#include "game/players.h"
#include "interface/first_person_weapons.h"
-#include "viewmodel_visibility.h"
#include "render.h"
#include "render_cameras_internal.h"
#include "render_particles.h"
@@ -30,6 +29,7 @@ symbols in this file:
#include "tag_files/tag_groups.h"
#include "units/unit_definitions.h"
#include "units/units.h"
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -160,6 +160,7 @@ void render_particles(
boolean owned_by_local_player =
particle->local_player_index == local_player_index;
+ /* port: not the first-person weapon's with it hidden (view_fov.c) */
if (render_location_visible(&particle->location) &&
viewmodel_draws_geometry(owned_by_local_player &&
TEST_FLAG(particle->flags, _particle_datum_dont_draw_third_person_bit)) &&
diff --git a/source/render/render_sprite.c b/source/render/render_sprite.c
index f3c31a95..a622cb63 100644
--- a/source/render/render_sprite.c
+++ b/source/render/render_sprite.c
@@ -76,7 +76,6 @@ symbols in this file:
/* ---------- headers */
#include "cseries/cseries.h"
-#include "viewmodel_fov.h"
#include "bitmaps/bitmap_group.h"
#include "cseries/errors.h"
#include "interface/hud_draw.h"
@@ -91,6 +90,7 @@ symbols in this file:
#include "tag_files/tag_files.h"
#include "tag_files/tag_groups.h"
#include "custom_edition_cache.h" /* port: port/linux/game/custom_edition_cache.c */
+#include "view_fov.h" /* port: port/linux/game/view_fov.c */
/* ---------- constants */
@@ -215,6 +215,7 @@ void build_sprites_begin(
!TEST_FLAG(flags, _build_sprites_valid_bit));
data->bitmap_group_index = bitmap_group_index;
+ /* port: the first-person weapon's projection (view_fov.c) */
if (TEST_FLAG(flags, _build_sprites_first_person_bit))
viewmodel_projection_begin();
data->flags = flags;
@@ -286,6 +287,7 @@ void build_sprites_end(
}
SET_FLAG(data->flags, _build_sprites_valid_bit, FALSE);
+ /* port: (view_fov.c) */
if (TEST_FLAG(data->flags, _build_sprites_first_person_bit))
viewmodel_projection_end();
return;
diff --git a/tools/port_settings.py b/tools/port_settings.py
index 0fb941f9..944783f6 100644
--- a/tools/port_settings.py
+++ b/tools/port_settings.py
@@ -191,15 +191,15 @@ _video["rows"] = [row for row in _video["rows"] if row[1] not in _graphics]
_video["categories"] = [
("GRAPHICS:", "video_settings/graphics", "The HUD, text, anti-aliasing, shadows and\nlighting."),
("FOV AND VIEWMODELS:", "video_settings/fov_viewmodels",
- "Optional field of view and first-person weapon\ndisplay settings. Defaults keep the original view."),
+ "The field of view and the first-person\nweapon. Their defaults keep the stock view."),
]
SCREENS["video_settings/fov_viewmodels"] = {
"screen": "fov_viewmodel_settings_screen", "header": _video["header"], "spacing": 30,
"rows": [
("FOV:", "display.fov", [("DEFAULT", "0")] + [(str(n), str(n)) for n in range(80, 151, 5)],
- "On-foot horizontal FOV at 16:9, in degrees.\nDefault keeps the authored view and scopes.", None),
+ "On foot, horizontal at 16:9, in degrees.\nDefault keeps the stock view.", None),
("VIEWMODEL FOV:", "display.viewmodel_fov", [("DEFAULT", "0")] + [(str(n), str(n)) for n in range(80, 151, 5)],
- "Weapon and hands horizontal FOV at 16:9, in degrees.\nA number sets that FOV. Default keeps the original weapon view.", None),
+ "The weapon and hands, horizontal at 16:9.\nDefault keeps the weapon's stock view.", None),
("VIEWMODELS:", "display.viewmodel_visible", ON_OFF,
"Draw first-person weapons, hands and attached\nvisuals. Gameplay and sound continue when off.", None),
],