mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
153
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db5a90c955 | ||
|
|
95f26ef625 | ||
|
|
bc7654392a | ||
|
|
760b035a3a | ||
|
|
ce2fd88c24 | ||
|
|
3d6c02ffe2 | ||
|
|
2aae150981 | ||
|
|
620afa0c1e | ||
|
|
7fdcd4abc7 | ||
|
|
18394f7074 | ||
|
|
8bde63a9ae | ||
|
|
f021e9df8a | ||
|
|
4a1d794a64 | ||
|
|
fecb9b16af | ||
|
|
7e637d5d5a | ||
|
|
ff5bc2f6a0 | ||
|
|
c08a669c2e | ||
|
|
03f6f09c93 | ||
|
|
74c2a204c7 | ||
|
|
a9ad87ea08 | ||
|
|
0a86623e9e | ||
|
|
2f957668e3 | ||
|
|
38d9a975ce | ||
|
|
f26643c43d | ||
|
|
c2cb07ded3 | ||
|
|
7a04f76a46 | ||
|
|
006d2a49b1 | ||
|
|
a281f35f1a | ||
|
|
88f7e41d8c | ||
|
|
f2998a2c69 | ||
|
|
1b0a3ea6f9 | ||
|
|
5e274a008c | ||
|
|
38be5c248c | ||
|
|
0450ef0d1a | ||
|
|
e6a2a2a7f9 | ||
|
|
bbb6a6f199 | ||
|
|
1c0b58e11b | ||
|
|
0bf0735cd9 | ||
|
|
cc3791b594 | ||
|
|
799906a921 | ||
|
|
043e3fab79 | ||
|
|
2e34c29215 | ||
|
|
96228d6e98 | ||
|
|
dc4daafd61 | ||
|
|
4b37796628 | ||
|
|
45a434a60a | ||
|
|
488ec8d5a8 | ||
|
|
b1460eb3fa | ||
|
|
671fe21a75 | ||
|
|
d6606ad642 | ||
|
|
d9b2b428a0 | ||
|
|
e87fcfaf28 | ||
|
|
65d1b7f99a | ||
|
|
712337a2da | ||
|
|
b9169cc425 | ||
|
|
b7a0124a9b | ||
|
|
27925607b8 | ||
|
|
38d8f17990 | ||
|
|
5143855863 | ||
|
|
648a1d009d | ||
|
|
df531fc595 | ||
|
|
5802f718f6 | ||
|
|
7d62d741b9 | ||
|
|
45258aabb4 | ||
|
|
db34b4d53c | ||
|
|
7c2077baf2 | ||
|
|
eef7623e9f | ||
|
|
529ac05034 | ||
|
|
6ac8559630 | ||
|
|
2626e7862b | ||
|
|
b3cd35258c | ||
|
|
0fb12b89eb | ||
|
|
c082babd9c | ||
|
|
d5f3be091c | ||
|
|
790227a2bf | ||
|
|
803f08f969 | ||
|
|
f2c40a2669 | ||
|
|
63756c00af | ||
|
|
2147571dff | ||
|
|
bb9c76103b | ||
|
|
857e61f638 | ||
|
|
58053a02b2 | ||
|
|
e8ea8733d0 | ||
|
|
184bbb52bb | ||
|
|
b00410ab01 | ||
|
|
525d8e34d0 | ||
|
|
4cdf10b399 | ||
|
|
c652d5a84c | ||
|
|
1a356834b4 | ||
|
|
3f48f7c4ad | ||
|
|
3e8a9d9738 | ||
|
|
592eefb60f | ||
|
|
373218d7d9 | ||
|
|
1bdd6c3c4c | ||
|
|
1313434e11 | ||
|
|
bf996313dc | ||
|
|
2eb5a3ecde | ||
|
|
1aee2401e5 | ||
|
|
f8203e9da3 | ||
|
|
b24bcbcc62 | ||
|
|
0b8c1b6853 | ||
|
|
6ae6c550a7 | ||
|
|
9c521d04d8 | ||
|
|
c6c9945e50 | ||
|
|
8dfeca4ac3 | ||
|
|
bb4898cb04 | ||
|
|
6e38656658 | ||
|
|
e72dd4c2ca | ||
|
|
be8725c6c6 | ||
|
|
15c921223b | ||
|
|
ec241fcab3 | ||
|
|
0e00ab670c | ||
|
|
1f9a2ca4ce | ||
|
|
0d697672dc | ||
|
|
1fe62ea8d1 | ||
|
|
687694c732 | ||
|
|
9093af9b95 | ||
|
|
3b0dca6cd9 | ||
|
|
817b7dc975 | ||
|
|
d4d7c8dbd2 | ||
|
|
bb89553b0a | ||
|
|
e4acd15a1e | ||
|
|
d16f46fb1c | ||
|
|
77ad3ba0aa | ||
|
|
da31995331 | ||
|
|
25d326567e | ||
|
|
03696d07ca | ||
|
|
0528538a6f | ||
|
|
a7b795e965 | ||
|
|
9b78fad1c5 | ||
|
|
f4d7b45e4d | ||
|
|
d23e4b8e87 | ||
|
|
d83de47ef2 | ||
|
|
59435abfb2 | ||
|
|
bf13ce54a8 | ||
|
|
fcd3264fad | ||
|
|
e33419c48d | ||
|
|
a73df5bcb4 | ||
|
|
4e707fc8e9 | ||
|
|
2e7057ed8d | ||
|
|
ba9285e09a | ||
|
|
138eddfbd2 | ||
|
|
66be185d0c | ||
|
|
0c355efaa2 | ||
|
|
38cd1bff86 | ||
|
|
71ee9501f9 | ||
|
|
221670589e | ||
|
|
9a47a664f7 | ||
|
|
7b7b19b71b | ||
|
|
666b9a5751 | ||
|
|
8421d8d8e6 | ||
|
|
63ed4c8254 | ||
|
|
3124c55642 |
No files matched your search
@@ -1,53 +0,0 @@
|
||||
name: Publish Standalone docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'nightly_*'
|
||||
- 'release_*'
|
||||
|
||||
jobs:
|
||||
build_images:
|
||||
if: github.repository == 'scp-fs2open/fs2open.github.com'
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
include:
|
||||
- configuration: FastDebug
|
||||
tag_suffix: -debug
|
||||
- configuration: Release
|
||||
tag_suffix: ""
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Docker meta
|
||||
id: docker_meta
|
||||
uses: crazy-max/ghaction-docker-meta@v1
|
||||
with:
|
||||
images: ghcr.io/scp-fs2open/standalone_server
|
||||
tag-latest: false
|
||||
|
||||
- name: Login to GitHub Docker Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/standalone/Dockerfile
|
||||
push: true
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}${{ matrix.tag_suffix }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
build-args: |
|
||||
build_type=${{ matrix.configuration }}
|
||||
@@ -2,14 +2,17 @@ name: Weekly Coverity Scan for Freespace Open
|
||||
# adapted from code by "albert-github" on the doxygen repository
|
||||
# many thanks for figuring this out first so it could be less painful for us!
|
||||
|
||||
# keep this from running on everyone's fork
|
||||
# if: github.ref == 'refs/heads/master'
|
||||
|
||||
#This mode is for testing
|
||||
#on: [push, pull_request]
|
||||
|
||||
# In production, push on a specific schedule
|
||||
on:
|
||||
schedule:
|
||||
- cron: "5 0 * * 5" # Run once per a week on Friday morning (midnight UTC, 4 AM EST), to avoid Coverity's submission limits
|
||||
|
||||
- cron: "57 18 * * *" # Run once per a week on Friday morning (4 AM EST), to avoid Coverity's submission limits
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.12
|
||||
coverity_email: [email protected]
|
||||
@@ -18,19 +21,17 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
name: Build FSO With Coverity Wrapper
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-1ff82e8
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- { name: "GCC on ubuntu", os: ubuntu-latest, build_type: "Release" }
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive # `true` to checkout submodules, `recursive` to recursively checkout submodules
|
||||
submodules: true # `true` to checkout submodules, `recursive` to recursively checkout submodules
|
||||
|
||||
# pipe results of wget to a log file because it's very verbose and rarely fails
|
||||
- name: Install Coverity
|
||||
@@ -46,8 +47,8 @@ jobs:
|
||||
|
||||
- name: Configure CMake for FSO
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
compiler: gcc-9
|
||||
CONFIGURATION: FastDebug
|
||||
COMPILER: gcc-9
|
||||
ENABLE_QTFRED: OFF
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
include("${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
endif()
|
||||
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 23)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 3)
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 24)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 1)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 0)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
|
||||
@@ -47,7 +47,7 @@ ProgramInstance::ProgramInstance(const actions::Program* program) : _program(pro
|
||||
|
||||
ProgramState ProgramInstance::step()
|
||||
{
|
||||
if (!_locals.host.IsValid()) {
|
||||
if (!_locals.host.isValid()) {
|
||||
return ProgramState::Done;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,9 @@ namespace AI {
|
||||
Whackable_debris,
|
||||
Whackable_asteroids,
|
||||
Dynamic_goals_afterburn_hard,
|
||||
Player_orders_afterburn_hard,
|
||||
Hudsquadmsg_tactical_disarm_disable,
|
||||
Align_to_target_when_guarding_still,
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
|
||||
@@ -625,8 +625,12 @@ void parse_ai_profiles_tbl(const char *filename)
|
||||
|
||||
set_flag(profile, "$dynamic goals afterburn hard:", AI::Profile_Flags::Dynamic_goals_afterburn_hard);
|
||||
|
||||
set_flag(profile, "$player orders afterburn hard:", AI::Profile_Flags::Player_orders_afterburn_hard);
|
||||
|
||||
set_flag(profile, "$hud squad messages use tactical disarm/disable:", AI::Profile_Flags::Hudsquadmsg_tactical_disarm_disable);
|
||||
|
||||
set_flag(profile, "$align to target when guarding stationary ship:", AI::Profile_Flags::Align_to_target_when_guarding_still);
|
||||
|
||||
// if we've been through once already and are at the same place, force a move
|
||||
if (saved_Mp && (saved_Mp == Mp))
|
||||
{
|
||||
|
||||
+19
-12
@@ -3515,6 +3515,7 @@ void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags, int
|
||||
aip->wp_index = start_index;
|
||||
aip->wp_flags = wp_flags;
|
||||
aip->mode = AIM_WAYPOINTS;
|
||||
aip->submode_parm0 = start_index; // keep track of the start index because we need it for Fix_ai_path_order_bug
|
||||
|
||||
Assert(aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC);
|
||||
}
|
||||
@@ -10891,14 +10892,14 @@ void ai_guard()
|
||||
// Goal point is in front.
|
||||
// If close to goal point, don't change direction, just change speed.
|
||||
if (dist_to_goal_point > Pl_objp->radius + 10.0f) {
|
||||
turn_towards_point(Pl_objp, &goal_point, NULL, 0.0f);
|
||||
turn_towards_point(Pl_objp, &goal_point, nullptr, 0.0f);
|
||||
}
|
||||
|
||||
set_accel_for_target_speed(Pl_objp, guard_objp->phys_info.speed + (dist_to_goal_point-40.0f)/20.0f);
|
||||
}
|
||||
} else {
|
||||
if (dot_to_goal_point > 0.8f) {
|
||||
turn_towards_point(Pl_objp, &goal_point, NULL, 0.0f);
|
||||
turn_towards_point(Pl_objp, &goal_point, nullptr, 0.0f);
|
||||
set_accel_for_target_speed(Pl_objp, guard_objp->phys_info.speed + dist_to_goal_point*0.1f);
|
||||
} else {
|
||||
set_accel_for_target_speed(Pl_objp, guard_objp->phys_info.speed - dist_to_goal_point*0.1f - 1.0f);
|
||||
@@ -10907,10 +10908,14 @@ void ai_guard()
|
||||
// consider guard object STILL
|
||||
} else if (guard_objp->radius < 50.0f) {
|
||||
if (dist_to_goal_point > 15.0f) {
|
||||
turn_towards_point(Pl_objp, &goal_point, NULL, 0.0f);
|
||||
turn_towards_point(Pl_objp, &goal_point, nullptr, 0.0f);
|
||||
set_accel_for_target_speed(Pl_objp, (dist_to_goal_point-10.0f)/2.0f);
|
||||
} else if (Pl_objp->phys_info.speed < 1.0f) {
|
||||
turn_away_from_point(Pl_objp, &guard_objp->pos, 0.0f);
|
||||
if (aip->ai_profile_flags[AI::Profile_Flags::Align_to_target_when_guarding_still]) {
|
||||
turn_towards_point(Pl_objp, &guard_objp->pos, nullptr, 0.0f, &guard_objp->orient);
|
||||
} else {
|
||||
turn_away_from_point(Pl_objp, &guard_objp->pos, 0.0f);
|
||||
}
|
||||
}
|
||||
// It's a big ship
|
||||
} else if (dist_to_guardobj > MAX_GUARD_DIST + Pl_objp->radius + guard_objp->radius) {
|
||||
@@ -12610,7 +12615,12 @@ int ai_formation()
|
||||
if (aip->mode == AIM_WAYPOINTS) {
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Fix_ai_path_order_bug]){
|
||||
// skip if wing leader has no waypoint order or a different waypoint list
|
||||
if ((laip->mode != AIM_WAYPOINTS) || !(aip->wp_list == laip->wp_list)){
|
||||
// ...or if it's a different start index or direction
|
||||
if ( (laip->mode != AIM_WAYPOINTS)
|
||||
|| (laip->wp_list != aip->wp_list)
|
||||
|| (laip->submode_parm0 != aip->submode_parm0)
|
||||
|| ((laip->wp_flags & WPF_BACKTRACK) != (aip->wp_flags & WPF_BACKTRACK))
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -13898,10 +13908,7 @@ int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int allowed_path_
|
||||
*/
|
||||
void ai_bay_depart()
|
||||
{
|
||||
ai_info *aip;
|
||||
int anchor_shipnum;
|
||||
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
auto aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
|
||||
// if no path to follow, leave this mode
|
||||
if ( aip->path_start < 0 ) {
|
||||
@@ -13910,8 +13917,8 @@ void ai_bay_depart()
|
||||
}
|
||||
|
||||
// check if parent ship valid; if not, abort depart
|
||||
anchor_shipnum = ship_name_lookup(Parse_names[Ships[Pl_objp->instance].departure_anchor]);
|
||||
if (anchor_shipnum < 0 || !ship_useful_for_departure(anchor_shipnum, Ships[Pl_objp->instance].departure_path_mask))
|
||||
auto anchor_ship_entry = ship_registry_get(Parse_names[Ships[Pl_objp->instance].departure_anchor]);
|
||||
if (!anchor_ship_entry || !ship_useful_for_departure(anchor_ship_entry->shipnum, Ships[Pl_objp->instance].departure_path_mask))
|
||||
{
|
||||
mprintf(("Aborting bay departure!\n"));
|
||||
aip->mode = AIM_NONE;
|
||||
@@ -13922,7 +13929,7 @@ void ai_bay_depart()
|
||||
|
||||
ai_manage_bay_doors(Pl_objp, aip, false);
|
||||
|
||||
if ( Ships[anchor_shipnum].bay_doors_status != MA_POS_READY )
|
||||
if ( anchor_ship_entry->shipp()->bay_doors_status != MA_POS_READY )
|
||||
return;
|
||||
|
||||
// follow the path to the final point
|
||||
|
||||
@@ -751,6 +751,9 @@ void ai_add_goal_sub_player(int type, int mode, int submode, const char *target_
|
||||
if ( target_name != NULL )
|
||||
aigp->target_name = ai_get_goal_target_name( target_name, &aigp->target_name_index );
|
||||
|
||||
if (The_mission.ai_profile->flags[AI::Profile_Flags::Player_orders_afterburn_hard])
|
||||
aigp->flags.set(AI::Goal_Flags::Afterburn_hard);
|
||||
|
||||
|
||||
// special case certain orders from player so that ships continue to do the right thing
|
||||
|
||||
|
||||
+1
-1
@@ -389,7 +389,7 @@ ai_achievability ai_lua_is_achievable(const ai_goal* aigp, int objnum){
|
||||
if (!retVals.empty() && retVals[0].getValueType() == luacpp::ValueType::USERDATA) {
|
||||
scripting::api::enum_h enumData;
|
||||
retVals[0].getValue(scripting::api::l_Enum.Get(&enumData));
|
||||
if (!enumData.IsValid()) {
|
||||
if (!enumData.isValid()) {
|
||||
Error(LOCATION, "LuaAI SEXP achievability hook returned an invalid avilability enum.");
|
||||
return ai_achievability::ACHIEVABLE;
|
||||
}
|
||||
|
||||
@@ -2536,9 +2536,10 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss)
|
||||
return;
|
||||
}
|
||||
|
||||
if ( lep == nullptr ){
|
||||
return;
|
||||
}
|
||||
//This can't happen. See above code
|
||||
//if ( lep == nullptr ){
|
||||
// return;
|
||||
//}
|
||||
|
||||
//This can't happen. See above code
|
||||
//Assert(ss->turret_enemy_objnum != -1);
|
||||
|
||||
+56
-16
@@ -14,8 +14,8 @@
|
||||
#include "ship/ship.h" //compute_slew_matrix
|
||||
|
||||
//*************************IMPORTANT GLOBALS*************************
|
||||
fov_t VIEWER_ZOOM_DEFAULT = 0.75f; // Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
|
||||
fov_t COCKPIT_ZOOM_DEFAULT = 0.75f;
|
||||
fov_t VIEWER_ZOOM_DEFAULT = DEFAULT_FOV;
|
||||
fov_t COCKPIT_ZOOM_DEFAULT = DEFAULT_FOV;
|
||||
float Sexp_fov = 0.0f;
|
||||
warp_camera Warp_camera;
|
||||
|
||||
@@ -54,6 +54,9 @@ APPLY_TO_FOV_T(*, mul)
|
||||
APPLY_TO_FOV_T(+, add)
|
||||
APPLY_TO_FOV_T(-, sub)
|
||||
|
||||
// Used to set the default value for in-game options
|
||||
static constexpr float fov_default = DEFAULT_FOV;
|
||||
|
||||
static SCP_string fov_display(float val)
|
||||
{
|
||||
auto degrees = fl_degrees(val);
|
||||
@@ -64,18 +67,55 @@ static SCP_string fov_display(float val)
|
||||
auto FovOption = options::OptionBuilder<float>("Graphics.FOV",
|
||||
std::pair<const char*, int>{"Field Of View", 1703},
|
||||
std::pair<const char*, int>{"The vertical field of view", 1704})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.range(0.436332f, 1.5708f)
|
||||
.change_listener([](const float& val, bool) {
|
||||
VIEWER_ZOOM_DEFAULT = val;
|
||||
return true;
|
||||
})
|
||||
.display(fov_display)
|
||||
.default_val(0.75f)
|
||||
.default_val(fov_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(60)
|
||||
.finish();
|
||||
|
||||
bool Use_cockpit_fov = false;
|
||||
|
||||
auto CockpitFOVToggleOption = options::OptionBuilder<bool>("Graphics.CockpitFOVToggle",
|
||||
std::pair<const char*, int>{"Cockpit FOV Toggle", 1838},
|
||||
std::pair<const char*, int>{"Whether or not to use a different FOV for cockpit rendering from normal rendering", 1839})
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(false)
|
||||
.change_listener([](bool val, bool) {
|
||||
if (!val) {
|
||||
COCKPIT_ZOOM_DEFAULT = VIEWER_ZOOM_DEFAULT;
|
||||
}
|
||||
return true; // This option will always persist so we never return false
|
||||
})
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Use_cockpit_fov)
|
||||
.importance(61)
|
||||
.finish();
|
||||
|
||||
auto CockpitFovOption = options::OptionBuilder<float>("Graphics.CockpitFOV",
|
||||
std::pair<const char*, int>{"Cockpit Field Of View", 1840},
|
||||
std::pair<const char*, int>{"The vertical field of view for cockpit rendering. Only works if cockpits are active and cockpit FOV toggle is turned on.", 1841})
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.range(0.436332f, 1.5708f)
|
||||
.change_listener([](const float& val, bool) {
|
||||
if (Use_cockpit_fov){
|
||||
COCKPIT_ZOOM_DEFAULT = val;
|
||||
} else {
|
||||
COCKPIT_ZOOM_DEFAULT = VIEWER_ZOOM_DEFAULT;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.display(fov_display)
|
||||
.default_val(fov_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(62)
|
||||
.finish();
|
||||
|
||||
//*************************CLASS: camera*************************
|
||||
//This is where the camera class begins! :D
|
||||
camera::camera(const char *in_name, int in_signature)
|
||||
@@ -301,7 +341,7 @@ void camera::set_rotation_facing(vec3d *in_target, float in_rotation_time, float
|
||||
|
||||
// if we have a host, we need the difference between the camera's current orient and the orient we want
|
||||
// if not, we will later set the absolute orientation, rather than the orientation relative to the host
|
||||
if (object_host.IsValid())
|
||||
if (object_host.isValid())
|
||||
{
|
||||
vm_transpose(orient);
|
||||
temp_matrix = temp_matrix * *orient;
|
||||
@@ -324,7 +364,7 @@ void camera::do_frame(float /*in_frametime*/)
|
||||
|
||||
object *camera::get_object_host()
|
||||
{
|
||||
if(object_host.IsValid())
|
||||
if(object_host.isValid())
|
||||
return object_host.objp;
|
||||
else
|
||||
return NULL;
|
||||
@@ -337,7 +377,7 @@ int camera::get_object_host_submodel()
|
||||
|
||||
object *camera::get_object_target()
|
||||
{
|
||||
if(object_target.IsValid())
|
||||
if(object_target.isValid())
|
||||
return object_target.objp;
|
||||
else
|
||||
return NULL;
|
||||
@@ -373,7 +413,7 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
bool use_host_orient = false;
|
||||
|
||||
//POSITION
|
||||
if(!(flags & CAM_STATIONARY_POS) || object_host.IsValid())
|
||||
if(!(flags & CAM_STATIONARY_POS) || object_host.isValid())
|
||||
{
|
||||
c_pos = vmd_zero_vector;
|
||||
|
||||
@@ -382,7 +422,7 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
pos_y.get(&pt.xyz.y, NULL);
|
||||
pos_z.get(&pt.xyz.z, NULL);
|
||||
|
||||
if(object_host.IsValid())
|
||||
if(object_host.isValid())
|
||||
{
|
||||
object *objp = object_host.objp;
|
||||
int model_num = object_get_model(objp);
|
||||
@@ -444,9 +484,9 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
if(orientation != NULL)
|
||||
{
|
||||
bool target_set = false;
|
||||
if(!(flags & CAM_STATIONARY_ORI) || object_target.IsValid() || object_host.IsValid())
|
||||
if(!(flags & CAM_STATIONARY_ORI) || object_target.isValid() || object_host.isValid())
|
||||
{
|
||||
if(object_target.IsValid())
|
||||
if(object_target.isValid())
|
||||
{
|
||||
object *target_objp = object_target.objp;
|
||||
int model_num = object_get_model(target_objp);
|
||||
@@ -481,7 +521,7 @@ void camera::get_info(vec3d *position, matrix *orientation, bool apply_camera_or
|
||||
vm_vector_2_matrix(&c_ori, &targetvec, NULL, NULL);
|
||||
target_set = true;
|
||||
}
|
||||
else if(object_host.IsValid())
|
||||
else if(object_host.isValid())
|
||||
{
|
||||
if(eyep)
|
||||
{
|
||||
@@ -754,7 +794,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char*
|
||||
//Get text size
|
||||
for(int i = 0; i < num_text_lines; i++)
|
||||
{
|
||||
gr_get_string_size(&w, &h, text_line_ptrs[i], text_line_lens[i]);
|
||||
gr_get_string_size(&w, &h, text_line_ptrs[i], static_cast<size_t>(text_line_lens[i]));
|
||||
|
||||
if(w > tw)
|
||||
tw = w;
|
||||
@@ -1011,7 +1051,7 @@ int camid::getSignature()
|
||||
return sig;
|
||||
}
|
||||
|
||||
bool camid::isValid()
|
||||
bool camid::isValid() const
|
||||
{
|
||||
if(idx >= Cameras.size())
|
||||
return false;
|
||||
@@ -1203,7 +1243,7 @@ vec3d normal_cache;
|
||||
void get_turret_cam_pos(camera *cam, vec3d *pos)
|
||||
{
|
||||
object_h obj(cam->get_object_host());
|
||||
if(!obj.IsValid())
|
||||
if(!obj.isValid())
|
||||
return;
|
||||
ship* shipp = &Ships[cam->get_object_host()->instance];
|
||||
ship_subsys* ssp = GET_FIRST(&shipp->subsys_list);
|
||||
@@ -1224,7 +1264,7 @@ void get_turret_cam_pos(camera *cam, vec3d *pos)
|
||||
void get_turret_cam_orient(camera *cam, matrix *ori)
|
||||
{
|
||||
object_h obj(cam->get_object_host());
|
||||
if(!obj.IsValid())
|
||||
if(!obj.isValid())
|
||||
return;
|
||||
vm_vector_2_matrix(ori, &normal_cache, vm_vec_same(&normal_cache, &cam->get_object_host()->orient.vec.uvec)?NULL:&cam->get_object_host()->orient.vec.uvec, NULL);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#define EXTERN_CAM_BBOX_CONSTANT_PADDING 5.0f
|
||||
#define EXTERN_CAM_BBOX_MULTIPLIER_PADDING 1.5f
|
||||
|
||||
#define DEFAULT_FOV 0.75f;
|
||||
|
||||
struct asymmetric_fov {
|
||||
float left, right, up, down;
|
||||
friend asymmetric_fov operator* (const asymmetric_fov&, const float&);
|
||||
|
||||
@@ -1900,7 +1900,7 @@ bool SetCmdlineParams()
|
||||
if (val > 0.1) {
|
||||
VIEWER_ZOOM_DEFAULT = val;
|
||||
} else {
|
||||
VIEWER_ZOOM_DEFAULT = 0.75f;
|
||||
VIEWER_ZOOM_DEFAULT = DEFAULT_FOV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -923,8 +923,8 @@ bool control_config_do_reset(bool cycle, bool API_Access)
|
||||
|
||||
// first, determine how many bindings need to be changed
|
||||
for (size_t e = 0; e < Control_config.size(); ++e) {
|
||||
auto item = Control_config[e];
|
||||
auto default_item = default_bindings[e];
|
||||
const auto& item = Control_config[e];
|
||||
const auto& default_item = default_bindings[e];
|
||||
|
||||
if (item.disabled) {
|
||||
// skip
|
||||
|
||||
@@ -48,12 +48,13 @@ int Joy_dead_zone_size = 10;
|
||||
auto DeadZoneOption = options::OptionBuilder<int>("Input.JoystickDeadZone",
|
||||
std::pair<const char*, int>{"Deadzone", 1377},
|
||||
std::pair<const char*, int>{"The deadzone used for all joysticks", 1744})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.range(0, 45)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(10)
|
||||
.bind_to(&Joy_dead_zone_size)
|
||||
.importance(1)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
int Joy_sensitivity = 9;
|
||||
@@ -61,12 +62,13 @@ int Joy_sensitivity = 9;
|
||||
auto SensitivityOption = options::OptionBuilder<int>("Input.JoystickSensitivity",
|
||||
std::pair<const char*, int>{"Sensitivity", 1745},
|
||||
std::pair<const char*, int>{"The sensitivity used for all joysticks", 1746})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.range(0, 9)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(9)
|
||||
.bind_to(&Joy_sensitivity)
|
||||
.importance(2)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
//! arrays which hold the key mappings. The array index represents a key-independent action.
|
||||
|
||||
@@ -220,8 +220,8 @@ struct Decal {
|
||||
vm_vec_make(&scale, 1.f, 1.f, 1.f);
|
||||
}
|
||||
|
||||
bool isValid() {
|
||||
if (!object.IsValid()) {
|
||||
bool isValid() const {
|
||||
if (!object.isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (object.objp->flags[Object::Object_Flags::Should_be_dead]) {
|
||||
|
||||
@@ -51,7 +51,7 @@ bool Fireball_use_3d_warp = false;
|
||||
static auto WarpOption __UNUSED = options::OptionBuilder<bool>("Graphics.3dWarp",
|
||||
std::pair<const char*, int>{"3D Warp", 1770},
|
||||
std::pair<const char*, int>{"Use a 3D model for warp effects", 1771})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Fireball_use_3d_warp)
|
||||
|
||||
@@ -27,7 +27,7 @@ bool Fireball_warp_flash = false;
|
||||
static auto WarpFlashOption __UNUSED = options::OptionBuilder<bool>("Graphics.WarpFlash",
|
||||
std::pair<const char*, int>{"Warp Flash", 1768},
|
||||
std::pair<const char*, int>{"Show flash upon warp open or close", 1769})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to_once(&Fireball_warp_flash)
|
||||
|
||||
@@ -499,7 +499,7 @@ void help_overlay_blit(int overlay_id, int resolution_index)
|
||||
font::set_font(help_overlaylist[overlay_id].fontlist.at(resolution_index));
|
||||
for (idx = 0; idx < textcount; idx++) {
|
||||
gr_set_color_fast(&Color_black);
|
||||
gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist.at(0).at(idx).string, (int)strlen(help_overlaylist[overlay_id].textlist.at(0).at(idx).string));
|
||||
gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist.at(0).at(idx).string, strlen(help_overlaylist[overlay_id].textlist.at(0).at(idx).string));
|
||||
gr_rect(help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).x_coord-2*HELP_PADDING, help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).y_coord-3*HELP_PADDING, width+4*HELP_PADDING, height+4*HELP_PADDING, GR_RESIZE_MENU);
|
||||
gr_set_color_fast(&Color_bright_white);
|
||||
gr_printf_menu(help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).x_coord, help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).y_coord,
|
||||
|
||||
@@ -114,7 +114,8 @@ const char *GS_event_text[] =
|
||||
"GS_EVENT_PXO_HELP",
|
||||
"GS_EVENT_FICTION_VIEWER", // 65
|
||||
"GS_EVENT_SCRIPTING",
|
||||
"GS_EVENT_SCRIPTING_MISSION"
|
||||
"GS_EVENT_SCRIPTING_MISSION",
|
||||
"GS_EVENT_INGAME_OPTIONS"
|
||||
};
|
||||
//XSTR:ON
|
||||
|
||||
@@ -178,7 +179,8 @@ const char *GS_state_text[] =
|
||||
"GS_STATE_START_GAME",
|
||||
"GS_STATE_FICTION_VIEWER",
|
||||
"GS_STATE_SCRIPTING",
|
||||
"GS_STATE_SCRIPTING_MISSION"
|
||||
"GS_STATE_SCRIPTING_MISSION",
|
||||
"GS_STATE_INGAME_OPTIONS"
|
||||
};
|
||||
//XSTR:ON
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ enum GS_EVENT {
|
||||
GS_EVENT_FICTION_VIEWER,
|
||||
GS_EVENT_SCRIPTING,
|
||||
GS_EVENT_SCRIPTING_MISSION,
|
||||
GS_EVENT_INGAME_OPTIONS,
|
||||
|
||||
GS_NUM_EVENTS // Last one++
|
||||
};
|
||||
@@ -161,6 +162,7 @@ enum GS_STATE {
|
||||
GS_STATE_FICTION_VIEWER,
|
||||
GS_STATE_SCRIPTING,
|
||||
GS_STATE_SCRIPTING_MISSION,
|
||||
GS_STATE_INGAME_OPTIONS,
|
||||
|
||||
GS_NUM_STATES // Last one++
|
||||
};
|
||||
|
||||
@@ -48,11 +48,12 @@ static bool music_volume_change_listener(float new_val, bool /*initial*/)
|
||||
static auto MusicVolumeOption __UNUSED = options::OptionBuilder<float>("Audio.Music",
|
||||
std::pair<const char*, int>{"Music", 1371},
|
||||
std::pair<const char*, int>{"Volume used for playing music", 1760})
|
||||
.category("Audio")
|
||||
.category(std::make_pair("Audio", 1826))
|
||||
.default_val(Default_music_volume)
|
||||
.range(0.0f, 1.0f)
|
||||
.change_listener(music_volume_change_listener)
|
||||
.importance(1)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
typedef struct tagSNDPATTERN {
|
||||
|
||||
@@ -319,7 +319,7 @@ enum class InterfaceSounds {
|
||||
MIN_INTERFACE_SOUNDS =70 //!< MIN_INTERFACE_SOUNDS
|
||||
};
|
||||
|
||||
// These two id types are defined as sublcasses so that type safe implicit conversions are possible from the predefined
|
||||
// These two id types are defined as subclasses so that type safe implicit conversions are possible from the predefined
|
||||
// sound enum values
|
||||
|
||||
struct gamesnd_id_tag{};
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#define MAX_POLYGON_MODELS 300
|
||||
|
||||
// object.h
|
||||
//If this value exceeds 2^16-1, this will break collision pair caching as is. Proceed with caution.
|
||||
#define MAX_OBJECTS 5000 //Increased from 3500 to 5000 in 2022
|
||||
|
||||
// from weapon.h (and beam.h)
|
||||
|
||||
@@ -442,7 +442,7 @@ public:
|
||||
class camera *getCamera();
|
||||
size_t getIndex();
|
||||
int getSignature();
|
||||
bool isValid();
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
#include "globalincs/vmallocator.h"
|
||||
|
||||
@@ -248,45 +248,48 @@ const auto ModelDetailOption __UNUSED = options::OptionBuilder<int>("Graphics.De
|
||||
std::pair<const char*, int>{"Model Detail", 1739},
|
||||
std::pair<const char*, int>{"Detail level of models", 1740})
|
||||
.importance(8)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.detail_distance = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto TexturesOption __UNUSED = options::OptionBuilder<int>("Graphics.Texture",
|
||||
std::pair<const char*, int>{"3D Hardware Textures", 1362},
|
||||
std::pair<const char*, int>{"Level of detail of textures", 1720})
|
||||
.importance(6)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.hardware_textures = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto ParticlesOption __UNUSED = options::OptionBuilder<int>("Graphics.Particles",
|
||||
std::pair<const char*, int>{"Particles", 1363},
|
||||
std::pair<const char*, int>{"Level of detail for particles", 1717})
|
||||
.importance(5)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.num_particles = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto SmallDebrisOption __UNUSED = options::OptionBuilder<int>("Graphics.SmallDebris",
|
||||
std::pair<const char*, int>{"Impact Effects", 1364},
|
||||
std::pair<const char*, int>{"Level of detail of impact effects", 1743})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.importance(4)
|
||||
@@ -294,32 +297,35 @@ const auto SmallDebrisOption __UNUSED = options::OptionBuilder<int>("Graphics.Sm
|
||||
Detail.num_small_debris = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto ShieldEffectsOption __UNUSED = options::OptionBuilder<int>("Graphics.ShieldEffects",
|
||||
std::pair<const char*, int>{"Shield Hit Effects", 1718},
|
||||
std::pair<const char*, int>{"Level of detail of shield impacts", 1719})
|
||||
.importance(3)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.shield_effects = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const auto StarsOption __UNUSED = options::OptionBuilder<int>("Graphics.Stars",
|
||||
std::pair<const char*, int>{"Stars", 1366},
|
||||
std::pair<const char*, int>{"Number of stars in the mission", 1698})
|
||||
.importance(2)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool) {
|
||||
Detail.num_stars = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
// Call this with:
|
||||
|
||||
@@ -21,17 +21,17 @@ template <typename T>
|
||||
using SCP_vector = std::vector<T, std::allocator<T>>;
|
||||
|
||||
template <typename T>
|
||||
bool SCP_vector_contains(SCP_vector<T>& vector, T item) {
|
||||
bool SCP_vector_contains(const SCP_vector<T>& vector, const T& item) {
|
||||
return std::find(vector.begin(), vector.end(), item) != vector.end();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool SCP_vector_inbounds(SCP_vector<T>& vector, int idx) {
|
||||
inline bool SCP_vector_inbounds(const SCP_vector<T>& vector, int idx) {
|
||||
return ((idx >= 0) && (idx < static_cast<int>(vector.size())));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool SCP_vector_inbounds(SCP_vector<T>& vector, size_t idx) {
|
||||
inline bool SCP_vector_inbounds(const SCP_vector<T>& vector, size_t idx) {
|
||||
return idx < vector.size();
|
||||
}
|
||||
|
||||
|
||||
+15
-13
@@ -116,11 +116,12 @@ static bool gamma_change_listener(float new_val, bool initial)
|
||||
static auto GammaOption __UNUSED = options::OptionBuilder<float>("Graphics.Gamma",
|
||||
std::pair<const char*, int>{"Brightness", 1375},
|
||||
std::pair<const char*, int>{"The brightness value used for the game window", 1738})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(1.0f)
|
||||
.enumerator(gamma_value_enumerator)
|
||||
.display(gamma_display)
|
||||
.change_listener(gamma_change_listener)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
|
||||
@@ -134,7 +135,7 @@ const auto LightingOption __UNUSED = options::OptionBuilder<int>("Graphics.Light
|
||||
std::pair<const char*, int>{"Lighting", 1367},
|
||||
std::pair<const char*, int>{"Level of detail of the lighting", 1715})
|
||||
.importance(1)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.change_listener([](int val, bool initial) {
|
||||
@@ -144,6 +145,7 @@ const auto LightingOption __UNUSED = options::OptionBuilder<int>("Graphics.Light
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
os::ViewportState Gr_configured_window_state = os::ViewportState::Windowed;
|
||||
@@ -169,7 +171,7 @@ static bool mode_change_func(os::ViewportState state, bool initial)
|
||||
static auto WindowModeOption __UNUSED = options::OptionBuilder<os::ViewportState>("Graphics.WindowMode",
|
||||
std::pair<const char*, int>{"Window Mode", 1772},
|
||||
std::pair<const char*, int>{"Controls how the game window is created", 1773})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.values({{os::ViewportState::Fullscreen, {"Fullscreen", 1679}},
|
||||
{os::ViewportState::Borderless, {"Borderless", 1675}},
|
||||
@@ -260,7 +262,7 @@ static bool videodisplay_change(int display, bool initial)
|
||||
static auto VideoDisplayOption = options::OptionBuilder<int>("Graphics.Display",
|
||||
std::pair<const char*, int>{"Primary display", 1741},
|
||||
std::pair<const char*, int>{"The display used for rendering", 1742})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.deserializer(videodisplay_deserializer)
|
||||
.serializer(videodisplay_serializer)
|
||||
@@ -370,7 +372,7 @@ static bool resolution_change(const ResolutionInfo& /*info*/, bool initial)
|
||||
static auto ResolutionOption = options::OptionBuilder<ResolutionInfo>("Graphics.Resolution",
|
||||
std::pair<const char*, int>{"Resolution", 1748},
|
||||
std::pair<const char*, int>{"The rendering resolution", 1749})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.deserializer(resolution_deserializer)
|
||||
.serializer(resolution_serializer)
|
||||
@@ -386,7 +388,7 @@ bool Gr_enable_soft_particles = false;
|
||||
static auto SoftParticlesOption __UNUSED = options::OptionBuilder<bool>("Graphics.SoftParticles",
|
||||
std::pair<const char*, int>{"Soft Particles", 1761},
|
||||
std::pair<const char*, int>{"Enable or disable soft particle rendering", 1762})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_enable_soft_particles)
|
||||
@@ -398,13 +400,13 @@ flagset<FramebufferEffects> Gr_framebuffer_effects;
|
||||
static auto FramebufferEffectsOption __UNUSED = options::OptionBuilder<flagset<FramebufferEffects>>("Graphics.FramebufferEffects",
|
||||
std::pair<const char*, int>{"Framebuffer effects", 1732},
|
||||
std::pair<const char*, int>{"Controls which framebuffer effects will be applied to the scene", 1733})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{{}, {"None", 211}},
|
||||
{{FramebufferEffects::Shockwaves}, {"Shockwaves", 1688}},
|
||||
{{FramebufferEffects::Thrusters}, {"Thrusters", 1689}},
|
||||
{{FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters}, {"All", 1690}}})
|
||||
.default_val({FramebufferEffects::Shockwaves, FramebufferEffects::Thrusters})
|
||||
.default_val({})
|
||||
.bind_to_once(&Gr_framebuffer_effects)
|
||||
.importance(77)
|
||||
.finish();
|
||||
@@ -415,7 +417,7 @@ AntiAliasMode Gr_aa_mode_last_frame = AntiAliasMode::None;
|
||||
static auto AAOption __UNUSED = options::OptionBuilder<AntiAliasMode>("Graphics.AAMode",
|
||||
std::pair<const char*, int>{"Anti Aliasing", 1752},
|
||||
std::pair<const char*, int>{"Controls the anti aliasing mode of the engine.", 1753})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{AntiAliasMode::None, {"None", 211}},
|
||||
{AntiAliasMode::FXAA_Low, {"FXAA Low", 1681}},
|
||||
@@ -434,7 +436,7 @@ extern int Cmdline_msaa_enabled;
|
||||
static auto MSAAOption __UNUSED = options::OptionBuilder<int>("Graphics.MSAASamples",
|
||||
std::pair<const char*, int>{"Multisample Anti Aliasing", 1758},
|
||||
std::pair<const char*, int>{"Controls whether multisample anti asliasing is enabled, and with how many samples", 1759})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.values({{0, {"Off", 1693}},
|
||||
{4, {"4 Samples", 1694}},
|
||||
@@ -458,9 +460,9 @@ bool Gr_post_processing_enabled = true;
|
||||
static auto PostProcessOption __UNUSED = options::OptionBuilder<bool>("Graphics.PostProcessing",
|
||||
std::pair<const char*, int>{"Post processing", 1726},
|
||||
std::pair<const char*, int>{"Controls whether post processing is enabled in the engine.", 1727})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(false)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_post_processing_enabled)
|
||||
.importance(69)
|
||||
.finish();
|
||||
@@ -470,7 +472,7 @@ bool Gr_enable_vsync = true;
|
||||
static auto VSyncOption __UNUSED = options::OptionBuilder<bool>("Graphics.VSync",
|
||||
std::pair<const char*, int>{"Vertical Sync", 1766},
|
||||
std::pair<const char*, int>{"Controls how the engine does vertical synchronization", 1767})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(true)
|
||||
.bind_to_once(&Gr_enable_vsync)
|
||||
|
||||
+1
-1
@@ -1002,7 +1002,7 @@ extern void gr_printf_menu_zoomed( int x, int y, const char * format, SCP_FORMAT
|
||||
extern void gr_printf_no_resize( int x, int y, const char * format, SCP_FORMAT_STRING ... ) SCP_FORMAT_STRING_ARGS(3, 4);
|
||||
|
||||
// Returns the size of the string in pixels in w and h
|
||||
extern void gr_get_string_size( int *w, int *h, const char * text, int len = 9999 );
|
||||
extern void gr_get_string_size( int *w, int *h, const char * text, size_t len = std::string::npos );
|
||||
|
||||
// Returns the height of the current font
|
||||
extern int gr_get_font_height();
|
||||
|
||||
@@ -339,8 +339,8 @@ void gr_set_ambient_light(int red, int green, int blue) {
|
||||
gr_light_ambient[3] = 1.0f;
|
||||
}
|
||||
void gr_get_ambient_light(vec3d* light_vector) {
|
||||
auto abv = ltp::current()->ambient_light_brightness;
|
||||
auto over = ltp::current()->overall_brightness;
|
||||
const auto& abv = ltp::current()->ambient_light_brightness;
|
||||
const auto& over = ltp::current()->overall_brightness;
|
||||
light_vector->xyz.x = over.handle(abv.handle(gr_light_ambient[0]));
|
||||
light_vector->xyz.y = over.handle(abv.handle(gr_light_ambient[1]));
|
||||
light_vector->xyz.z = over.handle(abv.handle(gr_light_ambient[2]));
|
||||
|
||||
@@ -85,7 +85,7 @@ void gr_start_instance_matrix(const vec3d *offset, const matrix *rotation)
|
||||
|
||||
gr_model_matrix_stack.push(offset, rotation);
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
modelview_matrix_depth++;
|
||||
@@ -109,7 +109,7 @@ void gr_end_instance_matrix()
|
||||
|
||||
gr_model_matrix_stack.pop();
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
modelview_matrix_depth--;
|
||||
@@ -280,7 +280,7 @@ void gr_end_2d_matrix()
|
||||
|
||||
gr_view_matrix = gr_last_view_matrix;
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
htl_2d_matrix_set = false;
|
||||
@@ -302,7 +302,7 @@ void gr_push_scale_matrix(const vec3d *scale_factor)
|
||||
|
||||
gr_model_matrix_stack.push(NULL, NULL, scale_factor);
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
matrix_uniform_up_to_date = false;
|
||||
@@ -315,7 +315,7 @@ void gr_pop_scale_matrix()
|
||||
|
||||
gr_model_matrix_stack.pop();
|
||||
|
||||
auto model_matrix = gr_model_matrix_stack.get_transform();
|
||||
const auto& model_matrix = gr_model_matrix_stack.get_transform();
|
||||
vm_matrix4_x_matrix4(&gr_model_view_matrix, &gr_view_matrix, &model_matrix);
|
||||
|
||||
modelview_matrix_depth--;
|
||||
|
||||
@@ -346,7 +346,7 @@ void gr_opengl_deferred_lighting_finish()
|
||||
auto light_data = prepare_light_uniforms(l, light_uniform_aligner);
|
||||
|
||||
if (l.type == Light_Type::Cone) {
|
||||
light_data->dualCone = l.dual_cone ? 1.0f : 0.0f;
|
||||
light_data->dualCone = (l.flags & LF_DUAL_CONE) ? 1.0f : 0.0f;
|
||||
light_data->coneAngle = l.cone_angle;
|
||||
light_data->coneInnerAngle = l.cone_inner_angle;
|
||||
light_data->coneDir = l.vec2;
|
||||
|
||||
@@ -124,10 +124,10 @@ bool gr_opengl_openxr_create_session() {
|
||||
};
|
||||
|
||||
XrSessionCreateInfo sessionCreateInfo {
|
||||
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO,
|
||||
sessionCreateInfo.next = &graphicsBinding,
|
||||
sessionCreateInfo.createFlags = 0,
|
||||
sessionCreateInfo.systemId = xr_system
|
||||
XR_TYPE_SESSION_CREATE_INFO,
|
||||
&graphicsBinding,
|
||||
0,
|
||||
xr_system
|
||||
};
|
||||
|
||||
XrResult sessionInit = xrCreateSession(xr_instance, &sessionCreateInfo, &xr_session);
|
||||
@@ -249,9 +249,9 @@ bool gr_opengl_openxr_flip() {
|
||||
xrAcquireSwapchainImage(swapchain, &acquireImageInfo, &activeIndex);
|
||||
|
||||
XrSwapchainImageWaitInfo waitImageInfo{
|
||||
waitImageInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
|
||||
XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
|
||||
nullptr,
|
||||
waitImageInfo.timeout = std::numeric_limits<int64_t>::max()
|
||||
std::numeric_limits<int64_t>::max()
|
||||
};
|
||||
xrWaitSwapchainImage(swapchain, &waitImageInfo);
|
||||
|
||||
|
||||
@@ -431,7 +431,6 @@ extern GLuint Cockpit_depth_texture;
|
||||
extern GLuint Scene_position_texture;
|
||||
extern GLuint Scene_normal_texture;
|
||||
extern GLuint Scene_specular_texture;
|
||||
extern bool stars_sun_has_glare(int index);
|
||||
extern float Sun_spot;
|
||||
void opengl_post_lightshafts()
|
||||
{
|
||||
@@ -452,7 +451,7 @@ void opengl_post_lightshafts()
|
||||
light_get_global_dir(&light_dir, idx);
|
||||
vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix);
|
||||
|
||||
if ( !stars_sun_has_glare(idx) ) {
|
||||
if ( !light_has_glare(idx) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -851,8 +850,8 @@ void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, i
|
||||
}
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS) {
|
||||
char temp[64];
|
||||
const auto ls_params = graphics::Post_processing_manager->getLightshaftParams();
|
||||
sprintf(temp, "#define SAMPLE_NUM %d\n", ls_params.samplenum);
|
||||
const auto& ls_params = graphics::Post_processing_manager->getLightshaftParams();
|
||||
snprintf(temp, 64, "#define SAMPLE_NUM %d\n", ls_params.samplenum);
|
||||
sflags << temp;
|
||||
} else if (shader_t == SDR_TYPE_POST_PROCESS_FXAA) {
|
||||
set_fxaa_defines(sflags);
|
||||
|
||||
@@ -55,7 +55,7 @@ static auto TextureFilteringOption __UNUSED = options::OptionBuilder<int>("Graph
|
||||
std::pair<const char*, int>{"Texture Filtering", 1763},
|
||||
std::pair<const char*, int>{"Texture filtering option", 1764})
|
||||
.importance(1)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(TextureFilteringValues)
|
||||
.default_val(0)
|
||||
.bind_to_once(&GL_mipmap_filter)
|
||||
@@ -107,7 +107,7 @@ static auto AnisotropyOption = options::OptionBuilder<float>("Graphics.Anisotrop
|
||||
std::pair<const char*, int>{"Anistropic filtering", 1736},
|
||||
std::pair<const char*, int>{"Controls the amount of anistropic filtering of the textures", 1737})
|
||||
.enumerator(anisotropic_value_enumerator)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.display(anisotropic_display)
|
||||
.default_func(anisotropic_default)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
|
||||
@@ -43,7 +43,7 @@ bool Post_processing_enable_lightshafts = true;
|
||||
static auto LightshaftsOption __UNUSED = options::OptionBuilder<bool>("Graphics.Lightshafts",
|
||||
std::pair<const char*, int>{"Lightshafts", 1724},
|
||||
std::pair<const char*, int>{"Enables or disables lightshafts (requires post-processing)", 1725})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to(&Post_processing_enable_lightshafts)
|
||||
@@ -55,12 +55,13 @@ int Post_processing_bloom_intensity = 25; // using default value of Cmdline_bloo
|
||||
static auto BloomIntensityOption __UNUSED = options::OptionBuilder<int>("Graphics.BloomIntensity",
|
||||
std::pair<const char*, int>{"Bloom intensity", 1701},
|
||||
std::pair<const char*, int>{"Sets the bloom intensity (requires post-processing)", 1702})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.range(0, 200)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.default_val(25)
|
||||
.bind_to(&Post_processing_bloom_intensity)
|
||||
.importance(55)
|
||||
.flags({options::OptionFlags::RangeTypeInteger})
|
||||
.finish();
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -779,7 +779,7 @@ void endDrawing(graphics::paths::PathRenderer* path) {
|
||||
}
|
||||
}
|
||||
|
||||
void gr_string(float sx, float sy, const char* s, int resize_mode, int in_length) {
|
||||
void gr_string(float sx, float sy, const char* s, int resize_mode, size_t in_length) {
|
||||
if (gr_screen.mode == GR_STUB) {
|
||||
return;
|
||||
}
|
||||
@@ -797,10 +797,10 @@ void gr_string(float sx, float sy, const char* s, int resize_mode, int in_length
|
||||
}
|
||||
|
||||
size_t length;
|
||||
if (in_length < 0) {
|
||||
if (in_length == std::string::npos) {
|
||||
length = strlen(s);
|
||||
} else {
|
||||
length = (size_t) in_length;
|
||||
length = in_length;
|
||||
}
|
||||
|
||||
FSFont* currentFont = FontManager::getCurrentFont();
|
||||
|
||||
@@ -60,7 +60,7 @@ void gr_bitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode =
|
||||
* @param resize_mode The mode for translating the screen positions
|
||||
* @param length The number of bytes in the string to render. -1 will render the whole string.
|
||||
*/
|
||||
void gr_string(float x, float y, const char* string, int resize_mode = GR_RESIZE_FULL, int length = -1);
|
||||
void gr_string(float x, float y, const char* string, int resize_mode = GR_RESIZE_FULL, size_t length = std::string::npos);
|
||||
/**
|
||||
* @brief Renders the specified string to the screen using the current font and color
|
||||
* @param x The x-coordinate
|
||||
@@ -69,7 +69,7 @@ void gr_string(float x, float y, const char* string, int resize_mode = GR_RESIZE
|
||||
* @param resize_mode The mode for translating the screen positions
|
||||
* @param length The number of bytes in the string to render. -1 will render the whole string.
|
||||
*/
|
||||
inline void gr_string(int x, int y, const char* string, int resize_mode = GR_RESIZE_FULL, int length = -1)
|
||||
inline void gr_string(int x, int y, const char* string, int resize_mode = GR_RESIZE_FULL, size_t length = std::string::npos)
|
||||
{
|
||||
gr_string(i2fl(x), i2fl(y), string, resize_mode, length);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ auto ShadowQualityOption = options::OptionBuilder<ShadowQuality>("Graphics.Shado
|
||||
{ShadowQuality::Ultra, {"Ultra", 1721}}})
|
||||
.change_listener([](ShadowQuality val, bool initial) {if (initial) {Shadow_quality = val;}return initial;})
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(ShadowQuality::Disabled)
|
||||
.importance(80)
|
||||
.finish();
|
||||
|
||||
@@ -669,7 +669,7 @@ int gr_get_dynamic_font_lines(int number_default_lines) {
|
||||
return fl2i((number_default_lines * 10) / (gr_get_font_height() + 1));
|
||||
}
|
||||
|
||||
void gr_get_string_size(int *w1, int *h1, const char *text, int len)
|
||||
void gr_get_string_size(int *w1, int *h1, const char *text, size_t len)
|
||||
{
|
||||
if (!FontManager::isReady())
|
||||
{
|
||||
@@ -685,7 +685,7 @@ void gr_get_string_size(int *w1, int *h1, const char *text, int len)
|
||||
float w = 0.0f;
|
||||
float h = 0.0f;
|
||||
|
||||
FontManager::getCurrentFont()->getStringSize(text, static_cast<size_t>(len), -1, &w, &h);
|
||||
FontManager::getCurrentFont()->getStringSize(text, len, -1, &w, &h);
|
||||
|
||||
if (w1)
|
||||
{
|
||||
|
||||
+47
-38
@@ -81,7 +81,7 @@ int HUD_color_blue = 0;
|
||||
int HUD_color_alpha = HUD_COLOR_ALPHA_DEFAULT; // 1 -> HUD_COLOR_ALPHA_USER_MAX
|
||||
|
||||
int HUD_draw = 1;
|
||||
int HUD_contrast = 0; // high or lo contrast (for nebula, etc)
|
||||
bool HUD_high_contrast = false; // high or low contrast (for nebula, etc)
|
||||
bool HUD_shadows = false;
|
||||
|
||||
// Goober5000
|
||||
@@ -363,7 +363,7 @@ void HudGauge::initPosition(int x, int y)
|
||||
position[1] = y;
|
||||
}
|
||||
|
||||
void HudGauge::getPosition(int *x, int *y)
|
||||
void HudGauge::getPosition(int *x, int *y) const
|
||||
{
|
||||
*x = position[0];
|
||||
*y = position[1];
|
||||
@@ -390,7 +390,7 @@ void HudGauge::initFont(int input_font_num)
|
||||
}
|
||||
}
|
||||
|
||||
int HudGauge::getFont()
|
||||
int HudGauge::getFont() const
|
||||
{
|
||||
return font_num;
|
||||
}
|
||||
@@ -404,7 +404,7 @@ void HudGauge::initOriginAndOffset(float originX, float originY, int offsetX, in
|
||||
tabled_offset[1] = offsetY;
|
||||
}
|
||||
|
||||
void HudGauge::getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY)
|
||||
void HudGauge::getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY) const
|
||||
{
|
||||
*originX = tabled_origin[0];
|
||||
*originY = tabled_origin[1];
|
||||
@@ -420,19 +420,24 @@ void HudGauge::initCoords(bool use_coords, int coordsX, int coordsY)
|
||||
tabled_coords[1] = coordsY;
|
||||
}
|
||||
|
||||
void HudGauge::getCoords(bool *use_coords, int *coordsX, int *coordsY)
|
||||
void HudGauge::getCoords(bool *use_coords, int *coordsX, int *coordsY) const
|
||||
{
|
||||
*use_coords = tabled_use_coords;
|
||||
*coordsX = tabled_coords[0];
|
||||
*coordsY = tabled_coords[1];
|
||||
}
|
||||
|
||||
const char* HudGauge::getCustomGaugeName()
|
||||
void HudGauge::initHiRes(const char* fname)
|
||||
{
|
||||
hi_res = (strncmp(fname, "2_", 2) == 0);
|
||||
}
|
||||
|
||||
const char* HudGauge::getCustomGaugeName() const
|
||||
{
|
||||
return custom_name;
|
||||
}
|
||||
|
||||
const char* HudGauge::getCustomGaugeText()
|
||||
const char* HudGauge::getCustomGaugeText() const
|
||||
{
|
||||
return custom_text.c_str();
|
||||
}
|
||||
@@ -483,17 +488,17 @@ void HudGauge::setGaugeColor(int bright_index)
|
||||
if(bright_index != HUD_C_NONE){
|
||||
switch(bright_index){
|
||||
case HUD_C_DIM:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_NORMAL:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_BRIGHT:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
|
||||
@@ -523,15 +528,15 @@ void HudGauge::setGaugeColor(int bright_index)
|
||||
} else {
|
||||
switch(maybeFlashSexp()) {
|
||||
case 0:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
case 1:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
break;
|
||||
default:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(&gauge_color, gauge_color.red, gauge_color.green, gauge_color.blue, alpha);
|
||||
}
|
||||
}
|
||||
@@ -539,33 +544,37 @@ void HudGauge::setGaugeColor(int bright_index)
|
||||
gr_set_color_fast(&gauge_color);
|
||||
}
|
||||
|
||||
bool HudGauge::isCustom()
|
||||
bool HudGauge::isCustom() const
|
||||
{
|
||||
return custom_gauge;
|
||||
}
|
||||
|
||||
int HudGauge::getBaseWidth()
|
||||
bool HudGauge::isHiRes() const
|
||||
{
|
||||
return hi_res;
|
||||
}
|
||||
|
||||
int HudGauge::getBaseWidth() const
|
||||
{
|
||||
return base_w;
|
||||
}
|
||||
|
||||
int HudGauge::getBaseHeight()
|
||||
int HudGauge::getBaseHeight() const
|
||||
{
|
||||
return base_h;
|
||||
}
|
||||
|
||||
float HudGauge::getAspectQuotient()
|
||||
float HudGauge::getAspectQuotient() const
|
||||
{
|
||||
return aspect_quotient;
|
||||
}
|
||||
|
||||
int HudGauge::getConfigType()
|
||||
int HudGauge::getConfigType() const
|
||||
{
|
||||
//return gauge_type;
|
||||
return gauge_config;
|
||||
}
|
||||
|
||||
int HudGauge::getObjectType()
|
||||
int HudGauge::getObjectType() const
|
||||
{
|
||||
return gauge_object;
|
||||
}
|
||||
@@ -588,7 +597,7 @@ void HudGauge::updateColor(int r, int g, int b, int a)
|
||||
gr_init_alphacolor(&gauge_color, r, g, b, a);
|
||||
}
|
||||
|
||||
const color& HudGauge::getColor()
|
||||
const color& HudGauge::getColor() const
|
||||
{
|
||||
return gauge_color;
|
||||
}
|
||||
@@ -613,12 +622,12 @@ void HudGauge::initCockpit_view_choice(int cockpit_view_choice)
|
||||
render_for_cockpit_toggle = cockpit_view_choice;
|
||||
}
|
||||
|
||||
bool HudGauge::isOffbyDefault()
|
||||
bool HudGauge::isOffbyDefault() const
|
||||
{
|
||||
return off_by_default;
|
||||
}
|
||||
|
||||
bool HudGauge::isActive()
|
||||
bool HudGauge::isActive() const
|
||||
{
|
||||
return active && !sexp_override;
|
||||
}
|
||||
@@ -643,7 +652,7 @@ void HudGauge::startPopUp(int time)
|
||||
popup_timer = timestamp(time);
|
||||
}
|
||||
|
||||
int HudGauge::popUpActive()
|
||||
int HudGauge::popUpActive() const
|
||||
{
|
||||
//Assert(gauge_index >=0 && gauge_index < NUM_HUD_GAUGES);
|
||||
if ( !pop_up ) {
|
||||
@@ -673,7 +682,7 @@ void HudGauge::startFlashSexp()
|
||||
flash_status = false;
|
||||
}
|
||||
|
||||
bool HudGauge::flashExpiredSexp()
|
||||
bool HudGauge::flashExpiredSexp() const
|
||||
{
|
||||
if(timestamp_elapsed(flash_duration)) {
|
||||
return true;
|
||||
@@ -1147,7 +1156,7 @@ void HudGauge::initialize()
|
||||
sexp_lock_color = false;
|
||||
}
|
||||
|
||||
bool HudGauge::canRender()
|
||||
bool HudGauge::canRender() const
|
||||
{
|
||||
if (sexp_override) {
|
||||
return false;
|
||||
@@ -1293,12 +1302,12 @@ void HUD_init()
|
||||
last_percent_throttle = 0.0f;
|
||||
|
||||
// default to high contrast in the nebula
|
||||
HUD_contrast = 0;
|
||||
HUD_high_contrast = false;
|
||||
HUD_draw = 1;
|
||||
HUD_disable_except_messages = 0;
|
||||
|
||||
if(The_mission.flags[Mission::Mission_Flags::Fullneb]){
|
||||
HUD_contrast = 1;
|
||||
HUD_high_contrast = true;
|
||||
}
|
||||
|
||||
// reset to infinite
|
||||
@@ -3310,17 +3319,17 @@ void hud_set_gauge_color(int gauge_index, int bright_index)
|
||||
if(bright_index != HUD_C_NONE){
|
||||
switch(bright_index){
|
||||
case HUD_C_DIM:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_NORMAL:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
|
||||
case HUD_C_BRIGHT:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
|
||||
@@ -3350,15 +3359,15 @@ void hud_set_gauge_color(int gauge_index, int bright_index)
|
||||
} else {
|
||||
switch(flash_status) {
|
||||
case 0:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_DIM_HI : HUD_NEW_ALPHA_DIM;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
case 1:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_BRIGHT_HI : HUD_NEW_ALPHA_BRIGHT;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
default:
|
||||
alpha = HUD_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
alpha = HUD_high_contrast ? HUD_NEW_ALPHA_NORMAL_HI : HUD_NEW_ALPHA_NORMAL;
|
||||
gr_init_alphacolor(use_color, use_color->red, use_color->green, use_color->blue, alpha);
|
||||
break;
|
||||
}
|
||||
@@ -3861,12 +3870,12 @@ void hud_save_restore_camera_data(int save)
|
||||
|
||||
void hud_toggle_contrast()
|
||||
{
|
||||
HUD_contrast = !HUD_contrast;
|
||||
HUD_high_contrast = !HUD_high_contrast;
|
||||
}
|
||||
|
||||
void hud_set_contrast(int high)
|
||||
void hud_set_contrast(bool high)
|
||||
{
|
||||
HUD_contrast = high;
|
||||
HUD_high_contrast = high;
|
||||
}
|
||||
|
||||
void hud_toggle_shadows()
|
||||
@@ -3985,7 +3994,7 @@ HudGauge(HUD_OBJECT_MULTI_MSG, HUD_MESSAGE_LINES, false, true, 0, 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
bool HudGaugeMultiMsg::canRender()
|
||||
bool HudGaugeMultiMsg::canRender() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
+24
-21
@@ -69,7 +69,7 @@ enum class HudAlignment
|
||||
};
|
||||
|
||||
extern int HUD_draw;
|
||||
extern int HUD_contrast;
|
||||
extern bool HUD_high_contrast;
|
||||
extern bool HUD_shadows;
|
||||
|
||||
#define HUD_NUM_COLOR_LEVELS 16
|
||||
@@ -203,7 +203,7 @@ int hud_disabled_except_messages();
|
||||
|
||||
// contrast stuff
|
||||
void hud_toggle_contrast();
|
||||
void hud_set_contrast(int high);
|
||||
void hud_set_contrast(bool high);
|
||||
void hud_toggle_shadows();
|
||||
|
||||
class HudGauge
|
||||
@@ -223,6 +223,7 @@ protected:
|
||||
bool tabled_use_coords;
|
||||
int tabled_coords[2];
|
||||
float aspect_quotient;
|
||||
bool hi_res;
|
||||
|
||||
bool lock_color;
|
||||
bool sexp_lock_color;
|
||||
@@ -271,28 +272,30 @@ public:
|
||||
void initFont(int input_font_num);
|
||||
void initOriginAndOffset(float originX, float originY, int offsetX, int offsetY);
|
||||
void initCoords(bool use_coords, int coordsX, int coordsY);
|
||||
void initHiRes(const char* fname);
|
||||
|
||||
virtual void initSlew(bool slew);
|
||||
void initCockpitTarget(const char* display_name, int _target_x, int _target_y, int _target_w, int _target_h, int _canvas_w, int _canvas_h);
|
||||
void initRenderStatus(bool render);
|
||||
|
||||
bool isCustom();
|
||||
int getBaseWidth();
|
||||
int getBaseHeight();
|
||||
float getAspectQuotient();
|
||||
bool isCustom() const;
|
||||
bool isHiRes() const;
|
||||
int getBaseWidth() const;
|
||||
int getBaseHeight() const;
|
||||
float getAspectQuotient() const;
|
||||
|
||||
int getConfigType();
|
||||
int getObjectType();
|
||||
void getPosition(int *x, int *y);
|
||||
bool isOffbyDefault();
|
||||
bool isActive();
|
||||
int getConfigType() const;
|
||||
int getObjectType() const;
|
||||
void getPosition(int *x, int *y) const;
|
||||
bool isOffbyDefault() const;
|
||||
bool isActive() const;
|
||||
|
||||
int getFont();
|
||||
void getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY);
|
||||
void getCoords(bool* use_coords, int* coordsX, int* coordsY);
|
||||
int getFont() const;
|
||||
void getOriginAndOffset(float *originX, float *originY, int *offsetX, int *offsetY) const;
|
||||
void getCoords(bool* use_coords, int* coordsX, int* coordsY) const;
|
||||
|
||||
void updateColor(int r, int g, int b, int a = 255);
|
||||
const color& getColor();
|
||||
const color& getColor() const;
|
||||
void lockConfigColor(bool lock);
|
||||
void sexpLockConfigColor(bool lock);
|
||||
void updateActive(bool show);
|
||||
@@ -305,21 +308,21 @@ public:
|
||||
// For flashing gauges in training missions
|
||||
void startFlashSexp();
|
||||
int maybeFlashSexp();
|
||||
bool flashExpiredSexp();
|
||||
bool flashExpiredSexp() const;
|
||||
void resetTimers();
|
||||
|
||||
// For updating custom gauges
|
||||
const char* getCustomGaugeName();
|
||||
const char* getCustomGaugeName() const;
|
||||
void updateCustomGaugeText(const char* txt);
|
||||
void updateCustomGaugeText(const SCP_string& txt);
|
||||
const char* getCustomGaugeText();
|
||||
const char* getCustomGaugeText() const;
|
||||
|
||||
void startPopUp(int time=4000);
|
||||
int popUpActive();
|
||||
int popUpActive() const;
|
||||
|
||||
virtual void preprocess();
|
||||
virtual void render(float frametime);
|
||||
virtual bool canRender();
|
||||
virtual bool canRender() const;
|
||||
virtual void pageIn();
|
||||
virtual void initialize();
|
||||
virtual void onFrame(float frametime);
|
||||
@@ -549,7 +552,7 @@ class HudGaugeMultiMsg: public HudGauge
|
||||
protected:
|
||||
public:
|
||||
HudGaugeMultiMsg();
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
void render(float frametime) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ void ssm_create(object *target, vec3d *start, size_t ssm_index, ssm_firing_info
|
||||
|
||||
count = Ssm_info[ssm_index].count;
|
||||
if (Ssm_info[ssm_index].max_count != -1 && (Ssm_info[ssm_index].max_count - count) > 0) {
|
||||
count += Random::next(count, Ssm_info[ssm_index].max_count);
|
||||
count = Random::next(count, Ssm_info[ssm_index].max_count);
|
||||
}
|
||||
|
||||
// override in multiplayer
|
||||
|
||||
@@ -1323,10 +1323,8 @@ void hud_config_button_do(int n)
|
||||
break;
|
||||
}
|
||||
|
||||
if (HC_current_file >= (int)HC_preset_filenames.size()) {
|
||||
if ((++HC_current_file) >= static_cast<int> (HC_preset_filenames.size())) {
|
||||
HC_current_file = 0;
|
||||
} else {
|
||||
HC_current_file++;
|
||||
}
|
||||
|
||||
// load em up
|
||||
|
||||
@@ -305,7 +305,7 @@ void HudGaugeMessages::processMessageBuffer()
|
||||
ptr = strstr(msg, NOX(": "));
|
||||
if ( ptr ) {
|
||||
int sw;
|
||||
gr_get_string_size(&sw, nullptr, msg, (int)(ptr + 2 - msg));
|
||||
gr_get_string_size(&sw, nullptr, msg, (ptr + 2 - msg));
|
||||
offset = sw;
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ void hud_add_msg_to_scrollback(const char *text, int source, int t)
|
||||
|
||||
// determine the length of the sender's name for underlining
|
||||
if (ptr) {
|
||||
gr_get_string_size(&w, nullptr, buf, (int)(ptr - buf));
|
||||
gr_get_string_size(&w, nullptr, buf, (ptr - buf));
|
||||
}
|
||||
|
||||
// create the new node for the vector
|
||||
@@ -843,7 +843,7 @@ void hud_initialize_scrollback_lines()
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
gr_get_string_size(&width, &height, node_msg.text.c_str(), (int)node_msg.text.length());
|
||||
gr_get_string_size(&width, &height, node_msg.text.c_str(), node_msg.text.length());
|
||||
|
||||
int max_width = Hud_mission_log_list2_coords[gr_screen.res][2];
|
||||
if (width > max_width) {
|
||||
@@ -1264,7 +1264,7 @@ void HudGaugeTalkingHead::pageIn()
|
||||
bm_page_in_aabitmap( Head_frame.first_frame, Head_frame.num_frames );
|
||||
}
|
||||
|
||||
bool HudGaugeTalkingHead::canRender()
|
||||
bool HudGaugeTalkingHead::canRender() const
|
||||
{
|
||||
if (sexp_override) {
|
||||
return false;
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
void pageIn() override;
|
||||
void render(float frametime) override;
|
||||
void initialize() override;
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
};
|
||||
|
||||
class HudGaugeFixedMessages: public HudGauge
|
||||
|
||||
@@ -1611,6 +1611,7 @@ void load_gauge_lag(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -1666,6 +1667,7 @@ void load_gauge_mini_shields(gauge_settings* settings)
|
||||
hud_gauge->init2DigitOffsets(Mini_2digit_offsets[0], Mini_2digit_offsets[1]);
|
||||
hud_gauge->init3DigitOffsets(Mini_3digit_offsets[0], Mini_3digit_offsets[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -1762,6 +1764,7 @@ void load_gauge_weapon_energy(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initEnergyHeight(Wenergy_h);
|
||||
hud_gauge->initTextOffsets(Wenergy_text_offsets[0], Wenergy_text_offsets[1]);
|
||||
hud_gauge->initAlignments(text_alignment, weapon_alignment);
|
||||
@@ -1915,6 +1918,7 @@ void load_gauge_escort_view(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initEntryHeight(entry_h);
|
||||
hud_gauge->initEntryStaggerWidth(entry_stagger_w);
|
||||
hud_gauge->initBottomBgOffset(bottom_bg_offset);
|
||||
@@ -1976,6 +1980,7 @@ void load_gauge_afterburner(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initEnergyHeight(energy_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -2018,6 +2023,7 @@ void load_gauge_mission_time(gauge_settings* settings)
|
||||
hud_gauge->initTextOffsets(time_text_offsets[0], time_text_offsets[1]);
|
||||
hud_gauge->initValueOffsets(time_val_offsets[0], time_val_offsets[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -2111,6 +2117,7 @@ void load_gauge_threat_indicator(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_arc, fname_laser, fname_lock);
|
||||
hud_gauge->initHiRes(fname_arc);
|
||||
hud_gauge->initLaserWarnOffsets(Laser_warn_offsets[0], Laser_warn_offsets[1]);
|
||||
hud_gauge->initLockWarnOffsets(Lock_warn_offsets[0], Lock_warn_offsets[1]);
|
||||
|
||||
@@ -2178,6 +2185,7 @@ void load_gauge_center_reticle(gauge_settings* settings)
|
||||
stuff_int(&autoaim_frame);
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initFirepointDisplay(firepoints, scaleX, scaleY, size);
|
||||
hud_gauge->setAutoaimFrame(autoaim_frame);
|
||||
|
||||
@@ -2351,6 +2359,7 @@ void load_gauge_throttle(gauge_settings* settings)
|
||||
hud_gauge->initGlideOffsets(glide_offset[0], glide_offset[1], custom_glide);
|
||||
hud_gauge->initMatchSpeedOffsets(match_speed_offset[0], match_speed_offset[1], custom_match);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->showBackground(show_background);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
@@ -2435,6 +2444,7 @@ void load_gauge_ets_retail(gauge_settings* settings)
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initGaugePositions(gauge_positions);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
@@ -2502,6 +2512,7 @@ void load_gauge_ets_weapons(gauge_settings* settings)
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -2565,6 +2576,7 @@ void load_gauge_ets_shields(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initLetter(letter);
|
||||
hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
|
||||
@@ -2633,6 +2645,7 @@ void load_gauge_ets_engines(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initBarHeight(bar_h);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
|
||||
hud_gauge->initLetter(letter);
|
||||
hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
|
||||
@@ -2708,6 +2721,7 @@ void load_gauge_extra_target_data(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBracketOffsets(bracket_offsets[0], bracket_offsets[1]);
|
||||
hud_gauge->initDockOffsets(dock_offsets[0], dock_offsets[1]);
|
||||
hud_gauge->initDockMaxWidth(dock_max_w);
|
||||
@@ -2830,6 +2844,7 @@ void load_gauge_radar_std(gauge_settings* settings)
|
||||
// Only load this if the user hasn't specified a preference
|
||||
if (Cmdline_orb_radar == 0) {
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBlipRadius(Radar_blip_radius_normal, Radar_blip_radius_target);
|
||||
hud_gauge->initCenterOffsets(Radar_center_offsets[0], Radar_center_offsets[1]);
|
||||
hud_gauge->initDistanceInfinityOffsets(Radar_dist_offsets[2][0], Radar_dist_offsets[2][1]);
|
||||
@@ -2926,6 +2941,7 @@ void load_gauge_radar_orb(gauge_settings* settings)
|
||||
//only load this if the user actually wants to use the orb radar.
|
||||
if (Cmdline_orb_radar == 1) {
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initBlipRadius(Radar_blip_radius_normal, Radar_blip_radius_target);
|
||||
hud_gauge->initCenterOffsets(Radar_center_offsets[0], Radar_center_offsets[1]);
|
||||
hud_gauge->initDistanceInfinityOffsets(Radar_dist_offsets[2][0], Radar_dist_offsets[2][1]);
|
||||
@@ -3126,6 +3142,7 @@ void load_gauge_radar_dradis(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initRadius(Radar_radius[0], Radar_radius[1]);
|
||||
hud_gauge->initBitmaps(xy_fname, xz_yz_fname, sweep_fname, target_fname, unknown_fname);
|
||||
hud_gauge->initHiRes(xy_fname);
|
||||
hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
|
||||
hud_gauge->initSound(loop_snd, loop_snd_volume, arrival_beep_snd, departure_beep_snd, stealth_arrival_snd, stealth_departure_snd, arrival_beep_delay, departure_beep_delay);
|
||||
hud_gauge->initChase_view_only(settings->chase_view_only);
|
||||
@@ -3345,6 +3362,7 @@ void load_gauge_target_monitor(gauge_settings* settings)
|
||||
hud_gauge->initGaugeWirecolor(wirecolor);
|
||||
hud_gauge->initGaugeWirecolorOverride(wirecoloroverride);
|
||||
hud_gauge->initBitmaps(fname_monitor, fname_monitor_mask, fname_integrity, fname_static);
|
||||
hud_gauge->initHiRes(fname_monitor);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -3429,6 +3447,7 @@ void load_gauge_squad_message(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initHeaderOffsets(Header_offsets[0], Header_offsets[1]);
|
||||
hud_gauge->initItemStartOffsets(Item_start_offsets[0], Item_start_offsets[1]);
|
||||
hud_gauge->initMiddleFrameStartOffsetY(Middle_frame_start_offset_y);
|
||||
@@ -3501,6 +3520,7 @@ void load_gauge_objective_notify(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initObjTextOffsetY(Objective_text_offset_y);
|
||||
hud_gauge->initObjValueOffsetY(Objective_text_val_offset_y);
|
||||
hud_gauge->initSubspaceTextOffsetY(Subspace_text_offset_y);
|
||||
@@ -3769,6 +3789,7 @@ void load_gauge_directives(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initMiddleFrameOffsetY(middle_frame_offset_y);
|
||||
hud_gauge->initTextHeight(text_h);
|
||||
hud_gauge->initBottomBgOffset(bottom_bg_offset);
|
||||
@@ -3827,6 +3848,7 @@ void load_gauge_talking_head(gauge_settings* settings)
|
||||
hud_gauge->initAnimOffsets(Anim_offsets[0], Anim_offsets[1]);
|
||||
hud_gauge->initAnimSizes(Anim_size[0], Anim_size[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initHeaderOffsets(Header_offsets[0], Header_offsets[1]);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
@@ -3866,6 +3888,7 @@ void load_gauge_countermeasures(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initCountTextOffsets(cm_text_offset[0], cm_text_offset[1]);
|
||||
hud_gauge->initCountValueOffsets(cm_text_val_offset[0], cm_text_val_offset[1]);
|
||||
|
||||
@@ -3924,6 +3947,7 @@ void load_gauge_auto_target(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initAutoTextOffsets(auto_text_offset[0], auto_text_offset[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initTargetTextOffsets(target_text_offset[0], target_text_offset[1]);
|
||||
hud_gauge->initOnColor(on_color[0], on_color[1], on_color[2], on_color[3]);
|
||||
hud_gauge->initOffColor(off_color[0], off_color[1], off_color[2], off_color[3]);
|
||||
@@ -3982,6 +4006,7 @@ void load_gauge_auto_speed(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initAutoTextOffsets(auto_text_offset[0], auto_text_offset[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initSpeedTextOffsets(speed_text_offset[0], speed_text_offset[1]);
|
||||
hud_gauge->initOnColor(on_color[0], on_color[1], on_color[2], on_color[3]);
|
||||
hud_gauge->initOffColor(off_color[0], off_color[1], off_color[2], off_color[3]);
|
||||
@@ -4121,6 +4146,7 @@ void load_gauge_wingman_status(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_left, fname_middle, fname_right, fname_dots);
|
||||
hud_gauge->initHiRes(fname_left);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initFixedHeaderPosition(fixed_header_position);
|
||||
hud_gauge->initLeftFrameEndX(left_frame_end_x);
|
||||
@@ -4218,6 +4244,7 @@ void load_gauge_damage(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
|
||||
hud_gauge->initHiRes(fname_top);
|
||||
hud_gauge->initHullIntegOffsets(hull_integ_offsets[0], hull_integ_offsets[1]);
|
||||
hud_gauge->initHullIntegValueOffsetX(hull_integ_val_offset_x);
|
||||
hud_gauge->initLineHeight(line_h);
|
||||
@@ -4285,6 +4312,7 @@ void load_gauge_support(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initTextDockOffsetX(text_dock_offset_x);
|
||||
hud_gauge->initTextDockValueOffsetX(text_dock_val_offset_x);
|
||||
@@ -4504,6 +4532,7 @@ void load_gauge_weapon_linking(gauge_settings* settings)
|
||||
hud_gauge->init2SecondaryOffsets(Weapon_link_offsets[LINK_TWO_SECONDARY][0], Weapon_link_offsets[LINK_TWO_SECONDARY][1]);
|
||||
hud_gauge->init3SecondaryOffsets(Weapon_link_offsets[LINK_THREE_SECONDARY][0], Weapon_link_offsets[LINK_THREE_SECONDARY][1]);
|
||||
hud_gauge->initBitmaps(fname_arc, fname_primary_link_1, fname_primary_link_2, fname_secondary_link_1, fname_secondary_link_2, fname_secondary_link_3);
|
||||
hud_gauge->initHiRes(fname_arc);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -4692,6 +4721,7 @@ void load_gauge_lock(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_lock, fname_spin);
|
||||
hud_gauge->initHiRes(fname_lock);
|
||||
hud_gauge->initLoopLockedAnim(loop_locked_anim);
|
||||
hud_gauge->initBlinkLockedAnim(blink_locked_anim);
|
||||
hud_gauge->initGaugeHalfSize(Lock_gauge_half_w, Lock_gauge_half_h);
|
||||
@@ -4766,6 +4796,7 @@ void load_gauge_brackets(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initMinSubTargetBoxSizes(min_subtarget_box[0], min_subtarget_box[1]);
|
||||
hud_gauge->initMinTargetBoxSizes(min_target_box[0], min_target_box[1]);
|
||||
|
||||
@@ -4957,6 +4988,7 @@ void load_gauge_lead(gauge_settings* settings)
|
||||
|
||||
hud_gauge->initHalfSize(Lead_indicator_half[0], Lead_indicator_half[1]);
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -5015,6 +5047,7 @@ void load_gauge_lead_sight(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
|
||||
gauge_assign_common(settings, std::move(hud_gauge));
|
||||
}
|
||||
@@ -5059,6 +5092,7 @@ void load_gauge_kills(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname);
|
||||
hud_gauge->initHiRes(fname);
|
||||
hud_gauge->initTextOffsets(text_offsets[0], text_offsets[1]);
|
||||
hud_gauge->initTextValueOffsets(text_value_offsets[0], text_value_offsets[1]);
|
||||
|
||||
@@ -5299,6 +5333,7 @@ void load_gauge_primary_weapons(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_first, fname_entry, fname_last);
|
||||
hud_gauge->initHiRes(fname_first);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initHeaderText(header_text);
|
||||
hud_gauge->initBgFirstHeight(first_bg_h);
|
||||
@@ -5413,6 +5448,7 @@ void load_gauge_secondary_weapons(gauge_settings* settings)
|
||||
}
|
||||
|
||||
hud_gauge->initBitmaps(fname_first, fname_entry, fname_last);
|
||||
hud_gauge->initHiRes(fname_first);
|
||||
hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
|
||||
hud_gauge->initHeaderText(header_text);
|
||||
hud_gauge->initBgFirstHeight(first_bg_h);
|
||||
|
||||
@@ -2635,7 +2635,7 @@ bool HudGaugeSquadMessage::maybeFlashPageScroll(bool flash_fast)
|
||||
return draw_bright;
|
||||
}
|
||||
|
||||
bool HudGaugeSquadMessage::canRender()
|
||||
bool HudGaugeSquadMessage::canRender() const
|
||||
{
|
||||
if(hud_disabled_except_messages() && !message_gauge) {
|
||||
return false;
|
||||
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
void initPgDnOffsets(int x, int y);
|
||||
|
||||
void render(float frametime) override;
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
void pageIn() override;
|
||||
void initialize() override;
|
||||
void startFlashPageScroll(int duration = 1400);
|
||||
|
||||
+14
-2
@@ -2627,12 +2627,24 @@ void hud_target_in_reticle_old()
|
||||
|
||||
target_obj = hud_reticle_pick_target();
|
||||
if ( target_obj != NULL ) {
|
||||
int oldTargetNum = Player_ai->target_objnum;
|
||||
set_target_objnum( Player_ai, OBJ_INDEX(target_obj) );
|
||||
hud_shield_hit_reset(target_obj);
|
||||
|
||||
if ( target_obj->type == OBJ_SHIP ) {
|
||||
hud_maybe_set_sorted_turret_subsys(&Ships[target_obj->instance]);
|
||||
hud_restore_subsystem_target(&Ships[target_obj->instance]);
|
||||
ship* shipp = &Ships[target_obj->instance];
|
||||
|
||||
// if the player is attempting to target the same ship under their reticule again
|
||||
// then lets select the nearest subsystem for them.
|
||||
if (Automatically_select_subsystem_under_reticle_when_targeting_same_ship &&
|
||||
Ship_info[shipp->ship_info_index].is_big_or_huge() &&
|
||||
oldTargetNum == Player_ai->target_objnum) {
|
||||
hud_target_subsystem_in_reticle();
|
||||
}
|
||||
else {
|
||||
hud_maybe_set_sorted_turret_subsys(shipp);
|
||||
hud_restore_subsystem_target(shipp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+16
-10
@@ -24,6 +24,10 @@ int radar_iff_color[5][2][4];
|
||||
int iff_bright_delta;
|
||||
int *iff_color_brightness = &iff_bright_delta;
|
||||
|
||||
int IFF_COLOR_SELECTION = 0;
|
||||
int IFF_COLOR_MESSAGE = 1;
|
||||
int IFF_COLOR_TAGGED = 2;
|
||||
|
||||
// global only to file
|
||||
SCP_vector <std::pair<color, color>> Iff_colors; // AL 1-2-97: Create two IFF colors, regular and bright
|
||||
|
||||
@@ -249,28 +253,28 @@ void parse_iff_table(const char* filename)
|
||||
if ((optional_string("$Selection Color:")) || (optional_string("$Selection Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
IFF_COLOR_SELECTION = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0xff);
|
||||
else if (!Parsing_modular_table)
|
||||
IFF_COLOR_SELECTION = iff_init_color(0xff, 0xff, 0xff);
|
||||
|
||||
// Marks the ship currently saying something
|
||||
if ((optional_string("$Message Color:")) || (optional_string("$Message Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
IFF_COLOR_MESSAGE = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0x7f, 0x7f, 0x7f);
|
||||
else if (!Parsing_modular_table)
|
||||
IFF_COLOR_MESSAGE = iff_init_color(0x7f, 0x7f, 0x7f);
|
||||
|
||||
// Marks the tagged ships
|
||||
if ((optional_string("$Tagged Color:")) || (optional_string("$Tagged Colour:")))
|
||||
{
|
||||
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
|
||||
iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
IFF_COLOR_TAGGED = iff_init_color(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
else
|
||||
iff_init_color(0xff, 0xff, 0x00);
|
||||
else if (!Parsing_modular_table)
|
||||
IFF_COLOR_TAGGED = iff_init_color(0xff, 0xff, 0x00);
|
||||
|
||||
// init radar blips colour table
|
||||
int a_bright, a_dim;
|
||||
@@ -579,7 +583,9 @@ int iff_lookup(const char *iff_name)
|
||||
*/
|
||||
int iff_get_attackee_mask(int attacker_team)
|
||||
{
|
||||
Assert(attacker_team >= 0 && attacker_team < (int)Iff_info.size());
|
||||
Assertion(SCP_vector_inbounds(Iff_info, attacker_team), "Attempted to get the attackee mask of an attacker team that is out of bounds");
|
||||
if (!SCP_vector_inbounds(Iff_info, attacker_team))
|
||||
return 0;
|
||||
|
||||
// All teams attack all other teams.
|
||||
if (Mission_all_attack)
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
class object;
|
||||
|
||||
// Goober5000 - new IFF color system
|
||||
#define IFF_COLOR_SELECTION 0
|
||||
#define IFF_COLOR_MESSAGE 1
|
||||
#define IFF_COLOR_TAGGED 2
|
||||
// Now variables so that modular tables can actually affect them. -MageKing17
|
||||
extern int IFF_COLOR_SELECTION;
|
||||
extern int IFF_COLOR_MESSAGE;
|
||||
extern int IFF_COLOR_TAGGED;
|
||||
|
||||
enum IFF_hotkey_team { Default = -1, None = 0, Friendly, Hostile };
|
||||
|
||||
|
||||
+4
-4
@@ -241,7 +241,7 @@ SCP_vector<Joystick*> joystick_enumerator()
|
||||
auto JoystickOption = options::OptionBuilder<Joystick*>("Input.Joystick",
|
||||
std::pair<const char*, int>{"Joystick 0", 1705},
|
||||
std::pair<const char*, int>{"The current joystick 0", 1706})
|
||||
.category("Input") // Category this option shows up in the scripting heirachy
|
||||
.category(std::make_pair("Input", 1827)) // Category this option shows up in the scripting heirachy
|
||||
.deserializer(joystick_deserialize) // callback for json to C++
|
||||
.serializer(joystick_serializer) // callback for C++ to json
|
||||
.display(joystick_display) // callback for constructing the display label
|
||||
@@ -255,7 +255,7 @@ auto JoystickOption = options::OptionBuilder<Joystick*>("Input.Joystick",
|
||||
auto JoystickOption1 = options::OptionBuilder<Joystick*>("Input.Joystick1",
|
||||
std::pair<const char*, int>{"Joystick 1", 1707},
|
||||
std::pair<const char*, int>{"The current joystick 1", 1708})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.deserializer(joystick_deserialize)
|
||||
.serializer(joystick_serializer)
|
||||
.display(joystick_display)
|
||||
@@ -269,7 +269,7 @@ auto JoystickOption1 = options::OptionBuilder<Joystick*>("Input.Joystick1",
|
||||
auto JoystickOption2 = options::OptionBuilder<Joystick*>("Input.Joystick2",
|
||||
std::pair<const char*, int>{"Joystick 2", 1709},
|
||||
std::pair<const char*, int>{"The current joystick 2", 1710})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.deserializer(joystick_deserialize)
|
||||
.serializer(joystick_serializer)
|
||||
.display(joystick_display)
|
||||
@@ -283,7 +283,7 @@ auto JoystickOption2 = options::OptionBuilder<Joystick*>("Input.Joystick2",
|
||||
auto JoystickOption3 = options::OptionBuilder<Joystick*>("Input.Joystick3",
|
||||
std::pair<const char*, int>{"Joystick 3", 1711},
|
||||
std::pair<const char*, int>{"The current joystick 3", 1712})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.deserializer(joystick_deserialize)
|
||||
.serializer(joystick_serializer)
|
||||
.display(joystick_display)
|
||||
|
||||
@@ -49,7 +49,7 @@ static haptic_effect_t pExplode;
|
||||
static auto ForceFeedbackOption = options::OptionBuilder<bool>("Input.ForceFeedback",
|
||||
std::pair<const char*, int>{"Force Feedback", 1728},
|
||||
std::pair<const char*, int>{"Enable or disable force feedback", 1729})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(false)
|
||||
.finish();
|
||||
@@ -57,7 +57,7 @@ static auto ForceFeedbackOption = options::OptionBuilder<bool>("Input.ForceFeedb
|
||||
static auto HitEffectOption = options::OptionBuilder<bool>("Input.HitEffect",
|
||||
std::pair<const char*, int>{"Directional Hit", 1730},
|
||||
std::pair<const char*, int>{"Enable or disable the directional hit effect", 1731})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(false)
|
||||
.finish();
|
||||
@@ -65,7 +65,7 @@ static auto HitEffectOption = options::OptionBuilder<bool>("Input.HitEffect",
|
||||
static auto ForceFeedbackStrength = options::OptionBuilder<float>("Input.FFStrength",
|
||||
std::pair<const char*, int>{"Force Feedback Strength", 1756},
|
||||
std::pair<const char*, int>{"The realtive strength of Force Feedback effects", 1757})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.range(0, 100)
|
||||
.default_val(100)
|
||||
|
||||
+4
-2
@@ -59,12 +59,13 @@ int Mouse_sensitivity = 4;
|
||||
static auto MouseSensitivityOption __UNUSED = options::OptionBuilder<int>("Input.MouseSensitivity",
|
||||
std::pair<const char*, int>{"Sensitivity", 1374},
|
||||
std::pair<const char*, int>{"The sensitivity of the mouse input", 1747})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.range(0, 9)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(4)
|
||||
.bind_to(&Mouse_sensitivity)
|
||||
.importance(0)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
bool Use_mouse_to_fly = false;
|
||||
@@ -74,12 +75,13 @@ static SCP_string mouse_mode_display(bool mode) { return mode ? XSTR("Joy-0", 16
|
||||
static auto UseMouseOption __UNUSED = options::OptionBuilder<bool>("Input.UseMouse",
|
||||
std::pair<const char*, int>{"Mouse", 1373},
|
||||
std::pair<const char*, int>{"Whether or not to use the mouse for flying", 1765})
|
||||
.category("Input")
|
||||
.category(std::make_pair("Input", 1827))
|
||||
.display(mouse_mode_display)
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(false)
|
||||
.bind_to(&Use_mouse_to_fly)
|
||||
.importance(1)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
const std::shared_ptr<scripting::Hook<>> OnMouseWheelHook = scripting::Hook<>::Factory(
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace ltp = lighting_profiles;
|
||||
using namespace ltp;
|
||||
bool graphics_options_changed()
|
||||
{
|
||||
auto stored_settings = getLabManager()->graphicsSettings;
|
||||
const auto& stored_settings = getLabManager()->graphicsSettings;
|
||||
|
||||
if (stored_settings.ambient_factor != ltp::lab_get_ambient())
|
||||
return true;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#include "lab/renderer/lab_renderer.h"
|
||||
#include "freespace.h"
|
||||
#include "globalincs/vmallocator.h"
|
||||
#include "lab/labv2_internal.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "graphics/light.h"
|
||||
#include "lab/labv2_internal.h"
|
||||
#include "lab/renderer/lab_renderer.h"
|
||||
#include "lighting/lighting_profiles.h"
|
||||
#include "math/bitarray.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "parse/parselo.h"
|
||||
#include "starfield/starfield.h"
|
||||
#include "starfield/nebula.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "freespace.h"
|
||||
|
||||
#include "missionui/missionscreencommon.h"
|
||||
#include "tracing/tracing.h"
|
||||
@@ -347,7 +348,7 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
|
||||
(ambient_light_level >> 16) & 0xff);
|
||||
|
||||
strcpy_s(Neb2_texture_name, "");
|
||||
Neb2_poof_flags = 0;
|
||||
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
|
||||
bool nebula = false;
|
||||
if (optional_string("+Neb2:")) {
|
||||
nebula = true;
|
||||
@@ -364,8 +365,11 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
|
||||
}
|
||||
|
||||
if (nebula){
|
||||
// Obsolete and only for backwards compatibility
|
||||
if (optional_string("+Neb2Flags:")) {
|
||||
stuff_int(&Neb2_poof_flags);
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
bit_array_set_from_int(Neb2_poof_flags.get(), Poof_info.size(), temp);
|
||||
}
|
||||
// Get poofs by name
|
||||
if (optional_string("+Neb2 Poofs List:")) {
|
||||
|
||||
+44
-10
@@ -107,7 +107,7 @@ static bool DeferredLightingEnabled = true;
|
||||
static auto DeferredLightingOption = options::OptionBuilder<bool>("Graphics.DeferredLighting",
|
||||
std::pair<const char*, int>{"Deferred Lighting", 1782},
|
||||
std::pair<const char*, int>{"Enables or disables deferred lighting", 1783})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.default_val(true)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.bind_to_once(&DeferredLightingEnabled)
|
||||
@@ -176,13 +176,13 @@ static void light_rotate(light * l)
|
||||
}
|
||||
}
|
||||
|
||||
void light_add_directional(const vec3d* dir, const hdr_color* new_color, const float source_radius)
|
||||
void light_add_directional(const vec3d* dir, int sun_index, bool no_glare, const hdr_color* new_color, const float source_radius)
|
||||
{
|
||||
Assert(new_color!= nullptr);
|
||||
light_add_directional(dir, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius);
|
||||
light_add_directional(dir, sun_index, no_glare, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius);
|
||||
}
|
||||
namespace ltp=lighting_profiles;
|
||||
void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius)
|
||||
void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius)
|
||||
{
|
||||
if (Lighting_off) return;
|
||||
|
||||
@@ -191,6 +191,8 @@ void light_add_directional(const vec3d *dir, float intensity, float r, float g,
|
||||
light l;
|
||||
|
||||
l.type = Light_Type::Directional;
|
||||
l.flags = no_glare ? (LF_DEFAULT | LF_NO_GLARE) : LF_DEFAULT;
|
||||
l.sun_index = sun_index;
|
||||
|
||||
vm_vec_copy_scale( &l.vec, dir, -1.0f );
|
||||
|
||||
@@ -233,6 +235,8 @@ void light_add_point(const vec3d *pos, float r1, float r2, float intensity, floa
|
||||
|
||||
Num_lights++;
|
||||
l.type = Light_Type::Point;
|
||||
l.flags = LF_DEFAULT;
|
||||
l.sun_index = -1;
|
||||
l.vec = *pos;
|
||||
l.r = r;
|
||||
l.g = g;
|
||||
@@ -272,6 +276,8 @@ void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, float
|
||||
Num_lights++;
|
||||
|
||||
l.type = Light_Type::Tube;
|
||||
l.flags = LF_DEFAULT;
|
||||
l.sun_index = -1;
|
||||
l.vec = *p0;
|
||||
l.vec2 = *p1;
|
||||
l.r = r;
|
||||
@@ -317,19 +323,46 @@ int light_get_global_count()
|
||||
* @param pos Position
|
||||
* @param n Light source
|
||||
*
|
||||
* Returns 0 if there is no global light.
|
||||
* Returns false if there is no global light.
|
||||
*/
|
||||
int light_get_global_dir(vec3d *pos, int n)
|
||||
bool light_get_global_dir(vec3d *pos, int n)
|
||||
{
|
||||
if ( (n < 0) || (n >= (int)Static_light.size()) ) {
|
||||
return 0;
|
||||
if (!SCP_vector_inbounds(Static_light, n)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos) {
|
||||
*pos = Static_light[n].vec;
|
||||
vm_vec_scale( pos, -1.0f );
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool light_has_glare(int n)
|
||||
{
|
||||
if (!SCP_vector_inbounds(Static_light, n)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Static_light[n].flags & LF_NO_GLARE) == 0;
|
||||
}
|
||||
|
||||
int light_get_sun_index(int n)
|
||||
{
|
||||
if (!SCP_vector_inbounds(Static_light, n)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Static_light[n].sun_index;
|
||||
}
|
||||
|
||||
int light_find_for_sun(int sun_index)
|
||||
{
|
||||
for (size_t n = 0; n < Static_light.size(); ++n)
|
||||
if (Static_light[n].sun_index == sun_index)
|
||||
return static_cast<int>(n);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3d *pos, const vec3d *norm, float static_light_level )
|
||||
@@ -478,11 +511,12 @@ void light_add_cone(const vec3d *pos, const vec3d *dir, float angle, float inner
|
||||
Num_lights++;
|
||||
|
||||
l.type = Light_Type::Cone;
|
||||
l.flags = dual_cone ? (LF_DEFAULT | LF_DUAL_CONE) : LF_DEFAULT;
|
||||
l.sun_index = -1;
|
||||
l.vec = *pos;
|
||||
l.vec2= *dir;
|
||||
l.cone_angle = angle;
|
||||
l.cone_inner_angle = inner_angle;
|
||||
l.dual_cone = dual_cone;
|
||||
l.r = r;
|
||||
l.g = g;
|
||||
l.b = b;
|
||||
|
||||
@@ -47,11 +47,16 @@ typedef struct light {
|
||||
float r,g,b; // The color components of the light
|
||||
float cone_angle; // angle for cone lights
|
||||
float cone_inner_angle; // the inner angle for calculating falloff
|
||||
bool dual_cone; // should the cone be shining in both directions?
|
||||
int flags; // see below
|
||||
int sun_index; // if this light corresponds to a sun
|
||||
float source_radius; // The actual size of the object or volume emitting the light
|
||||
int instance;
|
||||
} light;
|
||||
|
||||
#define LF_DUAL_CONE (1<<0) // should the cone be shining in both directions?
|
||||
#define LF_NO_GLARE (1<<1) // for example, a sun with $NoGlare
|
||||
#define LF_DEFAULT 0 // no flags by default
|
||||
|
||||
extern SCP_vector<light> Static_light;
|
||||
|
||||
struct light_indexing_info
|
||||
@@ -91,8 +96,8 @@ extern void light_reset();
|
||||
|
||||
//Intensity in lighting inputs multiplies the base colors.
|
||||
|
||||
extern void light_add_directional(const vec3d *dir, const hdr_color *new_color, const float source_radius = 0.0f );
|
||||
extern void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius = 0.0f);
|
||||
extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, const hdr_color *new_color, const float source_radius = 0.0f );
|
||||
extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius = 0.0f);
|
||||
extern void light_add_point(const vec3d * pos, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f);
|
||||
extern void light_add_point(const vec3d * pos, float r1, float r2, float intensity, float r, float g, float b, const float source_radius = 0.0f);
|
||||
extern void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f);
|
||||
@@ -110,8 +115,13 @@ void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3
|
||||
extern int light_get_global_count();
|
||||
|
||||
// Fills direction of global light source N in pos.
|
||||
// Returns 0 if there is no global light.
|
||||
extern int light_get_global_dir(vec3d *pos, int n);
|
||||
// Returns false if there is no global light.
|
||||
extern bool light_get_global_dir(vec3d *pos, int n);
|
||||
|
||||
extern bool light_has_glare(int n);
|
||||
|
||||
extern int light_get_sun_index(int n);
|
||||
extern int light_find_for_sun(int sun_index);
|
||||
|
||||
bool light_compare_by_type(const light &a, const light &b);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ bool *Lcl_unexpected_tstring_check = nullptr;
|
||||
// NOTE: with map storage of XSTR strings, the indexes no longer need to be contiguous,
|
||||
// but internal strings should still increment XSTR_SIZE to avoid collisions.
|
||||
// retail XSTR_SIZE = 1570
|
||||
// #define XSTR_SIZE 1817 // This is the next available ID
|
||||
// #define XSTR_SIZE 1842 // This is the next available ID
|
||||
|
||||
|
||||
// struct to allow for strings.tbl-determined x offset
|
||||
@@ -152,7 +152,7 @@ auto LanguageOption = options::OptionBuilder<int>("Game.Language",
|
||||
return false; //This makes it so that changing the language requires a game restart
|
||||
})
|
||||
.flags({options::OptionFlags::ForceMultiValueSelection})
|
||||
.category("Game")
|
||||
.category(std::make_pair("Game", 1824))
|
||||
.default_val(0)
|
||||
.finish();
|
||||
|
||||
|
||||
+51
-1
@@ -42,8 +42,58 @@
|
||||
#define toggle_bit(array, bitnum) (((ubyte *) array)[(bitnum) >> 3] ^= (1 << ((bitnum) & 7)))
|
||||
|
||||
|
||||
// calculate number of bytes from number of bits
|
||||
// calculates number of bytes from number of bits
|
||||
#define calculate_num_bytes(num_bits) ((num_bits >> 3) + 1)
|
||||
|
||||
// zeroes out all bits in the bit array
|
||||
#define clear_all_bits(array, num_bits) memset(array, 0, calculate_num_bytes(num_bits))
|
||||
|
||||
// tests whether any bit in this bit array is nonzero
|
||||
template <class N_TYPE>
|
||||
bool any_bits_set(void *array, N_TYPE num_bits)
|
||||
{
|
||||
auto bytes = static_cast<ubyte*>(array);
|
||||
N_TYPE num_bytes = calculate_num_bytes(num_bits);
|
||||
for (N_TYPE i = 0; i < num_bytes; ++i)
|
||||
if (bytes[i] != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// copies a bit array into an int so that they contain equivalent values, up to the capacity of the int type
|
||||
template <class N_TYPE>
|
||||
int bit_array_as_int(void *array, N_TYPE num_bits)
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
auto bytes = static_cast<ubyte*>(array);
|
||||
N_TYPE num_bytes = calculate_num_bytes(num_bits);
|
||||
for (N_TYPE i = 0; i < num_bytes && i < sizeof(int); ++i)
|
||||
{
|
||||
rval = rval << 3;
|
||||
rval |= bytes[i];
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
// copies an int into a bit array so that they contain equivalent values; any bits in the bit array higher than the capacity of an int are zeroed out
|
||||
template <class N_TYPE>
|
||||
void bit_array_set_from_int(void *array, N_TYPE num_bits, int input)
|
||||
{
|
||||
auto bytes = static_cast<ubyte*>(array);
|
||||
N_TYPE num_bytes = calculate_num_bytes(num_bits);
|
||||
for (N_TYPE i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
if (i < sizeof(int))
|
||||
{
|
||||
bytes[i] = input & 255;
|
||||
input = input >> 3;
|
||||
}
|
||||
else
|
||||
bytes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // _BIT_ARRAY_H
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
SCP_vector<Curve> Curves;
|
||||
|
||||
int curve_get_by_name(SCP_string& in_name) {
|
||||
int curve_get_by_name(const SCP_string& in_name) {
|
||||
for (int i = 0; i < (int)Curves.size(); i++) {
|
||||
if (lcase_equal(Curves[i].name, in_name))
|
||||
return i;
|
||||
|
||||
+1
-1
@@ -43,6 +43,6 @@ public :
|
||||
|
||||
extern SCP_vector<Curve> Curves;
|
||||
|
||||
extern int curve_get_by_name(SCP_string& in_name);
|
||||
extern int curve_get_by_name(const SCP_string& in_name);
|
||||
extern void curves_init();
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
*/
|
||||
float fl_roundoff(float x, int multiple)
|
||||
{
|
||||
float half = (float) multiple / 2.0f;
|
||||
float half = multiple / 2.0f;
|
||||
|
||||
if (x < 0)
|
||||
half = -half;
|
||||
|
||||
x += half;
|
||||
return (float) (((int) x / multiple) * multiple);
|
||||
return i2fl((fl2i(x) / multiple) * multiple);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-56
@@ -30,67 +30,19 @@ inline bool fl_is_nan(float fl) {
|
||||
#define fl_sqrt(fl) sqrtf(fl)
|
||||
#define fl_isqrt(fl) (1.0f/sqrtf(fl))
|
||||
#define fl_abs(fl) fabsf(fl)
|
||||
#define i2fl(i) ((float)(i))
|
||||
#define fl2i(fl) ((int)(fl))
|
||||
#define fl2ir(fl) ((int)(fl + ((fl < 0.0f) ? -0.5f : 0.5f)))
|
||||
#define flceil(fl) (int)ceil(fl)
|
||||
#define flfloor(fl) (int)floor(fl)
|
||||
#define f2fl(fx) ((float)(fx)/65536.0f)
|
||||
#define f2d(fx) (((double)(fx))/65536.0)
|
||||
#define fl2f(fl) (int)((fl)*65536.0f)
|
||||
#define i2fl(i) (static_cast<float>(i))
|
||||
#define fl2i(fl) (static_cast<int>(fl))
|
||||
#define fl2ir(fl) (static_cast<int>(fl + (((fl) < 0.0f) ? -0.5f : 0.5f)))
|
||||
#define f2fl(fx) (static_cast<float>(fx)/65536.0f)
|
||||
#define f2d(fx) (static_cast<double>(fx)/65536.0)
|
||||
#define fl2f(fl) (static_cast<int>((fl)*65536.0f))
|
||||
#define fl_tan(fl) tanf(fl)
|
||||
|
||||
// convert a measurement in degrees to radians
|
||||
#define fl_radians(fl) ((float)((fl) * (PI / 180.0f)))
|
||||
#define fl_radians(fl) (static_cast<float>((fl) * (PI / 180.0f)))
|
||||
|
||||
// convert a measurement in radians to degrees
|
||||
#define fl_degrees(fl) ((float)((fl) * (180.0f / PI)))
|
||||
|
||||
// use this instead of:
|
||||
// for: (int)floor(x+0.5f) use fl_round_2048(x)
|
||||
// (int)ceil(x-0.5f) use fl_round_2048(x)
|
||||
// (int)floor(x-0.5f) use fl_round_2048(x-1.0f)
|
||||
// (int)floor(x) use fl_round_2048(x-0.5f)
|
||||
// for values in the range -2048 to 2048
|
||||
// use this instead of:
|
||||
// for: (int)floor(x+0.5f) use fl_round_2048(x)
|
||||
// (int)ceil(x-0.5f) use fl_round_2048(x)
|
||||
// (int)floor(x-0.5f) use fl_round_2048(x-1.0f)
|
||||
// (int)floor(x) use fl_round_2048(x-0.5f)
|
||||
// for values in the range -2048 to 2048
|
||||
|
||||
/*
|
||||
extern const float *p_fl_magic;
|
||||
|
||||
inline int fl_round_2048( float x )
|
||||
{
|
||||
double tmp_quad;
|
||||
tmp_quad = x + *p_fl_magic;
|
||||
return *((int *)&tmp_quad);
|
||||
}
|
||||
|
||||
inline float fl_sqrt( float x)
|
||||
{
|
||||
float retval;
|
||||
|
||||
_asm fld x
|
||||
_asm fsqrt
|
||||
_asm fstp retval
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
float fl_isqrt( float x )
|
||||
{
|
||||
float retval;
|
||||
|
||||
_asm fld x
|
||||
_asm fsqrt
|
||||
_asm fstp retval
|
||||
|
||||
return 1.0f / retval;
|
||||
}
|
||||
*/
|
||||
#define fl_degrees(fl) (static_cast<float>((fl) * (180.0f / PI)))
|
||||
|
||||
// sees if a floating point number is within a certain threshold (by default, epsilon) of zero
|
||||
inline bool fl_near_zero(float a, float e = std::numeric_limits<float>::epsilon())
|
||||
|
||||
@@ -639,7 +639,7 @@ void credits_init()
|
||||
|
||||
for (iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
|
||||
{
|
||||
gr_get_string_size(NULL, &temp_h, iter->c_str(), (int)iter->length());
|
||||
gr_get_string_size(NULL, &temp_h, iter->c_str(), iter->length());
|
||||
|
||||
h = h + temp_h;
|
||||
}
|
||||
@@ -855,12 +855,12 @@ void credits_do_frame(float /*frametime*/)
|
||||
length = std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
gr_get_string_size(&width, &height, iter->c_str() + currentPos, static_cast<int>(length));
|
||||
gr_get_string_size(&width, &height, iter->c_str() + currentPos, length);
|
||||
// Check if the text part is actually visible
|
||||
if (Credit_position + y_offset + height > 0.0f)
|
||||
{
|
||||
float x = static_cast<float>((gr_screen.clip_width_unscaled - width) / 2);
|
||||
gr_string(x, Credit_position + y_offset, iter->c_str() + currentPos, GR_RESIZE_MENU, static_cast<int>(length));
|
||||
gr_string(x, Credit_position + y_offset, iter->c_str() + currentPos, GR_RESIZE_MENU, length);
|
||||
}
|
||||
|
||||
y_offset += height;
|
||||
|
||||
@@ -309,6 +309,8 @@ static int F1_text_done = 0;
|
||||
int Main_hall_help_stamp = -1;
|
||||
void main_hall_process_help_stuff();
|
||||
|
||||
bool Main_hall_use_defaults = true;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// VOICE RECORDING STUFF
|
||||
@@ -2156,18 +2158,20 @@ void region_info_init(main_hall_defines &m)
|
||||
m.regions.clear();
|
||||
}
|
||||
|
||||
main_hall_region defaults[] = {
|
||||
main_hall_region(0, 0, XSTR( "Exit FreeSpace 2", 353), EXIT_REGION, ""),
|
||||
main_hall_region(1, 'B', XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354), BARRACKS_REGION, ""),
|
||||
main_hall_region(2, 'R', XSTR( "Ready room - Start or continue a campaign", 355), START_REGION, ""),
|
||||
main_hall_region(3, 'T', XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356), TECH_ROOM_REGION, ""),
|
||||
main_hall_region(4, 0, XSTR( "Options - Change your FreeSpace 2 options", 357), OPTIONS_REGION, ""),
|
||||
main_hall_region(5, 'C', XSTR( "Campaign Room - View all available campaigns", 358), CAMPAIGN_ROOM_REGION, ""),
|
||||
main_hall_region(6, 'G', "Quick start", QUICK_START_REGION, "")
|
||||
};
|
||||
if (Main_hall_use_defaults) {
|
||||
main_hall_region defaults[] = {
|
||||
main_hall_region(0, 0, XSTR( "Exit FreeSpace 2", 353), EXIT_REGION, ""),
|
||||
main_hall_region(1, 'B', XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354), BARRACKS_REGION, ""),
|
||||
main_hall_region(2, 'R', XSTR( "Ready room - Start or continue a campaign", 355), START_REGION, ""),
|
||||
main_hall_region(3, 'T', XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356), TECH_ROOM_REGION, ""),
|
||||
main_hall_region(4, 0, XSTR( "Options - Change your FreeSpace 2 options", 357), OPTIONS_REGION, ""),
|
||||
main_hall_region(5, 'C', XSTR( "Campaign Room - View all available campaigns", 358), CAMPAIGN_ROOM_REGION, ""),
|
||||
main_hall_region(6, 'G', "Quick start", QUICK_START_REGION, "")
|
||||
};
|
||||
|
||||
for (int idx = 0; idx < 7; idx++) {
|
||||
m.regions.push_back(defaults[idx]);
|
||||
for (int idx = 0; idx < 7; idx++) {
|
||||
m.regions.push_back(defaults[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
// XSTR( "Multiplayer - Start or join a multiplayer game", 359)
|
||||
@@ -2214,6 +2218,10 @@ void parse_main_hall_table(const char* filename)
|
||||
|
||||
reset_parse();
|
||||
|
||||
if (optional_string("$Base mainhalls on retail defaults:")) {
|
||||
stuff_boolean(&Main_hall_use_defaults);
|
||||
}
|
||||
|
||||
if (optional_string("$Num Resolutions:")) {
|
||||
stuff_int(&num_resolutions);
|
||||
}
|
||||
|
||||
+138
-1
@@ -29,6 +29,8 @@
|
||||
#include "missionui/missionscreencommon.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "network/multi.h"
|
||||
#include "options/OptionsManager.h"
|
||||
#include "options/Option.h"
|
||||
#include "osapi/osregistry.h"
|
||||
#include "pilotfile/pilotfile.h"
|
||||
#include "popup/popup.h"
|
||||
@@ -284,6 +286,17 @@ int Options_skills_text_coords[GR_NUM_RESOLUTIONS][4] = {
|
||||
}
|
||||
};
|
||||
|
||||
int Options_scp_string_coords[GR_NUM_RESOLUTIONS][2] = {
|
||||
{
|
||||
265, 18 // GR_640
|
||||
},
|
||||
{
|
||||
465, 25 // GR_1024
|
||||
}
|
||||
};
|
||||
|
||||
std::pair<SCP_string, int> Options_scp_string_text = {"Press F3 to access additional options", 1831};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
// DETAIL LEVEL OPTIONS definitions BEGIN
|
||||
@@ -666,6 +679,11 @@ void options_cancel_exit()
|
||||
Detail = Detail_original;
|
||||
}
|
||||
|
||||
// We have to discard in game options here
|
||||
if (Using_in_game_options) {
|
||||
options::OptionsManager::instance()->discardChanges();
|
||||
}
|
||||
|
||||
gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
|
||||
}
|
||||
|
||||
@@ -690,6 +708,68 @@ void options_change_gamma(float delta)
|
||||
sprintf(tmp_gamma_string, NOX("%.2f"), gamma);
|
||||
|
||||
os_config_write_string( NULL, NOX("GammaD3D"), tmp_gamma_string );
|
||||
|
||||
if (Using_in_game_options) {
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey("Graphics.Gamma");
|
||||
if (thisOpt != nullptr) {
|
||||
auto val = thisOpt->getCurrentValueDescription();
|
||||
SCP_string newVal = std::to_string(gamma); // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({val.display, newVal.c_str()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_binary_option(SCP_string key, bool value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
auto val = thisOpt->getCurrentValueDescription();
|
||||
SCP_string newVal = value ? "true" : "false"; // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({val.display, newVal.c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_multi_option(SCP_string key, int value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
auto values = thisOpt->getValidValues();
|
||||
thisOpt->setValueDescription(values[value]);
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_range_option(SCP_string key, int value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
SCP_string newVal = std::to_string(value); // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({newVal.c_str(), newVal.c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
void options_set_ingame_range_option(SCP_string key, float value)
|
||||
{
|
||||
if (!Using_in_game_options) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options::OptionBase* thisOpt = options::OptionsManager::instance()->getOptionByKey(key);
|
||||
if (thisOpt != nullptr) {
|
||||
SCP_string newVal = std::to_string(value); // OptionsManager stores values as serialized strings
|
||||
thisOpt->setValueDescription({newVal.c_str(), newVal.c_str()});
|
||||
}
|
||||
}
|
||||
|
||||
void options_button_pressed(int n)
|
||||
@@ -740,6 +820,7 @@ void options_button_pressed(int n)
|
||||
|
||||
// BEGIN - detail level tab buttons
|
||||
|
||||
// Target View Rendering is currently not handled by in-game options, assumes "On"
|
||||
case HUD_TARGETVIEW_RENDER_ON:
|
||||
Detail.targetview_model = 1;
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -750,6 +831,7 @@ void options_button_pressed(int n)
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
// Planets is currently not handled by in-game options, assumes "On"
|
||||
case PLANETS_ON:
|
||||
Detail.planets_suns = 1;
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -760,6 +842,7 @@ void options_button_pressed(int n)
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
// Weapon extras is currently not handled by in-game options, assumes "On"
|
||||
case WEAPON_EXTRAS_ON:
|
||||
Detail.weapon_extras = 1;
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -798,29 +881,35 @@ void options_button_pressed(int n)
|
||||
|
||||
case GAMMA_DOWN:
|
||||
options_change_gamma(-0.05f);
|
||||
// Gamma in-game change is handled in the above method
|
||||
break;
|
||||
|
||||
case GAMMA_UP:
|
||||
options_change_gamma(0.05f);
|
||||
// Gamma in-game change is handled in the above method
|
||||
break;
|
||||
|
||||
case BRIEF_VOICE_ON:
|
||||
Briefing_voice_enabled = true;
|
||||
options_set_ingame_binary_option("Audio.BriefingVoice", true);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case BRIEF_VOICE_OFF:
|
||||
Briefing_voice_enabled = false;
|
||||
options_set_ingame_binary_option("Audio.BriefingVoice", false);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MOUSE_ON:
|
||||
Use_mouse_to_fly = 1;
|
||||
options_set_ingame_binary_option("Input.UseMouse", true);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
|
||||
case MOUSE_OFF:
|
||||
Use_mouse_to_fly = 0;
|
||||
options_set_ingame_binary_option("Input.UseMouse", false);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
break;
|
||||
}
|
||||
@@ -832,6 +921,7 @@ void options_sliders_update()
|
||||
if (Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos != Sound_volume_int) {
|
||||
Sound_volume_int = Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos;
|
||||
snd_set_effects_volume((float) (Sound_volume_int) / 9.0f);
|
||||
options_set_ingame_range_option("Audio.Effects", Master_sound_volume); // Volume options save the global float, not the range slider position
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
@@ -839,7 +929,7 @@ void options_sliders_update()
|
||||
if (Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos != Music_volume_int) {
|
||||
Music_volume_int = Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos;
|
||||
event_music_set_volume((float) (Music_volume_int) / 9.0f);
|
||||
|
||||
options_set_ingame_range_option("Audio.Music", Master_event_music_volume); // Volume options save the global float, not the range slider position
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
@@ -847,30 +937,48 @@ void options_sliders_update()
|
||||
if (Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos != Voice_volume_int) {
|
||||
Voice_volume_int = Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos;
|
||||
snd_set_voice_volume((float) (Voice_volume_int) / 9.0f);
|
||||
options_set_ingame_range_option("Audio.Voice", Master_voice_volume); // Volume options save the global float, not the range slider position
|
||||
options_play_voice_clip();
|
||||
}
|
||||
|
||||
if (Mouse_sensitivity != Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos) {
|
||||
Mouse_sensitivity = Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos;
|
||||
options_set_ingame_range_option("Input.MouseSensitivity", Mouse_sensitivity);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
if (Joy_sensitivity != Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos) {
|
||||
Joy_sensitivity = Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos;
|
||||
options_set_ingame_range_option("Input.JoystickSensitivity", Joy_sensitivity);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
if (Joy_dead_zone_size != Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5) {
|
||||
Joy_dead_zone_size = Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5;
|
||||
options_set_ingame_range_option("Input.JoystickDeadZone", Joy_dead_zone_size);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
|
||||
if (Game_skill_level != Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos) {
|
||||
Game_skill_level = Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos;
|
||||
options_set_ingame_range_option("Game.SkillLevel", Game_skill_level);
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
void options_detail_sliders_in_game_update()
|
||||
{
|
||||
// Save in-game options settings
|
||||
options_set_ingame_multi_option("Graphics.Detail", Detail.detail_distance);
|
||||
options_set_ingame_multi_option("Graphics.NebulaDetail", Detail.nebula_detail);
|
||||
options_set_ingame_multi_option("Graphics.Texture", Detail.hardware_textures);
|
||||
options_set_ingame_multi_option("Graphics.Particles", Detail.num_particles);
|
||||
options_set_ingame_multi_option("Graphics.SmallDebris", Detail.num_small_debris);
|
||||
options_set_ingame_multi_option("Graphics.ShieldEffects", Detail.shield_effects);
|
||||
options_set_ingame_multi_option("Graphics.Stars", Detail.num_stars);
|
||||
options_set_ingame_multi_option("Graphics.Lighting", Detail.lighting);
|
||||
}
|
||||
|
||||
void options_accept()
|
||||
{
|
||||
// apply the selected multiplayer options
|
||||
@@ -883,6 +991,15 @@ void options_accept()
|
||||
}
|
||||
}
|
||||
|
||||
// We have to save in game options here
|
||||
if (Using_in_game_options) {
|
||||
// detail sliders are updated every frame but it's silly to run OptionsManager every frame, too
|
||||
// so just set them on Accept and then persist.
|
||||
options_detail_sliders_in_game_update();
|
||||
|
||||
options::OptionsManager::instance()->persistChanges();
|
||||
}
|
||||
|
||||
// If music is zero volume, disable
|
||||
if ( Master_event_music_volume <= 0.0f ) {
|
||||
// event_music_disable();
|
||||
@@ -1178,6 +1295,17 @@ void options_menu_do_frame(float /*frametime*/)
|
||||
|
||||
case KEY_ENTER:
|
||||
break;
|
||||
|
||||
case KEY_F3: // SCP ingame options
|
||||
if (Using_in_game_options) {
|
||||
// Going into F3 Options needs to either discard or save the changes made here.
|
||||
// There's an argument to be made for both but I feel like saving is the better choice - Mjn
|
||||
options::OptionsManager::instance()->persistChanges();
|
||||
|
||||
gamesnd_play_iface(InterfaceSounds::IFACE_MOUSE_CLICK);
|
||||
gameseq_post_event(GS_EVENT_INGAME_OPTIONS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_BUTTONS; i++) {
|
||||
@@ -1275,6 +1403,15 @@ void options_menu_do_frame(float /*frametime*/)
|
||||
if(Tab == MULTIPLAYER_TAB){
|
||||
options_multi_vox_process_waveform();
|
||||
}
|
||||
|
||||
// maybe blit the SCP Options string
|
||||
if (Using_in_game_options) {
|
||||
gr_set_color_fast(&Color_bright_blue);
|
||||
gr_string(Options_scp_string_coords[gr_screen.res][OPTIONS_X_COORD],
|
||||
Options_scp_string_coords[gr_screen.res][OPTIONS_Y_COORD],
|
||||
XSTR(Options_scp_string_text.first.c_str(), Options_scp_string_text.second),
|
||||
GR_RESIZE_MENU);
|
||||
}
|
||||
|
||||
gr_flip();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ void options_menu_init();
|
||||
void options_menu_close();
|
||||
void options_menu_do_frame(float frametime);
|
||||
|
||||
// For optionsmenumulti.cpp
|
||||
void options_set_ingame_binary_option(SCP_string key, bool value);
|
||||
|
||||
// kill the options menu
|
||||
void options_cancel_exit();
|
||||
|
||||
|
||||
@@ -1005,8 +1005,10 @@ void options_multi_protocol_button_pressed(int n)
|
||||
|
||||
if(!Om_local_broadcast){
|
||||
Om_local_broadcast = 1;
|
||||
options_set_ingame_binary_option("Multi.LocalBroadcast", true);
|
||||
} else {
|
||||
Om_local_broadcast = 0;
|
||||
options_set_ingame_binary_option("Multi.LocalBroadcast", false);
|
||||
}
|
||||
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
@@ -1048,10 +1050,12 @@ void options_multi_protocol_button_pressed(int n)
|
||||
Om_tracker_login.enable();
|
||||
Om_tracker_passwd.enable();
|
||||
Om_tracker_squad_name.enable();
|
||||
options_set_ingame_binary_option("Multi.TogglePXO", true);
|
||||
} else {
|
||||
Om_tracker_login.disable();
|
||||
Om_tracker_passwd.disable();
|
||||
Om_tracker_squad_name.disable();
|
||||
options_set_ingame_binary_option("Multi.TogglePXO", false);
|
||||
}
|
||||
|
||||
// play a sound
|
||||
@@ -1539,6 +1543,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(!Om_gen_xfer_multidata){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_xfer_multidata = 1;
|
||||
options_set_ingame_binary_option("Multi.TransferMissions", true);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
@@ -1549,6 +1554,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(Om_gen_xfer_multidata){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_xfer_multidata = 0;
|
||||
options_set_ingame_binary_option("Multi.TransferMissions", false);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
@@ -1559,6 +1565,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(!Om_gen_flush_cache){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_flush_cache = 1;
|
||||
options_set_ingame_binary_option("Multi.FlushCache", true);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
@@ -1569,6 +1576,7 @@ void options_multi_gen_button_pressed(int n)
|
||||
if(Om_gen_flush_cache){
|
||||
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
||||
Om_gen_flush_cache = 0;
|
||||
options_set_ingame_binary_option("Multi.FlushCache", false);
|
||||
} else {
|
||||
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ void techroom_select_new_entry()
|
||||
if (Techroom_model_instance >= 0) {
|
||||
model_delete_instance(Techroom_model_instance);
|
||||
}
|
||||
Techroom_model_instance = model_create_instance(-1, Techroom_modelnum);
|
||||
Techroom_model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, Techroom_modelnum);
|
||||
|
||||
model_set_up_techroom_instance(sip, Techroom_model_instance);
|
||||
|
||||
@@ -396,7 +396,7 @@ void techroom_select_new_entry()
|
||||
if (Techroom_model_instance >= 0) {
|
||||
model_delete_instance(Techroom_model_instance);
|
||||
}
|
||||
Techroom_model_instance = model_create_instance(-1, Techroom_modelnum);
|
||||
Techroom_model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, Techroom_modelnum);
|
||||
|
||||
// If this ends up being needed for weapon models, a weapon version
|
||||
// of this method will need to be created. Should only be necessary
|
||||
|
||||
@@ -130,11 +130,12 @@ bool Briefing_voice_enabled = true; // flag which turn on/off voice playback of
|
||||
static auto BriefingVoiceOption __UNUSED = options::OptionBuilder<bool>("Audio.BriefingVoice",
|
||||
std::pair<const char*, int>{"Briefing voice", 1368},
|
||||
std::pair<const char*, int>{"Enable or disable voice playback in the briefing", 1716})
|
||||
.category("Audio")
|
||||
.category(std::make_pair("Audio", 1826))
|
||||
.level(options::ExpertLevel::Beginner)
|
||||
.default_val(true)
|
||||
.bind_to(&Briefing_voice_enabled)
|
||||
.importance(4)
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
@@ -49,18 +49,18 @@ static int Key_sets[MAX_KEYED_TARGETS] = {
|
||||
|
||||
static int Hotkey_bits[MAX_SHIPS]; // bitfield indicating which hotkeys are used by each ship
|
||||
|
||||
static int Hotkey_sets_saved; // have we saved the sets for this mission
|
||||
static bool Hotkey_sets_saved; // have we saved the sets for this mission
|
||||
|
||||
static int Mission_hotkey_save_timestamp; // timestamp used to tell us when we can save
|
||||
#define HOTKEY_SAVE_TIME 15000 // save sets this number of milliseconds into the mission
|
||||
static TIMESTAMP Mission_hotkey_save_timestamp; // timestamp used to tell us when we can save
|
||||
constexpr int HOTKEY_SAVE_TIME = 15 * MILLISECONDS_PER_SECOND; // save sets this number of milliseconds into the mission
|
||||
|
||||
typedef struct {
|
||||
int setnum;
|
||||
char name[NAME_LENGTH];
|
||||
} HK_save_info;
|
||||
|
||||
HK_save_info Hotkey_saved_info[MAX_HOTKEY_TARGET_ITEMS];
|
||||
int Num_hotkeys_saved;
|
||||
static HK_save_info Hotkey_saved_info[MAX_HOTKEY_TARGET_ITEMS];
|
||||
static int Num_hotkeys_saved;
|
||||
|
||||
|
||||
static const char *Hotkey_background_fname[GR_NUM_RESOLUTIONS] = {
|
||||
@@ -317,8 +317,8 @@ void mission_hotkey_set_defaults(bool restore)
|
||||
}
|
||||
|
||||
// set the variable letting us know that we should save the hotkey sets
|
||||
Hotkey_sets_saved = 0;
|
||||
Mission_hotkey_save_timestamp = timestamp(HOTKEY_SAVE_TIME);
|
||||
Hotkey_sets_saved = false;
|
||||
Mission_hotkey_save_timestamp = _timestamp(HOTKEY_SAVE_TIME);
|
||||
|
||||
// if we have hotkeys saved from the previous run of this mission, then simply keep the cleared
|
||||
// sets, and let the restore code take care of it! This works because this function is currently
|
||||
@@ -425,7 +425,7 @@ void mission_hotkey_maybe_save_sets()
|
||||
}
|
||||
}
|
||||
|
||||
Hotkey_sets_saved = 1;
|
||||
Hotkey_sets_saved = true;
|
||||
}
|
||||
|
||||
// function which gets called from MissionParse to maybe add a ship or wing to a hotkey set.
|
||||
|
||||
@@ -110,7 +110,7 @@ int Num_messages_playing; // number of is a message currently playing?
|
||||
pmessage Playing_messages[MAX_PLAYING_MESSAGES];
|
||||
|
||||
int Message_shipnum; // ship number of who is sending message to player -- used outside this module
|
||||
int Message_expire; // timestamp to extend the duration of message brackets when not using voice files
|
||||
static TIMESTAMP Message_expire; // timestamp to extend the duration of message brackets when not using voice files
|
||||
|
||||
// variables to control message queuing. All new messages to the player are queued. The array
|
||||
// will be ordered by priority, then time submitted.
|
||||
@@ -1708,7 +1708,7 @@ void message_queue_process()
|
||||
// translate tokens in message to the real things
|
||||
buf = message_translate_tokens(q->special_message ? q->special_message.get() : m->message);
|
||||
|
||||
Message_expire = timestamp(static_cast<int>(42 * buf.size()));
|
||||
Message_expire = _timestamp(static_cast<int>(42 * buf.size()));
|
||||
|
||||
// play wave first, since need to know duration for picking anim start frame
|
||||
if(message_play_wave(q) == false) {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "lighting/lighting.h"
|
||||
#include "lighting/lighting_profiles.h"
|
||||
#include "localization/localize.h"
|
||||
#include "math/bitarray.h"
|
||||
#include "math/fvi.h"
|
||||
#include "math/staticrand.h"
|
||||
#include "mission/missionbriefcommon.h"
|
||||
@@ -162,8 +163,7 @@ p_object *Player_start_pobject;
|
||||
|
||||
// name of all ships to use while parsing a mission (since a ship might be referenced by
|
||||
// something before that ship has even been loaded yet)
|
||||
char Parse_names[MAX_SHIPS + MAX_WINGS][NAME_LENGTH];
|
||||
size_t Num_parse_names;
|
||||
SCP_vector<SCP_string> Parse_names;
|
||||
|
||||
SCP_vector<texture_replace> Fred_texture_replacements;
|
||||
|
||||
@@ -486,6 +486,16 @@ const std::shared_ptr<scripting::Hook<scripting::hooks::ShipDepartConditions>> O
|
||||
const std::shared_ptr<scripting::Hook<>> OnLoadoutAboutToParseHook = scripting::Hook<>::Factory("On Loadout About To Parse",
|
||||
"Called during mission load just before parsing the team loadout.",{});
|
||||
|
||||
mission_custom_string* get_custom_string_by_name(SCP_string name) {
|
||||
for (size_t i = 0; i < The_mission.custom_strings.size(); i++) {
|
||||
if (The_mission.custom_strings[i].name == name) {
|
||||
return &The_mission.custom_strings[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
void parse_custom_bitmap(const char *expected_string_640, const char *expected_string_1024, char *string_field_640, char *string_field_1024)
|
||||
{
|
||||
@@ -2929,7 +2939,7 @@ int parse_object(mission *pm, int /*flag*/, p_object *p_objp)
|
||||
|
||||
required_string("$Name:");
|
||||
stuff_string(p_objp->name, F_NAME, NAME_LENGTH);
|
||||
if (mission_parse_get_parse_object(p_objp->name))
|
||||
if (mission_parse_find_parse_object(p_objp->name))
|
||||
error_display(0, NOX("Redundant ship name: %s\n"), p_objp->name);
|
||||
|
||||
// if this name has a hash, create a default display name
|
||||
@@ -3714,7 +3724,7 @@ void parse_common_object_data(p_object *p_objp)
|
||||
if (optional_string("+Cargo Name:")) {
|
||||
char cargo_name[NAME_LENGTH];
|
||||
stuff_string(cargo_name, F_NAME, NAME_LENGTH);
|
||||
int index = string_lookup(cargo_name, Cargo_names, Num_cargo, "cargo", 0);
|
||||
int index = string_lookup(cargo_name, Cargo_names, Num_cargo, "cargo", false);
|
||||
if (index == -1) {
|
||||
if (Num_cargo < MAX_CARGO) {
|
||||
index = Num_cargo;
|
||||
@@ -4044,21 +4054,8 @@ void swap_parse_object(p_object *p_obj, int new_ship_class)
|
||||
}
|
||||
}
|
||||
|
||||
p_object *mission_parse_get_parse_object(ushort net_signature)
|
||||
{
|
||||
SCP_vector<p_object>::iterator ii;
|
||||
|
||||
// look for original ships
|
||||
for (ii = Parse_objects.begin(); ii != Parse_objects.end(); ++ii)
|
||||
if (ii->net_signature == net_signature)
|
||||
return &(*ii);
|
||||
|
||||
// boo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Goober5000 - also get it by name
|
||||
p_object *mission_parse_get_parse_object(const char *name)
|
||||
// Goober5000 - this needs to search the vector instead of using the registry, because it can be used during parsing before the registry is populated
|
||||
p_object *mission_parse_find_parse_object(const char *name)
|
||||
{
|
||||
SCP_vector<p_object>::iterator ii;
|
||||
|
||||
@@ -4128,21 +4125,17 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
|
||||
// if wing is coming from docking bay, then be sure that ship we are arriving from actually exists
|
||||
// (or will exist).
|
||||
if ( wingp->arrival_location == ARRIVE_FROM_DOCK_BAY ) {
|
||||
int shipnum;
|
||||
char *name;
|
||||
|
||||
Assert( wingp->arrival_anchor >= 0 );
|
||||
name = Parse_names[wingp->arrival_anchor];
|
||||
auto anchor_ship_entry = ship_registry_get(Parse_names[wingp->arrival_anchor]);
|
||||
|
||||
// see if ship is yet to arrive. If so, then return 0 so we can evaluate again later.
|
||||
if (!anchor_ship_entry || anchor_ship_entry->status == ShipStatus::NOT_YET_PRESENT)
|
||||
return 0;
|
||||
|
||||
// see if ship is in mission.
|
||||
shipnum = ship_name_lookup( name );
|
||||
if ( shipnum == -1 ) {
|
||||
if (!anchor_ship_entry->has_shipp()) {
|
||||
int num_remaining;
|
||||
|
||||
// see if ship is yet to arrive. If so, then return 0 so we can evaluate again later.
|
||||
if (mission_check_ship_yet_to_arrive(name))
|
||||
return 0;
|
||||
|
||||
// since this wing cannot arrive from this place, we need to mark the wing as destroyed and
|
||||
// set the wing variables appropriately. Good for directives.
|
||||
|
||||
@@ -4155,21 +4148,24 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, bool force_create,
|
||||
wingp->total_arrived_count += num_remaining;
|
||||
wingp->current_wave = wingp->num_waves;
|
||||
|
||||
if ( mission_log_get_time(LOG_SHIP_DESTROYED, name, NULL, NULL) || mission_log_get_time(LOG_SELF_DESTRUCTED, name, NULL, NULL) ) {
|
||||
if ( mission_log_get_time(LOG_SHIP_DESTROYED, anchor_ship_entry->name, nullptr, nullptr) || mission_log_get_time(LOG_SELF_DESTRUCTED, anchor_ship_entry->name, nullptr, nullptr) ) {
|
||||
wingp->total_destroyed += num_remaining;
|
||||
} else if ( mission_log_get_time(LOG_SHIP_DEPARTED, name, NULL, NULL) ) {
|
||||
} else if ( mission_log_get_time(LOG_SHIP_DEPARTED, anchor_ship_entry->name, nullptr, nullptr) ) {
|
||||
wingp->total_departed += num_remaining;
|
||||
} else {
|
||||
wingp->total_vanished += num_remaining;
|
||||
}
|
||||
|
||||
mission_parse_mark_non_arrival(wingp); // Goober5000
|
||||
WarningEx(LOCATION, "Warning: Wing %s cannot arrive from docking bay of destroyed or departed %s.\n", wingp->name, anchor_ship_entry->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Goober5000 - check status of fighterbays - if they're destroyed, we can't launch - but we want to reeval later
|
||||
if (ship_fighterbays_all_destroyed(&Ships[shipnum]))
|
||||
if (ship_fighterbays_all_destroyed(anchor_ship_entry->shipp())) {
|
||||
WarningEx(LOCATION, "Warning: Wing %s cannot arrive from destroyed docking bay of %s.\n", wingp->name, anchor_ship_entry->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( num_to_create == 0 )
|
||||
@@ -4872,7 +4868,8 @@ void resolve_path_masks(int anchor, int *path_mask)
|
||||
|
||||
// get anchor ship
|
||||
Assert(!(anchor & SPECIAL_ARRIVAL_ANCHOR_FLAG));
|
||||
parent_pobjp = mission_parse_get_parse_object(Parse_names[anchor]);
|
||||
auto parent_ship_entry = ship_registry_get(Parse_names[anchor]);
|
||||
parent_pobjp = parent_ship_entry->p_objp();
|
||||
|
||||
// Load the anchor ship model with subsystems and all; it'll need to be done for this mission anyway
|
||||
ship_info *sip = &Ship_info[parent_pobjp->ship_class];
|
||||
@@ -4956,6 +4953,17 @@ void post_process_ships_wings()
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000 - add all the parse objects to the ship registry. This must be done before any other parse object processing.
|
||||
for (auto &p_obj : Parse_objects)
|
||||
{
|
||||
ship_registry_entry entry(p_obj.name);
|
||||
entry.status = ShipStatus::NOT_YET_PRESENT;
|
||||
entry.pobj_num = POBJ_INDEX(&p_obj);
|
||||
|
||||
Ship_registry.push_back(entry);
|
||||
Ship_registry_map[p_obj.name] = static_cast<int>(Ship_registry.size() - 1);
|
||||
}
|
||||
|
||||
// Goober5000 - resolve the path masks. Needs to be done early because
|
||||
// mission_parse_maybe_create_parse_object relies on it.
|
||||
post_process_path_stuff();
|
||||
@@ -4965,18 +4973,9 @@ void post_process_ships_wings()
|
||||
// both ships and wings have been parsed.
|
||||
mission_parse_set_up_initial_docks();
|
||||
|
||||
// Goober5000 - now add all the parse objects to the ship registry. This must be done before
|
||||
// any ships are created from the parse objects.
|
||||
// Might as well do any post-processing for parse objects here too.
|
||||
// Goober5000 - Now do any post-processing for parse objects.
|
||||
for (auto &p_obj : Parse_objects)
|
||||
{
|
||||
ship_registry_entry entry(p_obj.name);
|
||||
entry.status = ShipStatus::NOT_YET_PRESENT;
|
||||
entry.pobj_num = POBJ_INDEX(&p_obj);
|
||||
|
||||
Ship_registry.push_back(entry);
|
||||
Ship_registry_map[p_obj.name] = static_cast<int>(Ship_registry.size() - 1);
|
||||
|
||||
// set a flag if this parse object is in a starting wing
|
||||
if (p_obj.wingnum >= 0)
|
||||
{
|
||||
@@ -5494,7 +5493,7 @@ void parse_reinforcement(mission *pm)
|
||||
}
|
||||
|
||||
// sanity check on the names of reinforcements
|
||||
rforce_obj = mission_parse_get_parse_object(ptr->name);
|
||||
rforce_obj = mission_parse_find_parse_object(ptr->name);
|
||||
|
||||
if (rforce_obj == NULL) {
|
||||
if ((instance = wing_name_lookup(ptr->name, 1)) == -1) {
|
||||
@@ -5664,7 +5663,7 @@ void parse_bitmaps(mission *pm)
|
||||
|
||||
// all poofs on by default
|
||||
for (size_t i = 0; i < Poof_info.size(); i++)
|
||||
Neb2_poof_flags += (1 << i);
|
||||
set_bit(Neb2_poof_flags.get(), i);
|
||||
bool nebula = false;
|
||||
if (optional_string("+Neb2:")) {
|
||||
nebula = true;
|
||||
@@ -5682,7 +5681,9 @@ void parse_bitmaps(mission *pm)
|
||||
if (nebula) {
|
||||
// Obsolete and only for backwards compatibility
|
||||
if (optional_string("+Neb2Flags:")) {
|
||||
stuff_int(&Neb2_poof_flags);
|
||||
int temp;
|
||||
stuff_int(&temp);
|
||||
bit_array_set_from_int(Neb2_poof_flags.get(), Poof_info.size(), temp);
|
||||
}
|
||||
|
||||
// Get poofs by name
|
||||
@@ -6275,9 +6276,10 @@ bool post_process_mission(mission *pm)
|
||||
post_process_ships_wings();
|
||||
|
||||
// the player_start_shipname had better exist at this point!
|
||||
Player_start_shipnum = ship_name_lookup( Player_start_shipname );
|
||||
auto player_start_entry = ship_registry_get(Player_start_shipname);
|
||||
Player_start_shipnum = player_start_entry->shipnum;
|
||||
Assert( Player_start_shipnum != -1 );
|
||||
Player_start_pobject = mission_parse_get_parse_object( Player_start_shipname );
|
||||
Player_start_pobject = player_start_entry->p_objp();
|
||||
Assert( Player_start_pobject != NULL );
|
||||
|
||||
// Assign objnum, shipnum, etc. to the player structure
|
||||
@@ -6327,10 +6329,13 @@ bool post_process_mission(mission *pm)
|
||||
|
||||
// convert all ship name indices to ship indices now that mission has been loaded
|
||||
if (Fred_running) {
|
||||
for (i=0; i<(int)Num_parse_names; i++) {
|
||||
indices[i] = ship_name_lookup(Parse_names[i], 1);
|
||||
i = 0;
|
||||
for (const auto &parse_name: Parse_names) {
|
||||
auto ship_entry = ship_registry_get(parse_name);
|
||||
indices[i] = ship_entry ? ship_entry->shipnum : -1;
|
||||
if (indices[i] < 0)
|
||||
Warning(LOCATION, "Ship name \"%s\" referenced, but this ship doesn't exist", Parse_names[i]);
|
||||
Warning(LOCATION, "Ship name \"%s\" referenced, but this ship doesn't exist", parse_name.c_str());
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i=0; i<MAX_SHIPS; i++) {
|
||||
@@ -6689,7 +6694,6 @@ void mission_init(mission *pm)
|
||||
mission_parse_reset_callsign();
|
||||
ai_lua_reset_general_orders();
|
||||
|
||||
Num_parse_names = 0;
|
||||
Num_path_restrictions = 0;
|
||||
Num_ai_dock_names = 0;
|
||||
ai_clear_goal_target_names();
|
||||
@@ -7094,18 +7098,17 @@ void mission_parse_set_up_initial_docks()
|
||||
// build trees
|
||||
for (i = 0; i < Total_initially_docked; i++)
|
||||
{
|
||||
char *docker_point, *dockee_point;
|
||||
p_object *docker, *dockee;
|
||||
|
||||
// resolve the docker and dockee
|
||||
docker = mission_parse_get_parse_object(Initially_docked[i].docker);
|
||||
if (docker == NULL)
|
||||
auto docker_entry = ship_registry_get(Initially_docked[i].docker);
|
||||
auto docker = docker_entry ? docker_entry->p_objp_or_null() : nullptr;
|
||||
if (docker == nullptr)
|
||||
{
|
||||
Warning(LOCATION, "Could not resolve initially docked object '%s'!", Initially_docked[i].docker);
|
||||
continue;
|
||||
}
|
||||
dockee = mission_parse_get_parse_object(Initially_docked[i].dockee);
|
||||
if (dockee == NULL)
|
||||
auto dockee_entry = ship_registry_get(Initially_docked[i].dockee);
|
||||
auto dockee = dockee_entry ? dockee_entry->p_objp_or_null() : nullptr;
|
||||
if (dockee == nullptr)
|
||||
{
|
||||
Warning(LOCATION, "Could not resolve docking target '%s' of initially docked object '%s'!", Initially_docked[i].dockee, Initially_docked[i].docker);
|
||||
continue;
|
||||
@@ -7118,8 +7121,8 @@ void mission_parse_set_up_initial_docks()
|
||||
continue;
|
||||
|
||||
// resolve the dockpoints
|
||||
docker_point = Initially_docked[i].docker_point;
|
||||
dockee_point = Initially_docked[i].dockee_point;
|
||||
auto docker_point = Initially_docked[i].docker_point;
|
||||
auto dockee_point = Initially_docked[i].dockee_point;
|
||||
|
||||
// docker point in use?
|
||||
if (dock_find_object_at_dockpoint(docker, docker_point) != NULL)
|
||||
@@ -7356,7 +7359,8 @@ int mission_set_arrival_location(int anchor, int location, int dist, int objnum,
|
||||
// ship name lookup on the anchor
|
||||
else
|
||||
{
|
||||
shipnum = ship_name_lookup(Parse_names[anchor]);
|
||||
auto anchor_entry = ship_registry_get(Parse_names[anchor]);
|
||||
shipnum = anchor_entry ? anchor_entry->shipnum : -1;
|
||||
}
|
||||
|
||||
// if we didn't get an object from one of the above functions, then make the object
|
||||
@@ -7539,27 +7543,23 @@ int mission_did_ship_arrive(p_object *objp, bool force_arrival)
|
||||
// check to see if this ship is to arrive via a docking bay. If so, and the ship to arrive from
|
||||
// doesn't exist, don't create.
|
||||
if ( objp->arrival_location == ARRIVE_FROM_DOCK_BAY ) {
|
||||
int shipnum;
|
||||
char *name;
|
||||
|
||||
Assert( objp->arrival_anchor >= 0 );
|
||||
name = Parse_names[objp->arrival_anchor];
|
||||
|
||||
// see if ship is in mission.
|
||||
shipnum = ship_name_lookup( name );
|
||||
if ( shipnum == -1 ) {
|
||||
// see if ship is yet to arrive. If so, then return -1 so we can evaluate again later.
|
||||
if (mission_check_ship_yet_to_arrive(name))
|
||||
return -1;
|
||||
auto anchor_ship_entry = ship_registry_get(Parse_names[objp->arrival_anchor]);
|
||||
|
||||
// see if ship is yet to arrive. If so, then return -1 so we can evaluate again later.
|
||||
if (!anchor_ship_entry || anchor_ship_entry->status == ShipStatus::NOT_YET_PRESENT)
|
||||
return -1;
|
||||
|
||||
// see if ship is in mission.
|
||||
if (!anchor_ship_entry->has_shipp()) {
|
||||
mission_parse_mark_non_arrival(objp); // Goober5000
|
||||
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from docking bay of destroyed or departed %s.\n", objp->name, name);
|
||||
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from docking bay of destroyed or departed %s.\n", objp->name, anchor_ship_entry->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Goober5000: aha - also don't create if fighterbay is destroyed
|
||||
if (ship_fighterbays_all_destroyed(&Ships[shipnum])) {
|
||||
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from destroyed docking bay of %s.\n", objp->name, name);
|
||||
// Goober5000 - check status of fighterbays - if they're destroyed, we can't launch - but we want to reeval later
|
||||
if (ship_fighterbays_all_destroyed(anchor_ship_entry->shipp())) {
|
||||
WarningEx(LOCATION, "Warning: Ship %s cannot arrive from destroyed docking bay of %s.\n", objp->name, anchor_ship_entry->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -7949,37 +7949,33 @@ int mission_do_departure(object *objp, bool goal_is_to_warp)
|
||||
// just make it warp out like anything else.
|
||||
if (location == DEPART_AT_DOCK_BAY)
|
||||
{
|
||||
int anchor_shipnum;
|
||||
char *name;
|
||||
|
||||
Assert(anchor >= 0);
|
||||
name = Parse_names[anchor];
|
||||
auto anchor_ship_entry = ship_registry_get(Parse_names[anchor]);
|
||||
|
||||
// see if ship is yet to arrive. If so, then warp.
|
||||
if (mission_check_ship_yet_to_arrive(name))
|
||||
if (!anchor_ship_entry || anchor_ship_entry->status == ShipStatus::NOT_YET_PRESENT)
|
||||
{
|
||||
mprintf(("Anchor ship %s hasn't arrived yet! Trying to warp...\n", name));
|
||||
mprintf(("Anchor ship %s hasn't arrived yet! Trying to warp...\n", Parse_names[anchor].c_str()));
|
||||
goto try_to_warp;
|
||||
}
|
||||
|
||||
// see if ship is in mission. If not, then we can assume it was destroyed or departed since
|
||||
// it is not on the arrival list (as shown by above if statement).
|
||||
anchor_shipnum = ship_name_lookup(name);
|
||||
if (anchor_shipnum < 0)
|
||||
if (!anchor_ship_entry->has_shipp())
|
||||
{
|
||||
mprintf(("Anchor ship %s not found! Trying to warp...\n", name));
|
||||
mprintf(("Anchor ship %s not found! Trying to warp...\n", anchor_ship_entry->name));
|
||||
goto try_to_warp;
|
||||
}
|
||||
|
||||
// see if we can actually depart to the ship
|
||||
if (!ship_useful_for_departure(anchor_shipnum, shipp->departure_path_mask))
|
||||
if (!ship_useful_for_departure(anchor_ship_entry->shipnum, shipp->departure_path_mask))
|
||||
{
|
||||
mprintf(("Anchor ship %s not suitable for departure (dying, departing, bays destroyed, etc.). Trying to warp...\n", name));
|
||||
mprintf(("Anchor ship %s not suitable for departure (dying, departing, bays destroyed, etc.). Trying to warp...\n", anchor_ship_entry->name));
|
||||
goto try_to_warp;
|
||||
}
|
||||
|
||||
// find a path
|
||||
if (ai_acquire_depart_path(objp, Ships[anchor_shipnum].objnum, path_mask) >= 0)
|
||||
if (ai_acquire_depart_path(objp, anchor_ship_entry->objnum, path_mask) >= 0)
|
||||
{
|
||||
MONITOR_INC(NumShipDepartures,1);
|
||||
|
||||
@@ -8236,16 +8232,15 @@ subsys_status *parse_get_subsys_status(p_object *pobjp, const char *subsys_name)
|
||||
// find (or add) the name in the list and return an index to it.
|
||||
int get_parse_name_index(const char *name)
|
||||
{
|
||||
int i;
|
||||
int i, count = static_cast<int>(Parse_names.size());
|
||||
|
||||
for (i=0; i<(int)Num_parse_names; i++)
|
||||
if (!stricmp(name, Parse_names[i]))
|
||||
for (i=0; i<count; ++i)
|
||||
if (!stricmp(name, Parse_names[i].c_str()))
|
||||
return i;
|
||||
|
||||
Assert(i < MAX_SHIPS + MAX_WINGS);
|
||||
Assert(strlen(name) < NAME_LENGTH);
|
||||
strcpy_s(Parse_names[i], name);
|
||||
return (int)Num_parse_names++;
|
||||
Parse_names.push_back(name);
|
||||
return i;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
|
||||
@@ -453,6 +453,8 @@ typedef struct team_data {
|
||||
#define MAX_SHIP_LIST 16
|
||||
|
||||
extern team_data Team_data[MAX_TVT_TEAMS];
|
||||
extern int Num_teams;
|
||||
|
||||
extern subsys_status *Subsys_status;
|
||||
extern int Subsys_index;
|
||||
|
||||
@@ -461,9 +463,7 @@ extern matrix Parse_viewer_orient;
|
||||
|
||||
extern fix Mission_end_time;
|
||||
|
||||
extern char Parse_names[MAX_SHIPS + MAX_WINGS][NAME_LENGTH];
|
||||
extern size_t Num_parse_names;
|
||||
extern int Num_teams;
|
||||
extern SCP_vector<SCP_string> Parse_names;
|
||||
|
||||
extern char Player_start_shipname[NAME_LENGTH];
|
||||
extern int Player_start_shipnum;
|
||||
@@ -483,8 +483,7 @@ bool parse_main(const char *mission_name, int flags = 0);
|
||||
p_object *mission_parse_get_arrival_ship(ushort net_signature);
|
||||
p_object *mission_parse_get_arrival_ship(const char *name);
|
||||
bool mission_check_ship_yet_to_arrive(const char *name);
|
||||
p_object *mission_parse_get_parse_object(ushort net_signature);
|
||||
p_object *mission_parse_get_parse_object(const char *name);
|
||||
p_object *mission_parse_find_parse_object(const char *name);
|
||||
int parse_create_object(p_object *objp, bool standalone_ship = false);
|
||||
void resolve_parse_flags(object *objp, flagset<Mission::Parse_Object_Flags> &parse_flags);
|
||||
|
||||
@@ -554,6 +553,8 @@ void clear_texture_replacements();
|
||||
// Goober5000
|
||||
subsys_status *parse_get_subsys_status(p_object *pobjp, const char *subsys_name);
|
||||
|
||||
// MjnMixael
|
||||
mission_custom_string* get_custom_string_by_name(SCP_string name);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -187,7 +187,7 @@ void HudGaugeDirectives::initBitmaps(char *fname_top, char *fname_middle, char *
|
||||
}
|
||||
}
|
||||
|
||||
bool HudGaugeDirectives::canRender()
|
||||
bool HudGaugeDirectives::canRender() const
|
||||
{
|
||||
if (sexp_override) {
|
||||
return false;
|
||||
@@ -1050,7 +1050,7 @@ HudGauge(HUD_OBJECT_TRAINING_MESSAGES, HUD_DIRECTIVES_VIEW, false, true, VM_EXTE
|
||||
{
|
||||
}
|
||||
|
||||
bool HudGaugeTrainingMessages::canRender()
|
||||
bool HudGaugeTrainingMessages::canRender() const
|
||||
{
|
||||
if (hud_disabled() && !hud_disabled_except_messages()) {
|
||||
return false;
|
||||
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
void initKeyLineXOffset(int offset);
|
||||
void render(float frametime) override;
|
||||
void pageIn() override;
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
};
|
||||
|
||||
class HudGaugeTrainingMessages: public HudGauge
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
HudGaugeTrainingMessages();
|
||||
void render(float frametime) override;
|
||||
void pageIn() override;
|
||||
bool canRender() override;
|
||||
bool canRender() const override;
|
||||
};
|
||||
|
||||
#endif /* __MISSIONTRAINING_H__ */
|
||||
+98
-199
@@ -230,8 +230,7 @@ int Chat_scroll_down_coord[2];
|
||||
// what chars other than letters and number's we'll toss
|
||||
#define CHATBOX_INVALID_CHARS NOX("~`") // this is primarily so that we don't interfere with the voice recording keys
|
||||
|
||||
// common defines and data
|
||||
#define CHATBOX_STRING_LEN (CALLSIGN_LEN + CHATBOX_MAX_LEN + 32)
|
||||
// common defines and
|
||||
UI_WINDOW Chat_window;
|
||||
UI_INPUTBOX Chat_inputbox;
|
||||
UI_BUTTON Chat_enter_text;
|
||||
@@ -275,17 +274,12 @@ int Chatbox_created = 0;
|
||||
///////////////////////////////////////////////////////////
|
||||
// Chat window text
|
||||
///////////////////////////////////////////////////////////
|
||||
#define MAX_BRIEF_CHAT_LINES 60 // how many lines we can store in the scrollback buffer
|
||||
#define BRIEF_DISPLAY_SPACING 2 // pixel spacing between chat lines
|
||||
|
||||
// the first byte of the text string will be the net player id of the
|
||||
char Brief_chat_lines[MAX_BRIEF_CHAT_LINES][CHATBOX_STRING_LEN];
|
||||
int Brief_chat_indents[MAX_BRIEF_CHAT_LINES];
|
||||
// the first byte of the text string will be the net player id of the
|
||||
SCP_list<brief_chat> Brief_chat;
|
||||
|
||||
int Brief_chat_next_index[MAX_BRIEF_CHAT_LINES];
|
||||
int Brief_chat_prev_index[MAX_BRIEF_CHAT_LINES];
|
||||
int Num_brief_chat_lines;
|
||||
int Brief_current_add_line;
|
||||
// the index of the chat line we will start rendering at
|
||||
int Brief_start_display_index;
|
||||
|
||||
// chatbox line recall data
|
||||
@@ -304,7 +298,6 @@ void chatbox_set_mode(int mode_flags);
|
||||
void chatbox_toggle_size();
|
||||
void chatbox_toggle_size_adjust_lines();
|
||||
void chat_autosplit_line(char *msg,char *remainder);
|
||||
int chatbox_num_displayed_lines();
|
||||
void chatbox_recall_add(char *string);
|
||||
void chatbox_recall_up();
|
||||
void chatbox_recall_down();
|
||||
@@ -666,11 +659,9 @@ void chatbox_clear()
|
||||
{
|
||||
// only do this if we have valid data
|
||||
if(Chatbox_created){
|
||||
// clear all chat data
|
||||
memset(Brief_chat_lines,0,(MAX_BRIEF_CHAT_LINES * (CHATBOX_MAX_LEN + 2)));
|
||||
// clear all chat data
|
||||
Brief_chat.clear();
|
||||
Brief_start_display_index=0;
|
||||
Num_brief_chat_lines=0;
|
||||
Brief_current_add_line=0;
|
||||
|
||||
// clear all line recall data
|
||||
Chatbox_recall_count = 0;
|
||||
@@ -708,15 +699,11 @@ void chatbox_render()
|
||||
// try and scroll the chatbox up. return 0 or 1 on fail or success
|
||||
int chatbox_scroll_up()
|
||||
{
|
||||
if(Num_brief_chat_lines > Chatbox_max_lines){
|
||||
int prev = Brief_chat_prev_index[Brief_start_display_index];
|
||||
|
||||
// check to make sure we won't be going "up" above the "beginning" of the text array
|
||||
if(Brief_chat_prev_index[Brief_current_add_line] != prev && !(Num_brief_chat_lines < MAX_BRIEF_CHAT_LINES && Brief_start_display_index==0)){
|
||||
Brief_start_display_index = prev;
|
||||
if (static_cast<int>(Brief_chat.size()) > Chatbox_max_lines) {
|
||||
if (Brief_start_display_index > 0) {
|
||||
Brief_start_display_index--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -724,50 +711,18 @@ int chatbox_scroll_up()
|
||||
// try and scroll the chatbox down, return 0 or 1 on fail or success
|
||||
int chatbox_scroll_down()
|
||||
{
|
||||
int idx;
|
||||
int next;
|
||||
|
||||
if(Num_brief_chat_lines > Chatbox_max_lines){
|
||||
// yuck. There's got to be a better way to do this.
|
||||
next = Brief_chat_next_index[Brief_start_display_index];
|
||||
for(idx = 1;idx <= Chatbox_max_lines; idx++){
|
||||
next = Brief_chat_next_index[next];
|
||||
}
|
||||
|
||||
// check to make sure we won't be going "down" below the "bottom" of the text array
|
||||
if(Brief_chat_next_index[Brief_current_add_line] != next){
|
||||
Brief_start_display_index = Brief_chat_next_index[Brief_start_display_index];
|
||||
if (static_cast<int>(Brief_chat.size()) > Chatbox_max_lines) {
|
||||
if (Brief_start_display_index < (static_cast<int>(Brief_chat.size()) - Chatbox_max_lines)) {
|
||||
Brief_start_display_index++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// quick explanation as to how the scrolling works :
|
||||
// Brief_chat_next_index is an array A of size n, where A[i] = i+1 and A[n] = 0
|
||||
// Brief_chat_prev_index is an array A of size n, where A[i] = i-1 and A[0] = n
|
||||
// in other words, if you increment an integer i = A[i], you get the next index (or the prev)
|
||||
// with wrapping. In this way, as chat lines are entered, they are continuously wrapped
|
||||
// around the Brief_chat_lines array so we can keep it at a fixed size. These arrays are used
|
||||
// for both entering new chat strings as well as moving the Brief_start_display_index
|
||||
// integer, which is self-explanatory
|
||||
|
||||
void chatbox_chat_init()
|
||||
{
|
||||
int idx;
|
||||
|
||||
chatbox_clear();
|
||||
|
||||
// setup the wraparound arrays
|
||||
for(idx=0;idx<MAX_BRIEF_CHAT_LINES;idx++){
|
||||
Brief_chat_next_index[idx] = idx+1;
|
||||
}
|
||||
Brief_chat_next_index[MAX_BRIEF_CHAT_LINES-1]=0;
|
||||
|
||||
for(idx=MAX_BRIEF_CHAT_LINES-1; idx > 0 ; idx--){
|
||||
Brief_chat_prev_index[idx] = idx - 1;
|
||||
}
|
||||
Brief_chat_prev_index[0] = MAX_BRIEF_CHAT_LINES-1;
|
||||
chatbox_clear();
|
||||
|
||||
// initialize the line recall data
|
||||
Chatbox_recall_count = 0;
|
||||
@@ -776,91 +731,63 @@ void chatbox_chat_init()
|
||||
memset(Chatbox_recall_lines,0,CHATBOX_MAX_RECALL_LINES * (CHATBOX_MAX_LEN + 2));
|
||||
}
|
||||
|
||||
void chat_box_add_chat_to_list(brief_chat& chat)
|
||||
{
|
||||
if (Brief_chat.size() >= MAX_BRIEF_CHAT_LINES) {
|
||||
Brief_chat.erase(Brief_chat.begin());
|
||||
}
|
||||
|
||||
Brief_chat.push_back(chat);
|
||||
}
|
||||
|
||||
// int Test_color = 0;
|
||||
void chatbox_add_line(const char *msg, int pid, int add_id)
|
||||
{
|
||||
int backup;
|
||||
int n_lines,idx;
|
||||
int n_chars[3];
|
||||
const char *p_str[3]; // for the initial line (unindented)
|
||||
char msg_extra[CHATBOX_STRING_LEN];
|
||||
|
||||
{
|
||||
if(!Chatbox_created){
|
||||
return;
|
||||
}
|
||||
|
||||
brief_chat chat;
|
||||
chat.indent = false;
|
||||
chat.player_id = pid;
|
||||
|
||||
// maybe stick on who sent the message
|
||||
if(add_id){
|
||||
if(MULTI_STANDALONE(Net_players[pid])){
|
||||
sprintf(msg_extra, NOX("%s %s"), NOX("<SERVER>"), msg );
|
||||
strcpy_s(chat.callsign, "<SERVER>");
|
||||
} else {
|
||||
sprintf(msg_extra, NOX("%s: %s"), Net_players[pid].m_player->short_callsign, msg );
|
||||
strcpy_s(chat.callsign, Net_players[pid].m_player->short_callsign);
|
||||
}
|
||||
} else {
|
||||
strcpy_s(msg_extra,msg);
|
||||
chat.callsign[0] = '\0';
|
||||
}
|
||||
Assert(strlen(msg_extra) < (CHATBOX_STRING_LEN - 2));
|
||||
|
||||
// split the text up into as many lines as necessary
|
||||
n_lines = split_str(msg_extra, Chatbox_disp_w, n_chars, p_str, 3, CHATBOX_STRING_LEN);
|
||||
Assert(n_lines != -1);
|
||||
|
||||
// setup the first line -- be sure to clear out the line
|
||||
memset( Brief_chat_lines[Brief_current_add_line], 0, CHATBOX_STRING_LEN );
|
||||
|
||||
// add the player id #
|
||||
Brief_chat_lines[Brief_current_add_line][0] = (char)(pid % 16);
|
||||
// Brief_chat_lines[Brief_current_add_line][0] = (char)Test_color;
|
||||
// Test_color = (Test_color == MAX_PLAYERS - 1) ? 0 : Test_color++;
|
||||
|
||||
// set the indent to 0
|
||||
Brief_chat_indents[Brief_current_add_line] = 0;
|
||||
int n_chars[3];
|
||||
const char* p_str[3]; // for the initial line (unindented)
|
||||
int n_lines = split_str(msg, Chatbox_disp_w, n_chars, p_str, 3, CHATBOX_STRING_LEN);
|
||||
Assertion(n_lines != -1, "Chat split string returned an invalid number of lines, please report!");
|
||||
|
||||
// copy in the chars
|
||||
strncpy(&Brief_chat_lines[Brief_current_add_line][1],p_str[0],CHATBOX_STRING_LEN - 1);
|
||||
if(n_chars[0] >= CHATBOX_STRING_LEN){
|
||||
Brief_chat_lines[Brief_current_add_line][CHATBOX_STRING_LEN - 1] = '\0';
|
||||
} else {
|
||||
Brief_chat_lines[Brief_current_add_line][n_chars[0] + 1] = '\0';
|
||||
}
|
||||
|
||||
// increment the total line count if we haven't reached the max already
|
||||
if(Num_brief_chat_lines<MAX_BRIEF_CHAT_LINES){
|
||||
Num_brief_chat_lines++;
|
||||
}
|
||||
|
||||
// get the index of the next string to add text to
|
||||
Brief_current_add_line = Brief_chat_next_index[Brief_current_add_line];
|
||||
strcpy_s(chat.text, p_str[0]);
|
||||
|
||||
chat_box_add_chat_to_list(chat);
|
||||
|
||||
// if we have more than 1 line, re-split everything so that the rest are indented
|
||||
if(n_lines > 1){
|
||||
// split up the string after the first break-marker
|
||||
char msg_extra[CHATBOX_STRING_LEN];
|
||||
n_lines = split_str(msg_extra + n_chars[0],Chatbox_disp_w - CHAT_LINE_INDENT,n_chars,p_str,3, CHATBOX_STRING_LEN);
|
||||
Assert(n_lines != -1);
|
||||
Assertion(n_lines != -1, "Chat split string returned an invalid number of lines, please report!");
|
||||
|
||||
// setup these remaining lines
|
||||
for(idx=0;idx<n_lines;idx++){
|
||||
// add the player id#
|
||||
Brief_chat_lines[Brief_current_add_line][0] = (char)(pid % 16);
|
||||
for(int idx=0;idx<n_lines;idx++){
|
||||
brief_chat i_chat;
|
||||
i_chat.player_id = pid;
|
||||
i_chat.indent = true;
|
||||
strcpy_s(i_chat.text, p_str[idx]);
|
||||
|
||||
// add the proper indent
|
||||
Brief_chat_indents[Brief_current_add_line] = CHAT_LINE_INDENT;
|
||||
|
||||
// copy in the line text itself
|
||||
strncpy(&Brief_chat_lines[Brief_current_add_line][1],p_str[idx],CHATBOX_STRING_LEN-1);
|
||||
if(n_chars[idx] >= CHATBOX_STRING_LEN){
|
||||
Brief_chat_lines[Brief_current_add_line][CHATBOX_STRING_LEN - 1] = '\0';
|
||||
} else {
|
||||
Brief_chat_lines[Brief_current_add_line][n_chars[idx] + 1] = '\0';
|
||||
}
|
||||
|
||||
// increment the total line count if we haven't reached the max already
|
||||
if(Num_brief_chat_lines<MAX_BRIEF_CHAT_LINES){
|
||||
Num_brief_chat_lines++;
|
||||
}
|
||||
|
||||
// get the index of the next line to add text to
|
||||
Brief_current_add_line = Brief_chat_next_index[Brief_current_add_line];
|
||||
chat_box_add_chat_to_list(i_chat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -873,11 +800,8 @@ void chatbox_add_line(const char *msg, int pid, int add_id)
|
||||
// if this line of text is from the player himself, automatically go to the bottom of
|
||||
// the chat list
|
||||
if(pid == MY_NET_PLAYER_NUM){
|
||||
if(Num_brief_chat_lines > Chatbox_max_lines){
|
||||
Brief_start_display_index = Brief_current_add_line;
|
||||
for(backup = 1;backup <= Chatbox_max_lines;backup++){
|
||||
Brief_start_display_index = Brief_chat_prev_index[Brief_start_display_index];
|
||||
}
|
||||
if (static_cast<int>(Brief_chat.size()) > Chatbox_max_lines) {
|
||||
Brief_start_display_index = (static_cast<int>(Brief_chat.size()) - Chatbox_max_lines);
|
||||
}
|
||||
}
|
||||
// if we have enough lines of text to require scrolling, scroll down by one.
|
||||
@@ -888,54 +812,69 @@ void chatbox_add_line(const char *msg, int pid, int add_id)
|
||||
|
||||
void chatbox_render_chat_lines()
|
||||
{
|
||||
int started_at,player_num,count,ly,line_height;
|
||||
|
||||
started_at = Brief_start_display_index;
|
||||
count = 0;
|
||||
ly = Chatbox_begin_y;
|
||||
line_height = gr_get_font_height() + 1;
|
||||
while((count < Chatbox_max_lines) && (count < Num_brief_chat_lines)){
|
||||
// determine what player this chat line came from, and set the appropriate text color
|
||||
player_num = Brief_chat_lines[started_at][0];
|
||||
|
||||
// print the line out
|
||||
gr_set_color_fast(Color_netplayer[player_num]);
|
||||
int count = 0;
|
||||
int ly = Chatbox_begin_y;
|
||||
int line_height = gr_get_font_height() + 1;
|
||||
|
||||
// draw the first line (no indent)
|
||||
gr_string(Chatbox_begin_x + Brief_chat_indents[started_at],ly,&Brief_chat_lines[started_at][1],GR_RESIZE_MENU);
|
||||
if (Brief_chat.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assertion(Brief_start_display_index >= 0 && Brief_start_display_index < static_cast<int>(Brief_chat.size()),
|
||||
"Chat display index is invalid, please report!");
|
||||
|
||||
auto chat = Brief_chat.begin();
|
||||
std::advance(chat, Brief_start_display_index);
|
||||
|
||||
while (chat != Brief_chat.end() && count < Chatbox_max_lines) {
|
||||
char msg[CHATBOX_STRING_LEN];
|
||||
|
||||
// add the player callsign
|
||||
sprintf(msg, "%s %s", chat->callsign, chat->text);
|
||||
Assertion(strlen(msg) < (CHATBOX_STRING_LEN - 2), "Chat string is too long, please report!");
|
||||
|
||||
// print the line out
|
||||
gr_set_color_fast(Color_netplayer[chat->player_id]);
|
||||
|
||||
// draw the first line (no indent)
|
||||
int indent = 0;
|
||||
if (chat->indent) {
|
||||
indent = CHAT_LINE_INDENT;
|
||||
}
|
||||
gr_string(Chatbox_begin_x + indent, ly, msg, GR_RESIZE_MENU);
|
||||
|
||||
// if we're in a team vs. team game, blit the player color icon
|
||||
if(Netgame.type_flags & NG_TYPE_TEAM){
|
||||
switch(Net_players[player_num].p_info.team){
|
||||
case 0 :
|
||||
if (Netgame.type_flags & NG_TYPE_TEAM) {
|
||||
switch (Net_players[chat->player_id].p_info.team) {
|
||||
case 0:
|
||||
// if he's a team captain
|
||||
if(Net_players[player_num].flags & NETINFO_FLAG_TEAM_CAPTAIN){
|
||||
if(Multi_common_icons[MICON_TEAM0_SELECT] != -1){
|
||||
if (Net_players[chat->player_id].flags & NETINFO_FLAG_TEAM_CAPTAIN) {
|
||||
if (Multi_common_icons[MICON_TEAM0_SELECT] != -1) {
|
||||
gr_set_bitmap(Multi_common_icons[MICON_TEAM0_SELECT]);
|
||||
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
|
||||
}
|
||||
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
|
||||
}
|
||||
}
|
||||
// just you're average peon
|
||||
else {
|
||||
if(Multi_common_icons[MICON_TEAM0] != -1){
|
||||
if (Multi_common_icons[MICON_TEAM0] != -1) {
|
||||
gr_set_bitmap(Multi_common_icons[MICON_TEAM0]);
|
||||
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
|
||||
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1 :
|
||||
case 1:
|
||||
// if he's a team captain
|
||||
if(Net_players[player_num].flags & NETINFO_FLAG_TEAM_CAPTAIN){
|
||||
if(Multi_common_icons[MICON_TEAM1_SELECT] != -1){
|
||||
if (Net_players[chat->player_id].flags & NETINFO_FLAG_TEAM_CAPTAIN) {
|
||||
if (Multi_common_icons[MICON_TEAM1_SELECT] != -1) {
|
||||
gr_set_bitmap(Multi_common_icons[MICON_TEAM1_SELECT]);
|
||||
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
|
||||
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
|
||||
}
|
||||
}
|
||||
// just your average peon
|
||||
else {
|
||||
if(Multi_common_icons[MICON_TEAM1] != -1){
|
||||
if (Multi_common_icons[MICON_TEAM1] != -1) {
|
||||
gr_set_bitmap(Multi_common_icons[MICON_TEAM1]);
|
||||
gr_bitmap(Chatbox_icon_x,ly-2,GR_RESIZE_MENU);
|
||||
gr_bitmap(Chatbox_icon_x, ly - 2, GR_RESIZE_MENU);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -943,11 +882,9 @@ void chatbox_render_chat_lines()
|
||||
}
|
||||
|
||||
// increment the count and line position
|
||||
count++;
|
||||
count++;
|
||||
++chat;
|
||||
ly += line_height;
|
||||
|
||||
// increment the started at index
|
||||
started_at = Brief_chat_next_index[started_at];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -971,52 +908,14 @@ void chatbox_toggle_size()
|
||||
|
||||
void chatbox_toggle_size_adjust_lines()
|
||||
{
|
||||
int count_diff;
|
||||
|
||||
// if the chatbox is now big, move the starting display index _up_ as far as possible
|
||||
if(Chatbox_mode_flags & CHATBOX_FLAG_BIG){
|
||||
// if we've wrapped around or we have more chatlines then we can display, move back as far as we can
|
||||
if((Num_brief_chat_lines > MAX_BRIEF_CHAT_LINES) || (Num_brief_chat_lines > Chatbox_max_lines)){
|
||||
count_diff = Chatbox_max_lines - chatbox_num_displayed_lines();
|
||||
while(count_diff > 0){
|
||||
Brief_start_display_index = Brief_chat_prev_index[Brief_start_display_index];
|
||||
count_diff--;
|
||||
}
|
||||
}
|
||||
// otherwise start displaying from position 0
|
||||
else {
|
||||
Brief_start_display_index = 0;
|
||||
}
|
||||
if ((static_cast<int>(Brief_chat.size()) > Chatbox_max_lines)) {
|
||||
Brief_start_display_index = (static_cast<int>(Brief_chat.size()) - Chatbox_max_lines);
|
||||
}
|
||||
// if the chatbox is now small, move the starting display index down as far as we need
|
||||
else if(Chatbox_mode_flags & CHATBOX_FLAG_SMALL){
|
||||
count_diff = chatbox_num_displayed_lines();
|
||||
// if we were displaying more lines than we can now
|
||||
if(count_diff > Chatbox_max_lines){
|
||||
count_diff -= Chatbox_max_lines;
|
||||
while(count_diff > 0){
|
||||
Brief_start_display_index = Brief_chat_next_index[Brief_start_display_index];
|
||||
count_diff--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Brief_start_display_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int chatbox_num_displayed_lines()
|
||||
{
|
||||
int idx = Brief_start_display_index;
|
||||
int count;
|
||||
|
||||
// count the lines up
|
||||
count = 0;
|
||||
while(idx != Brief_current_add_line){
|
||||
idx = Brief_chat_next_index[idx];
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// force the chatbox to go into small mode (if its in large mode) - will not wotk if in multi paused chatbox mode
|
||||
void chatbox_force_small()
|
||||
{
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
#ifndef __FREESPACE_CHATBOX_H__
|
||||
#define __FREESPACE_CHATBOX_H__
|
||||
|
||||
#include "globalincs/globals.h"
|
||||
|
||||
// prototype
|
||||
struct net_player;
|
||||
|
||||
#define CHATBOX_MAX_LEN 125 // max length of the actual text string
|
||||
#define CHATBOX_STRING_LEN (CALLSIGN_LEN + CHATBOX_MAX_LEN + 32)
|
||||
#define MAX_BRIEF_CHAT_LINES 60 // how many lines we can store in the scrollback buffer
|
||||
|
||||
// chatbox flags for creation/switching between modes
|
||||
#define CHATBOX_FLAG_SMALL (1<<0) // small chatbox
|
||||
@@ -25,6 +29,15 @@ struct net_player;
|
||||
#define CHATBOX_FLAG_BUTTONS (1<<4) // the chatbox should be drawing/checking its own buttons
|
||||
// NOTE : CHATBOX_FLAG_BUTTONS requires that CHATBOX_FLAG_DRAW_BOX is also set!
|
||||
|
||||
typedef struct brief_chat {
|
||||
int player_id; // the net player id
|
||||
bool indent; // true if the line should be indented
|
||||
char text[CHATBOX_MAX_LEN]; // the text of the message
|
||||
char callsign[CALLSIGN_LEN]; // the player's callsign
|
||||
} brief_chat;
|
||||
|
||||
extern SCP_list<brief_chat> Brief_chat;
|
||||
|
||||
// initialize all chatbox details with the given mode flags
|
||||
int chatbox_create(int mode_flags = (CHATBOX_FLAG_SMALL | CHATBOX_FLAG_DRAW_BOX | CHATBOX_FLAG_BUTTONS));
|
||||
|
||||
|
||||
@@ -1396,7 +1396,7 @@ int brief_setup_closeup(brief_icon *bi, bool api_access)
|
||||
Closeup_icon->modelnum = model_load(pof_filename, 0, nullptr);
|
||||
} else {
|
||||
Closeup_icon->modelnum = model_load(sip, true);
|
||||
Closeup_icon->model_instance_num = model_create_instance(-1, Closeup_icon->modelnum);
|
||||
Closeup_icon->model_instance_num = model_create_instance(model_objnum_special::OBJNUM_NONE, Closeup_icon->modelnum);
|
||||
model_set_up_techroom_instance(sip, Closeup_icon->model_instance_num);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1963,7 +1963,9 @@ void debrief_init(bool API_Access)
|
||||
// be backed out if used chooses to replace them.
|
||||
scoring_level_close();
|
||||
|
||||
debrief_ui_init(); // init UI items
|
||||
if (!API_Access) {
|
||||
debrief_ui_init(); // init UI items
|
||||
}
|
||||
debrief_award_init();
|
||||
show_stats_init();
|
||||
debrief_voice_init();
|
||||
|
||||
@@ -1960,13 +1960,13 @@ void common_setup_room_lights()
|
||||
light_reset();
|
||||
auto tempv = vm_vec_new(-1.0f,0.3f,-1.0f);
|
||||
auto tempc = hdr_color(1.0f,0.95f,0.9f, 0.0f, 1.5f);
|
||||
light_add_directional(&tempv,&tempc);
|
||||
light_add_directional(&tempv,-1,false,&tempc);
|
||||
tempv.xyz={-0.4f,0.4f,1.1f};
|
||||
tempc = hdr_color(0.788f,0.886f,1.0f,0.0f,1.5f);
|
||||
light_add_directional(&tempv,&tempc);
|
||||
light_add_directional(&tempv,-1,false,&tempc);
|
||||
tempv.xyz={0.4f,0.1f,0.4f};
|
||||
tempc = hdr_color(1.0f,1.0f,1.0f,0.0f,0.4f);
|
||||
light_add_directional(&tempv,&tempc);
|
||||
light_add_directional(&tempv,-1,false,&tempc);
|
||||
gr_set_ambient_light(53, 53, 53);
|
||||
light_rotate_all();
|
||||
}
|
||||
|
||||
@@ -2352,12 +2352,12 @@ void wl_render_weapon_desc(float frametime)
|
||||
if (!Weapon_desc_wipe_done) {
|
||||
// draw mid-wipe version
|
||||
// decide which char is last (and bright)
|
||||
int bright_char_index = (int)(Weapon_desc_wipe_time_elapsed * WEAPON_DESC_MAX_LENGTH / WEAPON_DESC_WIPE_TIME);
|
||||
int i, w, h, curr_len;
|
||||
size_t bright_char_index = (size_t)(Weapon_desc_wipe_time_elapsed * WEAPON_DESC_MAX_LENGTH / WEAPON_DESC_WIPE_TIME);
|
||||
int i, w, h;
|
||||
|
||||
// draw weapon title (above weapon anim)
|
||||
for (i=0; i<2; i++) {
|
||||
curr_len = (int)strlen(Weapon_desc_lines[i]);
|
||||
size_t curr_len = strlen(Weapon_desc_lines[i]);
|
||||
|
||||
if (bright_char_index < curr_len) {
|
||||
// save bright char and plunk in some nulls to shorten string
|
||||
@@ -2385,7 +2385,7 @@ void wl_render_weapon_desc(float frametime)
|
||||
|
||||
// draw weapon desc (below weapon anim)
|
||||
for (i=2; i<WEAPON_DESC_MAX_LINES; i++) {
|
||||
curr_len = (int)strlen(Weapon_desc_lines[i]);
|
||||
size_t curr_len = strlen(Weapon_desc_lines[i]);
|
||||
|
||||
if (bright_char_index < curr_len) {
|
||||
// save bright char and plunk in some nulls to shorten string
|
||||
@@ -2439,9 +2439,10 @@ void wl_render_weapon_desc(float frametime)
|
||||
*/
|
||||
void wl_weapon_desc_start_wipe()
|
||||
{
|
||||
int currchar_src = 0, currline_dest = 2, currchar_dest = 0, i;
|
||||
size_t currchar_src = 0;
|
||||
int currline_dest = 2, currchar_dest = 0, i;
|
||||
int w, h;
|
||||
int title_len = (int)strlen(Weapon_info[Selected_wl_class].title);
|
||||
size_t title_len = strlen(Weapon_info[Selected_wl_class].title);
|
||||
|
||||
// init wipe vars
|
||||
Weapon_desc_wipe_time_elapsed = 0.0f;
|
||||
@@ -2452,7 +2453,7 @@ void wl_weapon_desc_start_wipe()
|
||||
gr_get_string_size(&w, &h, Weapon_info[Selected_wl_class].title, title_len);
|
||||
if (w > Weapon_title_max_width[gr_screen.res]) {
|
||||
// split
|
||||
currchar_src = (int)(((float)title_len / (float)w) * Weapon_title_max_width[gr_screen.res]); // char to start space search at
|
||||
currchar_src = (size_t)(((float)title_len / (float)w) * Weapon_title_max_width[gr_screen.res]); // char to start space search at
|
||||
while (Weapon_desc_lines[0][currchar_src] != ' ') {
|
||||
currchar_src--;
|
||||
if (currchar_src <= 0) {
|
||||
@@ -2960,7 +2961,7 @@ void wl_render_icon_count(int num, int x, int y)
|
||||
Assert(number_to_draw >= 0);
|
||||
|
||||
sprintf(buf, "%d", number_to_draw);
|
||||
gr_get_string_size(&num_w, &num_h, buf, (int)strlen(buf));
|
||||
gr_get_string_size(&num_w, &num_h, buf, strlen(buf));
|
||||
|
||||
// render
|
||||
gr_set_color_fast(&Color_white);
|
||||
|
||||
@@ -48,6 +48,7 @@ bool Enable_external_default_scripts;
|
||||
int Default_detail_level;
|
||||
bool Full_color_head_anis;
|
||||
bool Dont_automatically_select_turret_when_targeting_ship;
|
||||
bool Automatically_select_subsystem_under_reticle_when_targeting_same_ship;
|
||||
bool Always_reset_selected_wep_on_loadout_open;
|
||||
bool Weapons_inherit_parent_collision_group;
|
||||
bool Flight_controls_follow_eyepoint_orientation;
|
||||
@@ -149,11 +150,12 @@ bool Randomize_particle_rotation;
|
||||
bool Calculate_subsystem_hitpoints_after_parsing;
|
||||
bool Disable_internal_loadout_restoration_system;
|
||||
bool Contrails_use_absolute_speed;
|
||||
bool Lua_API_returns_nil_instead_of_invalid_object;
|
||||
|
||||
static auto DiscordOption __UNUSED = options::OptionBuilder<bool>("Game.Discord",
|
||||
std::pair<const char*, int>{"Discord Presence", 1754},
|
||||
std::pair<const char*, int>{"Toggle Discord Rich Presence", 1755})
|
||||
.category("Game")
|
||||
.category(std::make_pair("Game", 1824))
|
||||
.default_val(Discord_presence)
|
||||
.level(options::ExpertLevel::Advanced)
|
||||
.importance(55)
|
||||
@@ -296,6 +298,11 @@ void parse_mod_table(const char *filename)
|
||||
stuff_boolean(&Disable_internal_loadout_restoration_system);
|
||||
}
|
||||
|
||||
if (optional_string("$Lua API returns nil instead of invalid object:")) {
|
||||
stuff_boolean(&Lua_API_returns_nil_instead_of_invalid_object);
|
||||
mprintf(("Game Settings Table: Lua API returns nil instead of invalid object: %s\n", Lua_API_returns_nil_instead_of_invalid_object ? "yes" : "no"));
|
||||
}
|
||||
|
||||
optional_string("#LOCALIZATION SETTINGS");
|
||||
|
||||
if (optional_string("$Use tabled strings for the default language:")) {
|
||||
@@ -418,6 +425,10 @@ void parse_mod_table(const char *filename)
|
||||
stuff_boolean(&Dont_automatically_select_turret_when_targeting_ship);
|
||||
}
|
||||
|
||||
if (optional_string("$Auto select subsystem under reticle when targeting same ship:")) {
|
||||
stuff_boolean(&Automatically_select_subsystem_under_reticle_when_targeting_same_ship);
|
||||
}
|
||||
|
||||
if (optional_string("$Supernova hits at zero:")) {
|
||||
stuff_boolean(&Supernova_hits_at_zero);
|
||||
if (Supernova_hits_at_zero) {
|
||||
@@ -1443,6 +1454,7 @@ void mod_table_reset()
|
||||
Default_detail_level = 3; // "very high" seems a reasonable default in 2012 -zookeeper
|
||||
Full_color_head_anis = false;
|
||||
Dont_automatically_select_turret_when_targeting_ship = false;
|
||||
Automatically_select_subsystem_under_reticle_when_targeting_same_ship = false;
|
||||
Always_reset_selected_wep_on_loadout_open = false;
|
||||
Weapons_inherit_parent_collision_group = false;
|
||||
Flight_controls_follow_eyepoint_orientation = false;
|
||||
@@ -1474,7 +1486,7 @@ void mod_table_reset()
|
||||
Window_icon_path = "app_icon_sse";
|
||||
Disable_built_in_translations = false;
|
||||
Weapon_shockwaves_respect_huge = false;
|
||||
Using_in_game_options = false;
|
||||
Using_in_game_options = true;
|
||||
Dinky_shockwave_default_multiplier = 1.0f;
|
||||
Shockwaves_always_damage_bombs = false;
|
||||
Shockwaves_damage_all_obj_types_once = false;
|
||||
@@ -1551,6 +1563,7 @@ void mod_table_reset()
|
||||
Calculate_subsystem_hitpoints_after_parsing = false;
|
||||
Disable_internal_loadout_restoration_system = false;
|
||||
Contrails_use_absolute_speed = false;
|
||||
Lua_API_returns_nil_instead_of_invalid_object = false;
|
||||
}
|
||||
|
||||
void mod_table_set_version_flags()
|
||||
|
||||
@@ -56,6 +56,7 @@ extern bool Enable_external_default_scripts;
|
||||
extern int Default_detail_level;
|
||||
extern bool Full_color_head_anis;
|
||||
extern bool Dont_automatically_select_turret_when_targeting_ship;
|
||||
extern bool Automatically_select_subsystem_under_reticle_when_targeting_same_ship;
|
||||
extern bool Always_reset_selected_wep_on_loadout_open;
|
||||
extern bool Weapons_inherit_parent_collision_group;
|
||||
extern bool Flight_controls_follow_eyepoint_orientation;
|
||||
@@ -158,6 +159,7 @@ extern bool Randomize_particle_rotation;
|
||||
extern bool Calculate_subsystem_hitpoints_after_parsing;
|
||||
extern bool Disable_internal_loadout_restoration_system;
|
||||
extern bool Contrails_use_absolute_speed;
|
||||
extern bool Lua_API_returns_nil_instead_of_invalid_object;
|
||||
|
||||
void mod_table_init();
|
||||
void mod_table_post_process();
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace animation {
|
||||
//We are in multiplayer. Send animation to server to start. Server starts animation online, and sends start request back (which'll have multiOverride == true).
|
||||
//If we _are_ the server, also just start the animation
|
||||
|
||||
object* objp = pmi->objnum > -1 ? &Objects[pmi->objnum] : nullptr;
|
||||
object* objp = pmi->objnum >= 0 ? &Objects[pmi->objnum] : nullptr;
|
||||
|
||||
if(objp != nullptr)
|
||||
send_animation_triggered_packet(id, objp, 0, direction, force, instant, pause);
|
||||
@@ -1446,9 +1446,8 @@ namespace animation {
|
||||
ModelAnimationParseHelper::parseAnimsetInfo(set, 's', sip->name);
|
||||
}
|
||||
|
||||
void ModelAnimationParseHelper::parseAnimsetInfoDrivers(ModelAnimationSet& set, ship_info* sip) {
|
||||
void ModelAnimationParseHelper::parseAnimsetInfoDrivers(ModelAnimationSet& set, char uniquePrefix, const SCP_string& parentName, std::function<std::function<float(polymodel_instance *)>()> driverSourceParser) {
|
||||
set.m_animationSet.clear();
|
||||
set.changeShipName(sip->name);
|
||||
|
||||
while(optional_string("+Driver Set:")) {
|
||||
decltype(ModelAnimation::m_driver) driver;
|
||||
@@ -1457,7 +1456,7 @@ namespace animation {
|
||||
|
||||
if (optional_string("+Time Remap:")) {
|
||||
required_string("+Source:");
|
||||
std::function<float(polymodel_instance *)> remap_driver_source = parse_ship_property_driver_source();
|
||||
std::function<float(polymodel_instance *)> remap_driver_source = driverSourceParser();
|
||||
if (!remap_driver_source) {
|
||||
error_display(0, "Unknown driver specifier encountered! Driver will be disabled!");
|
||||
continue;
|
||||
@@ -1550,7 +1549,7 @@ namespace animation {
|
||||
auto animIt = s_animationsById.find(request);
|
||||
if (animIt != s_animationsById.end()) {
|
||||
const ParsedModelAnimation& foundAnim = animIt->second;
|
||||
auto anim = set.emplace(foundAnim.anim, request, foundAnim.name, foundAnim.type, foundAnim.subtype, ModelAnimationParseHelper::getUniqueAnimationID(animIt->first, 's', sip->name));
|
||||
auto anim = set.emplace(foundAnim.anim, request, foundAnim.name, foundAnim.type, foundAnim.subtype, ModelAnimationParseHelper::getUniqueAnimationID(animIt->first, uniquePrefix, parentName));
|
||||
|
||||
if (driver)
|
||||
anim->m_driver = driver;
|
||||
@@ -1564,6 +1563,13 @@ namespace animation {
|
||||
}
|
||||
}
|
||||
|
||||
void ModelAnimationParseHelper::parseAnimsetInfoDrivers(ModelAnimationSet& set, ship_info* sip) {
|
||||
set.m_animationSet.clear();
|
||||
set.changeShipName(sip->name);
|
||||
|
||||
parseAnimsetInfoDrivers(set, 's', sip->name, parse_ship_property_driver_source);
|
||||
}
|
||||
|
||||
void ModelAnimationParseHelper::parseMoveablesetInfo(ModelAnimationSet& set) {
|
||||
SCP_vector<SCP_string> requestedAnimations;
|
||||
stuff_string_list(requestedAnimations);
|
||||
|
||||
@@ -416,6 +416,8 @@ namespace animation {
|
||||
static void parseAnimsetInfo(ModelAnimationSet& set, ship_info* sip);
|
||||
static void parseAnimsetInfo(ModelAnimationSet& set, char uniqueTypePrefix, const SCP_string& uniqueParentName);
|
||||
static void parseAnimsetInfoDrivers(ModelAnimationSet& set, ship_info* sip);
|
||||
static void parseAnimsetInfoDrivers(ModelAnimationSet& set, char uniquePrefix, const SCP_string& parentName, std::function<std::function<float(polymodel_instance *)>()> driverSourceParser);
|
||||
|
||||
static void parseMoveablesetInfo(ModelAnimationSet& set);
|
||||
//Parses the legacy animation table in ships.tbl of a single subsystem. Currently initial animations only
|
||||
static void parseLegacyAnimationTable(model_subsystem* sp, ship_info* sip);
|
||||
|
||||
@@ -2,12 +2,24 @@
|
||||
|
||||
#include "hud/hudets.h"
|
||||
#include "model/animation/modelanimation.h"
|
||||
#include "playerman/player.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
namespace animation {
|
||||
template<float control_info::* ci_property>
|
||||
static float get_player_ci_property(polymodel_instance* /*pmi*/){
|
||||
return Player->ci.*ci_property;
|
||||
}
|
||||
|
||||
std::function<float(polymodel_instance*)> parse_generic_property_driver_source() {
|
||||
switch(optional_string_one_of(1,
|
||||
"Random"
|
||||
switch(optional_string_one_of(7,
|
||||
"Random",
|
||||
"ControlAccelForward",
|
||||
"ControlAccelLateral",
|
||||
"ControlAccelVertical",
|
||||
"ControlRotationPitch",
|
||||
"ControlRotationBank",
|
||||
"ControlRotationHeading"
|
||||
)){
|
||||
case 0: {
|
||||
float min, max;
|
||||
@@ -22,22 +34,40 @@ namespace animation {
|
||||
return static_cast<float>(std::mt19937(seed ^ pmi->objnum)()) / static_cast<float>(std::mt19937::max()) * (max - min) + min;
|
||||
};
|
||||
}
|
||||
case 1:
|
||||
return get_player_ci_property<&control_info::forward>;
|
||||
case 2:
|
||||
return get_player_ci_property<&control_info::sideways>;
|
||||
case 3:
|
||||
return get_player_ci_property<&control_info::vertical>;
|
||||
case 4:
|
||||
return get_player_ci_property<&control_info::pitch>;
|
||||
case 5:
|
||||
return get_player_ci_property<&control_info::bank>;
|
||||
case 6:
|
||||
return get_player_ci_property<&control_info::heading>;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
static int get_pmi_objnum(const polymodel_instance* pmi) {
|
||||
return pmi->objnum == model_objnum_special::OBJNUM_COCKPIT ? Player->objnum : pmi->objnum;
|
||||
}
|
||||
|
||||
template<typename property, property object::* property_ptr, float property::* subproperty_ptr>
|
||||
static float get_object_subproperty_float(polymodel_instance* pmi){
|
||||
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
|
||||
return Objects[pmi->objnum].*property_ptr.*subproperty_ptr;
|
||||
int objnum = get_pmi_objnum(pmi);
|
||||
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
|
||||
return Objects[objnum].*property_ptr.*subproperty_ptr;
|
||||
}
|
||||
|
||||
template<matrix object::* property_ptr, float angles::* angle>
|
||||
static float get_object_matrix_angle(polymodel_instance* pmi){
|
||||
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
|
||||
int objnum = get_pmi_objnum(pmi);
|
||||
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
|
||||
angles a;
|
||||
vm_extract_angles_matrix(&a, &(Objects[pmi->objnum].*property_ptr));
|
||||
vm_extract_angles_matrix(&a, &(Objects[objnum].*property_ptr));
|
||||
return a.*angle;
|
||||
}
|
||||
|
||||
@@ -70,16 +100,18 @@ namespace animation {
|
||||
|
||||
template<typename property, property ship::* property_ptr, float property::* subproperty_ptr>
|
||||
static float get_ship_subproperty_float(polymodel_instance* pmi){
|
||||
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
|
||||
Assertion(Objects[pmi->objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
|
||||
return Ships[Objects[pmi->objnum].instance].*property_ptr.*subproperty_ptr;
|
||||
int objnum = get_pmi_objnum(pmi);
|
||||
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
|
||||
Assertion(Objects[objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
|
||||
return Ships[Objects[objnum].instance].*property_ptr.*subproperty_ptr;
|
||||
}
|
||||
|
||||
template<int ship::* ets_property>
|
||||
static float get_ship_ets_property(polymodel_instance* pmi){
|
||||
Assertion(pmi->objnum >= 0, "Invalid object used in animation property driver!");
|
||||
Assertion(Objects[pmi->objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
|
||||
return Energy_levels[Ships[Objects[pmi->objnum].instance].*ets_property];
|
||||
int objnum = get_pmi_objnum(pmi);
|
||||
Assertion(objnum >= 0, "Invalid object used in animation property driver!");
|
||||
Assertion(Objects[objnum].type == OBJ_SHIP, "Non-ship object used in ship animation property driver!");
|
||||
return Energy_levels[Ships[Objects[objnum].instance].*ets_property];
|
||||
}
|
||||
|
||||
std::function<float(polymodel_instance*)> parse_ship_property_driver_source() {
|
||||
|
||||
+6
-1
@@ -73,6 +73,8 @@ extern int model_render_flags_size;
|
||||
|
||||
enum class modelread_status { FAIL, SUCCESS_REAL, SUCCESS_VIRTUAL };
|
||||
|
||||
enum model_objnum_special : int { OBJNUM_NONE = -1, OBJNUM_COCKPIT = -2, OBJNUM_SPECIAL_MIN = -3};
|
||||
|
||||
// Goober5000
|
||||
extern const char *Subsystem_types[SUBSYSTEM_MAX];
|
||||
|
||||
@@ -119,6 +121,7 @@ struct submodel_instance
|
||||
color arc_primary_color_1[MAX_ARC_EFFECTS];
|
||||
color arc_primary_color_2[MAX_ARC_EFFECTS];
|
||||
color arc_secondary_color[MAX_ARC_EFFECTS];
|
||||
float arc_width[MAX_ARC_EFFECTS]; // only used for MARC_TYPE_SHIP and MARC_TYPE_SCRIPTED
|
||||
vec3d arc_pts[MAX_ARC_EFFECTS][2];
|
||||
ubyte arc_type[MAX_ARC_EFFECTS]; // see MARC_TYPE_* defines
|
||||
|
||||
@@ -133,6 +136,7 @@ struct submodel_instance
|
||||
memset(&arc_primary_color_2, 0, MAX_ARC_EFFECTS * sizeof(color));
|
||||
memset(&arc_secondary_color, 0, MAX_ARC_EFFECTS * sizeof(color));
|
||||
memset(&arc_type, 0, MAX_ARC_EFFECTS * sizeof(ubyte));
|
||||
memset(&arc_width, 0, MAX_ARC_EFFECTS * sizeof(float));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -266,6 +270,7 @@ typedef struct model_special {
|
||||
#define MARC_TYPE_DAMAGED 0 // blue lightning arcs for when the ship is damaged
|
||||
#define MARC_TYPE_EMP 1 // EMP blast type arcs
|
||||
#define MARC_TYPE_SHIP 2 // arcing lightning thats intrinsically part of the ship
|
||||
#define MARC_TYPE_SCRIPTED 3 // an arc created via script
|
||||
|
||||
#define MAX_LIVE_DEBRIS 7
|
||||
|
||||
@@ -1190,7 +1195,7 @@ void model_replicate_submodel_instance(polymodel *pm, polymodel_instance *pmi, i
|
||||
|
||||
// Adds an electrical arcing effect to a submodel
|
||||
void model_instance_clear_arcs(polymodel *pm, polymodel_instance *pmi);
|
||||
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1 = nullptr, color *primary_color_2 = nullptr, color *secondary_color = nullptr);
|
||||
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1 = nullptr, color *primary_color_2 = nullptr, color *secondary_color = nullptr, float width = 0.0f);
|
||||
|
||||
// Gets two random points on the surface of a submodel
|
||||
extern vec3d submodel_get_random_point(int model_num, int submodel_num, int seed = -1);
|
||||
|
||||
@@ -1198,15 +1198,13 @@ int model_collide(mc_info *mc_info_obj)
|
||||
|
||||
}
|
||||
|
||||
if ( Mc->flags & MC_SUBMODEL ) {
|
||||
// Check only one subobject
|
||||
mc_check_subobj( Mc->submodel_num );
|
||||
// Check submodel and any children
|
||||
} else if (Mc->flags & MC_SUBMODEL_INSTANCE) {
|
||||
// Check only one subobject; or check submodel and any children
|
||||
if ( (Mc->flags & MC_SUBMODEL) || (Mc->flags & MC_SUBMODEL_INSTANCE) ) {
|
||||
// note: within this function, MC_SUBMODEL will return after one check; but MC_SUBMODEL_INSTANCE will not
|
||||
mc_check_subobj(Mc->submodel_num);
|
||||
} else {
|
||||
// Check all the the highest detail model polygons and subobjects for intersections
|
||||
|
||||
}
|
||||
// Check all the the highest detail model polygons and subobjects for intersections
|
||||
else {
|
||||
// Don't check it or its children if it is destroyed
|
||||
if ( Mc_pmi ) {
|
||||
if ( !Mc_pmi->submodel[Mc_pm->detail[0]].blown_off ) {
|
||||
|
||||
@@ -3538,7 +3538,7 @@ int model_load(const char* filename, int n_subsystems, model_subsystem* subsyst
|
||||
|
||||
int model_create_instance(int objnum, int model_num)
|
||||
{
|
||||
Assertion(objnum >= -1 && objnum < MAX_OBJECTS, "objnum must be -1 or a valid object index!");
|
||||
Assertion(objnum > OBJNUM_SPECIAL_MIN && objnum < MAX_OBJECTS, "objnum must be -1 (none), -2 (player cockpit) or a valid object index!");
|
||||
|
||||
// this will also run a bunch of Assertions
|
||||
auto pm = model_get(model_num);
|
||||
@@ -5155,7 +5155,7 @@ void model_instance_clear_arcs(polymodel *pm, polymodel_instance *pmi)
|
||||
}
|
||||
|
||||
// Adds an electrical arcing effect to a submodel
|
||||
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1, color *primary_color_2, color *secondary_color )
|
||||
void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type, color *primary_color_1, color *primary_color_2, color *secondary_color, float width )
|
||||
{
|
||||
Assert(pm->id == pmi->model_num);
|
||||
|
||||
@@ -5175,10 +5175,11 @@ void model_instance_add_arc(polymodel *pm, polymodel_instance *pmi, int sub_mode
|
||||
smi->arc_pts[smi->num_arcs][0] = *v1;
|
||||
smi->arc_pts[smi->num_arcs][1] = *v2;
|
||||
|
||||
if (arc_type == MARC_TYPE_SHIP) {
|
||||
if (arc_type == MARC_TYPE_SHIP || arc_type == MARC_TYPE_SCRIPTED) {
|
||||
smi->arc_primary_color_1[smi->num_arcs] = *primary_color_1;
|
||||
smi->arc_primary_color_2[smi->num_arcs] = *primary_color_2;
|
||||
smi->arc_secondary_color[smi->num_arcs] = *secondary_color;
|
||||
smi->arc_width[smi->num_arcs] = width;
|
||||
}
|
||||
|
||||
smi->num_arcs++;
|
||||
|
||||
@@ -862,6 +862,7 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
|
||||
|
||||
break;
|
||||
|
||||
case MARC_TYPE_SCRIPTED:
|
||||
case MARC_TYPE_SHIP:
|
||||
if ( Random::flip_coin() ) {
|
||||
primary = smi->arc_primary_color_1[i];
|
||||
@@ -870,16 +871,8 @@ void model_render_add_lightning(model_draw_list *scene, const model_render_param
|
||||
}
|
||||
|
||||
secondary = smi->arc_secondary_color[i];
|
||||
|
||||
// try and scale the size a bit so that it looks equally well on smaller vessels
|
||||
width = Arc_width_default_damage;
|
||||
if (pm->rad < Arc_width_no_multiply_over_radius_damage) {
|
||||
width *= (pm->rad * Arc_width_radius_multiplier_damage);
|
||||
|
||||
if (width < Arc_width_minimum_damage) {
|
||||
width = Arc_width_minimum_damage;
|
||||
}
|
||||
}
|
||||
width = smi->arc_width[i];
|
||||
|
||||
break;
|
||||
|
||||
@@ -3189,7 +3182,7 @@ bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int
|
||||
|
||||
// Create an instance for ships that can be used to clear out destroyed subobjects from rendering
|
||||
if (model_type == TECH_SHIP) {
|
||||
model_instance = model_create_instance(-1, model_num);
|
||||
model_instance = model_create_instance(model_objnum_special::OBJNUM_NONE, model_num);
|
||||
model_set_up_techroom_instance(&Ship_info[class_idx], model_instance);
|
||||
}
|
||||
|
||||
|
||||
+29
-48
@@ -15,6 +15,7 @@
|
||||
#include "debugconsole/console.h"
|
||||
#include "freespace.h"
|
||||
#include "jpgutils/jpgutils.h"
|
||||
#include "math/bitarray.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "nebula/neb.h"
|
||||
#include "object/object.h"
|
||||
@@ -59,15 +60,15 @@ SCP_vector<poof_info> Poof_info;
|
||||
|
||||
float Poof_dist_threshold;
|
||||
vec3d Poof_last_gen_pos;
|
||||
float Poof_accum[MAX_NEB2_POOFS];
|
||||
SCP_vector<float> Poof_accum;
|
||||
float Poof_density_multiplier;
|
||||
|
||||
const float UPKEEP_DIST_MULT = 1.2f;
|
||||
|
||||
const float PROBABLY_TOO_MANY_POOFS = 100000.0f;
|
||||
|
||||
// array of neb2 poofs
|
||||
int32_t Neb2_poof_flags = 0;
|
||||
// bit array of neb2 poofs
|
||||
std::unique_ptr<ubyte> Neb2_poof_flags;
|
||||
|
||||
// array of neb2 bitmaps
|
||||
SCP_vector<SCP_string> Neb2_bitmap_filenames;
|
||||
@@ -137,7 +138,7 @@ const SCP_vector<std::pair<int, std::pair<const char*, int>>> DetailLevelValues
|
||||
const auto NebulaDetailOption __UNUSED = options::OptionBuilder<int>("Graphics.NebulaDetail",
|
||||
std::pair<const char*, int>{"Nebula Detail", 1361},
|
||||
std::pair<const char*, int>{"Detail level of nebulas", 1697})
|
||||
.category("Graphics")
|
||||
.category(std::make_pair("Graphics", 1825))
|
||||
.values(DetailLevelValues)
|
||||
.default_val(MAX_DETAIL_LEVEL)
|
||||
.importance(7)
|
||||
@@ -145,6 +146,7 @@ const auto NebulaDetailOption __UNUSED = options::OptionBuilder<int>("Graphics.N
|
||||
Detail.nebula_detail = val;
|
||||
return true;
|
||||
})
|
||||
.flags({options::OptionFlags::RetailBuiltinOption})
|
||||
.finish();
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
@@ -166,7 +168,7 @@ void neb2_get_eye_orient(matrix *eye_matrix);
|
||||
|
||||
static poof_info* get_nebula_poof_pointer(char* nebula_name)
|
||||
{
|
||||
for (int i = 0; i < (int)Poof_info.size(); i++) {
|
||||
for (size_t i = 0; i < Poof_info.size(); i++) {
|
||||
if (!stricmp(nebula_name, Poof_info[i].name)) {
|
||||
return &Poof_info[i];
|
||||
}
|
||||
@@ -224,11 +226,7 @@ void parse_nebula_table(const char* filename)
|
||||
|
||||
generic_anim_init(&pooft.bitmap, name);
|
||||
|
||||
if (Poof_info.size() < MAX_NEB2_POOFS) {
|
||||
Poof_info.push_back(pooft);
|
||||
} else {
|
||||
Warning(LOCATION, "More than 32 poofs are defined! Skipping poof %s\n", pooft.name);
|
||||
}
|
||||
Poof_info.push_back(pooft);
|
||||
} else if (optional_string("$Name:")) { // new style
|
||||
stuff_string(pooft.name, F_NAME, NAME_LENGTH);
|
||||
|
||||
@@ -257,17 +255,8 @@ void parse_nebula_table(const char* filename)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Check if we're at max poofs. If so, then log and continue.
|
||||
if (Poof_info.size() < MAX_NEB2_POOFS) {
|
||||
Poof_info.push_back(pooft);
|
||||
poofp = &Poof_info[Poof_info.size() - 1];
|
||||
} else {
|
||||
Warning(LOCATION, "More than 32 poofs are defined! Skipping poof %s\n", pooft.name);
|
||||
if (!skip_to_start_of_string_either("$Name:", "#end")) {
|
||||
error_display(1, "Missing [#end] or [$Name] after nebula poof %s", pooft.name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Poof_info.push_back(pooft);
|
||||
poofp = &Poof_info[Poof_info.size() - 1];
|
||||
}
|
||||
|
||||
if (poof_new) {
|
||||
@@ -322,9 +311,6 @@ void parse_nebula_table(const char* filename)
|
||||
poofp->alpha = ::util::parseUniformRange<float>(0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebula poofs (%d)!\nSkipping %s.", (int)MAX_NEB2_POOFS, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const parse::ParseException& e)
|
||||
@@ -337,29 +323,35 @@ void parse_nebula_table(const char* filename)
|
||||
// initialize neb2 stuff at game startup
|
||||
void neb2_init()
|
||||
{
|
||||
|
||||
// first parse the default table
|
||||
parse_nebula_table("nebula.tbl");
|
||||
|
||||
// parse any modular tables
|
||||
parse_modular_table("*-neb.tbm", parse_nebula_table);
|
||||
|
||||
// align Poof_accum with Poof_info
|
||||
Poof_accum.resize(Poof_info.size());
|
||||
|
||||
// set up bit string
|
||||
Neb2_poof_flags.reset(new ubyte[calculate_num_bytes(Poof_info.size())]);
|
||||
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
|
||||
}
|
||||
|
||||
// set the bits for poofs from a list of poof names
|
||||
void neb2_set_poof_bits(const SCP_vector<SCP_string>& list)
|
||||
{
|
||||
Neb2_poof_flags = 0; //Make absolutely sure flags are zero'd before we start adding to it-Mjn
|
||||
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size()); //Make absolutely sure flags are zero'd before we start adding to it-Mjn
|
||||
for (const SCP_string& thisPoof : list) {
|
||||
for (int i = 0; i < (int)Poof_info.size(); i++) {
|
||||
for (size_t i = 0; i < Poof_info.size(); i++) {
|
||||
if (lcase_equal(Poof_info[i].name, thisPoof)) {
|
||||
Neb2_poof_flags |= (1 << i);
|
||||
set_bit(Neb2_poof_flags.get(), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool poof_is_used(size_t idx) {
|
||||
return (Neb2_poof_flags & (1 << idx)) != 0;
|
||||
return get_bit(Neb2_poof_flags.get(), idx) != 0;
|
||||
}
|
||||
|
||||
void neb2_get_fog_color(ubyte *r, ubyte *g, ubyte *b)
|
||||
@@ -376,7 +368,7 @@ void neb2_pre_level_init()
|
||||
Neb2_fog_far_mult = 1.0f;
|
||||
|
||||
strcpy_s(Neb2_texture_name, "");
|
||||
Neb2_poof_flags = 0;
|
||||
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
|
||||
|
||||
strcpy_s(Mission_parse_storm_name, "none");
|
||||
}
|
||||
@@ -389,7 +381,7 @@ void neb2_level_init()
|
||||
float nNf_near, nNf_density;
|
||||
|
||||
void neb2_poof_setup() {
|
||||
if (!Neb2_poof_flags)
|
||||
if (!any_bits_set(Neb2_poof_flags.get(), Poof_info.size()))
|
||||
return;
|
||||
|
||||
// make the total density of poofs be the average of all poofs, and each poofs density is its relative proportion compared to others
|
||||
@@ -515,17 +507,6 @@ void neb2_post_level_init(bool fog_color_override)
|
||||
Neb2_awacs = -1.0f;
|
||||
}
|
||||
|
||||
// truncate the poof flags down to the poofs we have
|
||||
if (Poof_info.size() < MAX_NEB2_POOFS) {
|
||||
int available_poofs_mask = (1 << Poof_info.size()) - 1;
|
||||
|
||||
// check for negative here too, because if we're not at max, 32, then we're gauranteed not to have the sign bit
|
||||
if (Neb2_poof_flags > available_poofs_mask || Neb2_poof_flags < 0)
|
||||
Warning(LOCATION, "One or more invalid nebula poofs detected!");
|
||||
|
||||
Neb2_poof_flags = Neb2_poof_flags & available_poofs_mask;
|
||||
}
|
||||
|
||||
// set the mission fog near dist and density
|
||||
float fog_far;
|
||||
neb2_get_adjusted_fog_values(&nNf_near, &fog_far, &nNf_density, nullptr);
|
||||
@@ -789,7 +770,7 @@ void neb2_calc_poof_fades() {
|
||||
if (pinfo->fade_in) {
|
||||
// Make sure to enable this poof type if we're fading it in
|
||||
if (pinfo->fade_multiplier < 0) {
|
||||
Neb2_poof_flags |= (1 << i);
|
||||
set_bit(Neb2_poof_flags.get(), i);
|
||||
neb2_poof_setup();
|
||||
}
|
||||
pinfo->fade_multiplier = 0.0f + ((float)elapsedTime / pinfo->fade_duration);
|
||||
@@ -802,7 +783,7 @@ void neb2_calc_poof_fades() {
|
||||
|
||||
// turn off any faded out poof types
|
||||
if (!pinfo->fade_in) {
|
||||
Neb2_poof_flags &= ~(1 << i);
|
||||
clear_bit(Neb2_poof_flags.get(), i);
|
||||
neb2_poof_setup();
|
||||
}
|
||||
|
||||
@@ -822,8 +803,8 @@ void neb2_calc_poof_fades() {
|
||||
|
||||
void neb2_toggle_poof(int poof_idx, bool enabling) {
|
||||
|
||||
if (enabling) Neb2_poof_flags |= (1 << poof_idx);
|
||||
else Neb2_poof_flags &= ~(1 << poof_idx);
|
||||
if (enabling) set_bit(Neb2_poof_flags.get(), poof_idx);
|
||||
else clear_bit(Neb2_poof_flags.get(), poof_idx);
|
||||
|
||||
Neb2_poofs.clear();
|
||||
|
||||
@@ -1243,10 +1224,10 @@ DCF(neb2_select, "Enables/disables a poof bitmap")
|
||||
|
||||
dc_stuff_int(&bmap);
|
||||
|
||||
if ( (bmap >= 0) && (bmap < (int)Poof_info.size()) ) {
|
||||
if ( (bmap >= 0) && (bmap < static_cast<int>(Poof_info.size())) ) {
|
||||
dc_stuff_boolean(&val_b);
|
||||
|
||||
val_b ? (Neb2_poof_flags |= (1<<bmap)) : (Neb2_poof_flags &= ~(1<<bmap));
|
||||
val_b ? (set_bit(Neb2_poof_flags.get(), bmap)) : (clear_bit(Neb2_poof_flags.get(), bmap));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -55,8 +55,7 @@ extern float Neb2_fog_visibility_shockwave;
|
||||
extern float Neb2_fog_visibility_fireball_const;
|
||||
extern float Neb2_fog_visibility_fireball_scaled_factor;
|
||||
|
||||
extern int Neb2_poof_flags;
|
||||
const size_t MAX_NEB2_POOFS = 32;
|
||||
extern std::unique_ptr<ubyte> Neb2_poof_flags;
|
||||
|
||||
// pof texture filenames
|
||||
extern SCP_vector<SCP_string> Neb2_bitmap_filenames;
|
||||
|
||||
@@ -1305,7 +1305,7 @@ char *GetTrackerIdByUser(char *nickname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *GetChannelByUser(char *nickname)
|
||||
char *GetChannelByUser(const char *nickname)
|
||||
{
|
||||
char szWhoisCmd[100];
|
||||
|
||||
@@ -1332,5 +1332,5 @@ char *GetChannelByUser(char *nickname)
|
||||
SendChatString(szWhoisCmd,1);
|
||||
GettingUserChannel = 1;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -50,6 +50,9 @@ typedef struct _Chat_command {
|
||||
_Chat_command *next;
|
||||
} Chat_command;
|
||||
|
||||
// For returning a player's channel when searching by player name
|
||||
extern char User_req_channel[100];
|
||||
|
||||
//Prototypes
|
||||
void ChatInit(void);
|
||||
int ConnectToChatServer(char *serveraddr, char *nickname, char *trackerid);
|
||||
@@ -61,7 +64,7 @@ char *GetChatUserList();
|
||||
int SetNewChatChannel(char *channel);
|
||||
char *GetChannelList(void);
|
||||
char *GetTrackerIdByUser(char *nickname);
|
||||
char *GetChannelByUser(char *nickname);
|
||||
char *GetChannelByUser(const char *nickname);
|
||||
|
||||
char *ChatGetString(void);
|
||||
const char *GetWordNum(int num, const char *l_String);
|
||||
|
||||
@@ -119,8 +119,7 @@ int Multi_button_info_ok = 0; // flag saying it is ok to apply critical
|
||||
int Multi_button_info_id = 0; // identifier of the stored button info to be applying
|
||||
|
||||
// misc data
|
||||
active_game* Active_game_head; // linked list of active games displayed on Join screen
|
||||
int Active_game_count; // for interface screens as well
|
||||
SCP_list<active_game> Active_games; // list of active games displayed on the Join screen
|
||||
CFILE* Multi_chat_stream; // for streaming multiplayer chat strings to a file
|
||||
int Multi_connection_speed; // connection speed of this machine.
|
||||
int Multi_num_players_at_start = 0; // the # of players present (kept track of only on the server) at the very start of the mission
|
||||
@@ -131,9 +130,9 @@ server_item* Game_server_head; // list of permanent game servers to be qu
|
||||
|
||||
// timestamp data
|
||||
int Netgame_send_time = -1; // timestamp used to send netgame info to players before misison starts
|
||||
int State_send_time = -1; // timestamp used to send state information to the host before a mission starts
|
||||
time_t State_send_time = -1; // timestamp used to send state information to the host before a mission starts
|
||||
int Gameinfo_send_time = -1; // timestamp used by master to send game information to clients
|
||||
int Next_ping_time = -1; // when we should next ping all
|
||||
time_t Next_ping_time = -1; // when we should next ping all
|
||||
int Multi_server_check_count = 0; // var to keep track of reentrancy when checking server status
|
||||
int Next_bytes_time = -1; // bytes sent
|
||||
|
||||
@@ -249,7 +248,7 @@ void multi_vars_init()
|
||||
Multi_current_file_checksum = 0;
|
||||
Multi_current_file_length = -1;
|
||||
|
||||
Active_game_head = NULL;
|
||||
Active_games.clear();
|
||||
Game_server_head = NULL;
|
||||
|
||||
// only the server should ever care about this
|
||||
@@ -1199,7 +1198,7 @@ void multi_do_frame()
|
||||
|
||||
// ping everyone
|
||||
multi_ping_send_all();
|
||||
Next_ping_time = (int) time(NULL);
|
||||
Next_ping_time = time(NULL);
|
||||
}
|
||||
|
||||
// if I am the master, and we are not yet actually playing the mission, send off netgame
|
||||
@@ -1219,7 +1218,7 @@ void multi_do_frame()
|
||||
send_netplayer_update_packet();
|
||||
}
|
||||
|
||||
State_send_time = (int) time(NULL);
|
||||
State_send_time = time(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1404,7 +1403,7 @@ void multi_pause_do_frame()
|
||||
if((Next_ping_time < 0) || ((time(NULL) - Next_ping_time) > PING_SEND_TIME) ){
|
||||
multi_ping_send_all();
|
||||
|
||||
Next_ping_time = (int) time(NULL);
|
||||
Next_ping_time = time(NULL);
|
||||
}
|
||||
|
||||
// periodically send a client update packet to all clients
|
||||
|
||||
@@ -414,7 +414,7 @@ typedef struct net_player_server_info {
|
||||
UI_TIMESTAMP kick_timestamp; // timestamp with which we'll disconnect a player if he hasn't reponded to a kick packet
|
||||
int kick_reason; // reason he was kicked
|
||||
UI_TIMESTAMP voice_token_timestamp; // timestamp set when a player loses a token (so we can prevent him from getting it again too quickly)
|
||||
int reliable_connect_time; // after sending an accept packet, wait for this long for the guy to connect on the reliable socket
|
||||
time_t reliable_connect_time; // after sending an accept packet, wait for this long for the guy to connect on the reliable socket
|
||||
|
||||
// weapon select/linking information (maintained on the server and passed on respawn to all clients)
|
||||
char cur_primary_bank; // currently selected primary bank
|
||||
@@ -465,7 +465,7 @@ typedef struct net_player_server_info {
|
||||
num_last_buttons = 0;
|
||||
xfer_handle = -1;
|
||||
kick_reason = 0;
|
||||
reliable_connect_time = 0;
|
||||
reliable_connect_time = -1;
|
||||
|
||||
cur_primary_bank = 0;
|
||||
cur_secondary_bank = 0;
|
||||
@@ -643,7 +643,6 @@ typedef struct netgame_info {
|
||||
#define AG_FLAG_STATE_MASK (AG_FLAG_FORMING|AG_FLAG_BRIEFING|AG_FLAG_DEBRIEF|AG_FLAG_PAUSE|AG_FLAG_IN_MISSION)
|
||||
|
||||
typedef struct active_game {
|
||||
active_game *next, *prev; // next and previous elements in the list
|
||||
UI_TIMESTAMP heard_from_timer; // when we last heard from the game
|
||||
|
||||
char name[MAX_GAMENAME_LEN+1];
|
||||
@@ -656,8 +655,6 @@ typedef struct active_game {
|
||||
ping_struct ping; // ping time to the server
|
||||
|
||||
void init() {
|
||||
next = nullptr;
|
||||
prev = nullptr;
|
||||
num_players = 0;
|
||||
flags = 0;
|
||||
version = 0;
|
||||
@@ -890,8 +887,7 @@ extern int Multi_button_info_id; // identifier of the stored button inf
|
||||
#define HEADER_LENGTH 1 // 1 byte (packet type)
|
||||
|
||||
// misc data
|
||||
extern active_game* Active_game_head; // linked list of active games displayed on Join screen
|
||||
extern int Active_game_count; // for interface screens as well
|
||||
extern SCP_list<active_game> Active_games; // list of active games displayed on the Join screen
|
||||
extern CFILE* Multi_chat_stream; // for streaming multiplayer chat strings to a file
|
||||
extern int Multi_num_players_at_start; // the # of players present (kept track of only on the server) at the very start of the mission
|
||||
extern short Multi_id_num; // for assigning player id #'s
|
||||
|
||||
@@ -1028,13 +1028,10 @@ void process_ingame_ships_packet( ubyte *data, header *hinfo )
|
||||
GET_INT(Wings[wing_data].current_wave);
|
||||
}
|
||||
|
||||
// lookup ship in the original ships array
|
||||
p_objp = mission_parse_get_parse_object(ship_name);
|
||||
if(p_objp == NULL){
|
||||
// if this ship is part of wing not on its current wave, look for its "original" by subtracting out wave #
|
||||
p_objp = mission_parse_get_arrival_ship(ship_name);
|
||||
}
|
||||
if(p_objp == NULL){
|
||||
// lookup ship in the registry
|
||||
auto entry = ship_registry_get(ship_name);
|
||||
p_objp = entry ? entry->p_objp_or_null() : nullptr;
|
||||
if (p_objp == nullptr) {
|
||||
mprintf(("ABORTING in-game join since FSO couldn't find ship %s in either arrival list or in mission!\n", ship_name));
|
||||
multi_quit_game(PROMPT_NONE, MULTI_END_NOTIFY_NONE, MULTI_END_ERROR_INGAME_BOGUS);
|
||||
return;
|
||||
|
||||
Loaded 100 of 277 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user