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 faf580b8..b403333f 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
@@ -16,6 +16,7 @@
+
@@ -50,6 +51,15 @@
+
+
+
+
+
+
+
+
+
@@ -64,11 +74,13 @@
+
+
diff --git a/port/linux/README.md b/port/linux/README.md
index 34e28bd0..1d105042 100644
--- a/port/linux/README.md
+++ b/port/linux/README.md
@@ -339,6 +339,7 @@ the setting for one start of the game. It has priority over the file.
| `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.viewmodel_shield` | `false` | `HALO_VIEWMODEL_SHIELD` | `true`: the energy shield's flare (its hits, its charging, its fall) is drawn on the first-person arms too, as on the body, with the unit's own shield shader. The stock game draws it on the body only. |
| `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; the menus' titles are drawn from the high-res pictures in `port/assets/titles`, and the controller button icons from those in `port/assets/buttons`. `false`: the maps' bitmap fonts, titles and button icons. |
| `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. |
@@ -1046,6 +1047,7 @@ Other changes:
| `render/render.c` | The 3D view of each window is antialiased before the HUD is drawn (`display.anti_aliasing`). |
| `interface/hud.c` | In multiplayer, players' names are drawn above their heads (`display.player_names`, `display.player_name_scale`). |
| `rasterizer/rasterizer_text.c`, `text/draw_string.c` | Text is drawn from an atlas of the fonts' glyphs, rasterized at the resolution the game draws at (`src/text_hires.c`), when the font has every character of the string. Text can be drawn scaled about a point (`rasterizer_text_set_scale`), as the players' names are. Each glyph's advance is centred on the font tag character's, so the layout is the same, and a glyph is cut at a text box only where the font tag's character visibly was. |
+| `interface/first_person_weapons.c` | The first-person hands are drawn with the unit's shield modifier shader, as its body is (`display.viewmodel_shield`). |
The x86 inline assembly of the game is replaced by C. Thus the compiler
can optimize that code for each processor:
diff --git a/port/linux/game/view_fov.c b/port/linux/game/view_fov.c
index c6f3f6ac..2c0241de 100644
--- a/port/linux/game/view_fov.c
+++ b/port/linux/game/view_fov.c
@@ -263,6 +263,23 @@ boolean viewmodel_is_visible(void)
return visible;
}
+/* ---------- whether the energy shield's flare is drawn on the arms */
+
+boolean viewmodel_shield_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_shield") != 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
index 6f410e0a..de4dcec5 100644
--- a/port/linux/game/view_fov.h
+++ b/port/linux/game/view_fov.h
@@ -25,6 +25,9 @@ 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);
+/* display.viewmodel_shield: the unit's energy shield flare drawn on the
+first-person arms too, as on its body */
+boolean viewmodel_shield_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);
diff --git a/port/linux/src/port_config.c b/port/linux/src/port_config.c
index 32fe5b1f..e225c293 100644
--- a/port/linux/src/port_config.c
+++ b/port/linux/src/port_config.c
@@ -295,6 +295,9 @@ static const struct config_setting config_settings[] =
"as CUSTOM SINGLEPLAYER and CUSTOM MULTIPLAYER. Their tags are checked\n"
"as the game's own maps' are before they run; false refuses them\n"
"(docs/custom_edition_caches.md)." },
+ { "display.viewmodel_shield", _config_boolean, "false", "HALO_VIEWMODEL_SHIELD", _environment_value, _platform_all,
+ "The energy shield's flare on the first-person arms too, as on the body\n"
+ "(the stock game draws it on the body only)." },
{ "paths.data", _config_string, "\"\"", "HALO_DATA_ROOT", _environment_value, _platform_desktop,
"The folder holding the game data's maps folder; empty looks in the\n"
diff --git a/source/interface/first_person_weapons.c b/source/interface/first_person_weapons.c
index 733f71cf..025b2f56 100644
--- a/source/interface/first_person_weapons.c
+++ b/source/interface/first_person_weapons.c
@@ -125,6 +125,8 @@ symbols in this file:
#include "sound/sound_manager.h"
#include "units/units.h"
#include "view_fov.h" /* port: port/linux/game/view_fov.c */
+#include "shaders/shader_definitions.h" /* port: (the shield's flare on the arms) */
+#include "shaders/shaders.h"
/* ---------- constants */
@@ -544,6 +546,26 @@ void first_person_weapon_draw(
FLAG(_render_model_first_person_bit));
}
+ /* port: the shield's flare on the arms as on the body, the
+ unit's own modifier shader (display.viewmodel_shield,
+ view_fov.c); the weapon above is drawn without it */
+ if (viewmodel_shield_is_visible())
+ {
+ struct object_definition *unit_definition= object_definition_get(object_get(unit_index)->definition_index);
+
+ if (unit_definition->object.modifier_shader.index!=NONE)
+ {
+ struct shader *modifier_shader= shader_definition_get(unit_definition->object.modifier_shader.index);
+
+ if (shader_type_is_valid_for_modifier(modifier_shader->base.type))
+ {
+ model_effect.modifier_shader= modifier_shader;
+ model_effect.modifier_animation.colors= unit->object.outgoing_change_colors;
+ model_effect.modifier_animation.values= unit->object.outgoing_function_values;
+ }
+ }
+ }
+
if (first_person_weapon->hands_node_remapping_table_valid &&
first_person_interface->hands.index!=NONE)
{
diff --git a/tools/port_settings.py b/tools/port_settings.py
index 944783f6..729e7ae6 100644
--- a/tools/port_settings.py
+++ b/tools/port_settings.py
@@ -202,6 +202,8 @@ SCREENS["video_settings/fov_viewmodels"] = {
"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),
+ ("ARM SHIELDS:", "display.viewmodel_shield", ON_OFF,
+ "The energy shield's flare on your first-person\narms too, as on your body.", None),
],
}