Compare commits

..
Author SHA1 Message Date
asarium 1111dcf0a8 Add system for reading flags from stdin
This adds support for reading flags from the standard input stream
instead of from the command line. This allows more complex formats to be
used such as JSON which is implemented in this first version. This can
be used for implementing much more sophisticated ways of expressing
complex data structures such as the mod command line.
2019-06-07 18:31:33 +02:00
85 changed files with 2348 additions and 20446 deletions

No files matched your search

+11 -1
View File
@@ -43,7 +43,7 @@ env:
deploy:
- provider: releases
api_key:
secure: "q619+eQTe7lv8UVphK4OIzU8Jw84KBbVkuprN2sWIubRcV3IbZr2+WahJoUMt+nyhiy3YjDYtstO2ZgkxupwnZgwGUBVIiD1c4SPuyy+HTjNMOtiVsEUHT2hf+xPAemWpTlK5HcwhMmHAOh6rt6dEj57QOg0gcmGiwD/tCbEriA="
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
skip_cleanup: true
file_glob: true
file: "/tmp/builds/*"
@@ -150,6 +150,16 @@ matrix:
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
# As long as Windows is still experimental on Travis CI, allow failures
allow_failures:
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141_xp CMAKE_GENERATOR="Visual Studio 15 2017"
- os: windows
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
fast_finish: true
before_install:
+1 -1
View File
@@ -24,7 +24,7 @@ test_script:
deploy:
- provider: GitHub
auth_token:
secure: h55Scpy+3vmo1Yb7WlSIGA4d9DRnsbzUYc2LYsQdByQHZHbqrqjBpicH0D2FFLEO
secure: 3kV4efHXwRnfXzmJPRAOs8D7+MhwXUXYeayI/P5y114L09kJa6b6L70beXdW7yYr
on:
ReleaseBuild: true # deploy on release push only
+10 -10
View File
@@ -10,8 +10,8 @@ include(CheckSymbolExists)
include(CheckCXXSymbolExists)
include(CheckTypeSize)
CHECK_INCLUDE_FILE("execinfo.h" SCP_HAVE_EXECINFO_H)
CHECK_INCLUDE_FILE_CXX("cxxabi.h" SCP_HAVE_CXXAPI_H)
CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFO_H)
CHECK_INCLUDE_FILE_CXX("cxxabi.h" HAVE_CXXAPI_H)
CHECK_TYPE_SIZE("max_align_t" MAX_ALIGN_T)
@@ -31,18 +31,18 @@ CHECK_TYPE_SIZE("U'b'" UNICODE_CHAR_LITERAL LANGUAGE CXX)
set(CMAKE_REQUIRED_FLAGS)
CHECK_FUNCTION_EXISTS(strcasecmp SCP_HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(strncasecmp SCP_HAVE_STRNCASECMP)
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP)
CHECK_FUNCTION_EXISTS(_stricmp SCP_HAVE__STRICMP)
CHECK_FUNCTION_EXISTS(_strnicmp SCP_HAVE__STRNICMP)
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
CHECK_FUNCTION_EXISTS(_strnicmp HAVE__STRNICMP)
CHECK_FUNCTION_EXISTS(strlwr SCP_HAVE_STRLWR)
CHECK_FUNCTION_EXISTS(strlwr HAVE_STRLWR)
CHECK_INCLUDE_FILE("strings.h" SCP_HAVE_STRINGS_H)
CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
check_symbol_exists(snprintf "stdio.h" SCP_HAVE_SNPRINTF)
check_symbol_exists(_snprintf "stdio.h" SCP_HAVE__SNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
set(PLATFORM_CHECK_HEADER "${GENERATED_SOURCE_DIR}/platformChecks.h")
CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/platformChecks.h.in "${PLATFORM_CHECK_HEADER}")
+14 -14
View File
@@ -3,29 +3,29 @@
#define __PLATFORM_CHECKS_H__
#pragma once
#cmakedefine SCP_HAVE_EXECINFO_H
#cmakedefine SCP_HAVE_CXXAPI_H
#cmakedefine SCP_HAVE_MAX_ALIGN_T
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
#cmakedefine HAVE_EXECINFO_H
#cmakedefine HAVE_CXXAPI_H
#cmakedefine HAVE_MAX_ALIGN_T
#cmakedefine HAVE_STD_MAX_ALIGN_T
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE
#cmakedefine SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
#cmakedefine01 IS_64BIT
#cmakedefine01 SCP_HAVE_STRCASECMP
#cmakedefine01 SCP_HAVE_STRNCASECMP
#cmakedefine01 SCP_HAVE__STRICMP
#cmakedefine01 SCP_HAVE__STRNICMP
#cmakedefine01 HAVE_STRCASECMP
#cmakedefine01 HAVE_STRNCASECMP
#cmakedefine01 HAVE__STRICMP
#cmakedefine01 HAVE__STRNICMP
#cmakedefine01 SCP_HAVE_STRLWR
#cmakedefine01 HAVE_STRLWR
#cmakedefine01 SCP_HAVE_STRINGS_H
#cmakedefine01 HAVE_STRINGS_H
#cmakedefine01 HAVE_CHAR32_T
#cmakedefine01 HAVE_UNICODE_CHAR_LITERAL
#cmakedefine01 SCP_HAVE_SNPRINTF
#cmakedefine01 SCP_HAVE__SNPRINTF
#cmakedefine01 HAVE_SNPRINTF
#cmakedefine01 HAVE__SNPRINTF
#endif // __PLATFORM_CHECKS_H__
+64 -64
View File
@@ -1314,9 +1314,7 @@ ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, int pare
}
if ( aip == Player_ai ) {
if (aip->last_subsys_target != aip->targeted_subsys) {
hud_lock_reset(0.5f);
}
hud_lock_reset(0.5f);
}
} else {
@@ -5320,7 +5318,9 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
{
if (swp->current_primary_bank >= 0)
{
int bank_index = swp->current_primary_bank;
int bank_index;
bank_index = swp->current_primary_bank;
if (Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Puncture])
{
@@ -5329,9 +5329,11 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
}
for (int i=0; i<swp->num_primary_banks; i++)
{
int weapon_info_index = swp->primary_bank_weapons[i];
int weapon_info_index;
if (weapon_info_index >= 0)
weapon_info_index = swp->primary_bank_weapons[i];
if (weapon_info_index > -1)
{
if (Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Puncture])
{
@@ -5342,51 +5344,44 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
}
}
auto other_is_ship = (other_objp->type == OBJ_SHIP);
float enemy_remaining_shield = get_shield_pct(other_objp);
if ( other_is_ship && (Ship_info[Ships[other_objp->instance].ship_info_index].is_big_or_huge() ) )
if ( (other_objp->type == OBJ_SHIP) && (Ship_info[Ships[other_objp->instance].ship_info_index].is_big_or_huge() ) )
{
//Check if we have a capital+ weapon on board
for (int i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if (wip->wi_flags[Weapon::Info_Flags::Capital_plus])
if (Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus])
{
// handle shielded big/huge ships (non FS-verse)
// only pick capital+ if the target has no shields; or the weapon is an ok shield-breaker anyway
if (enemy_remaining_shield <= 0.05f || (wip->shield_factor * 1.33f > wip->armor_factor))
{
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s (capital+) vs target %s\n", Framecount, Ships[objp->instance].ship_name, wip->name, Ships[other_objp->instance].ship_name));
return i;
}
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s (capital+) vs target %s\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i]].name, Ships[other_objp->instance].ship_name));
return i;
}
}
}
}
float enemy_remaining_shield = get_shield_pct(other_objp);
// Is the target shielded by say only 5%?
if (enemy_remaining_shield <= 0.05f)
{
// Then it is safe to start using a heavy hull damage weapon such as the maxim
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest hull * damage / fire delay factor
for (int i = 0; i < swp->num_primary_banks; i++)
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((((wip->armor_factor) * (wip->damage)) / wip->fire_wait) > i_hullfactor_prev)
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
{
// This weapon is the new candidate
i_hullfactor_prev = ( ((wip->armor_factor) * (wip->damage)) / wip->fire_wait );
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].armor_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
@@ -5397,7 +5392,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (no shields) vs target %s\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name, (other_is_ship ? Ships[other_objp->instance].ship_name : "non-ship") ));
nprintf(("AI", "%i: Ship %s selecting weapon %s (no shields) vs target %s\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name, (other_objp->type == OBJ_SHIP ? Ships[other_objp->instance].ship_name : "non-ship") ));
return i_hullfactor_prev_bank; // Return
}
@@ -5406,23 +5401,28 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
{
if (swp->current_primary_bank >= 0)
{
auto wip = &Weapon_info[swp->primary_bank_weapons[swp->current_primary_bank]];
int bank_index;
if ((wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]))
bank_index = swp->current_primary_bank;
if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags[Weapon::Info_Flags::Capital_plus]))
{
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, shipp->ship_name, wip->name));
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[bank_index]].name));
return swp->current_primary_bank;
}
}
for (int i=0; i<swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0)
int weapon_info_index;
weapon_info_index = swp->primary_bank_weapons[i];
if (weapon_info_index > -1)
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((wip->wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]))
if ((Weapon_info[weapon_info_index].wi_flags[Weapon::Info_Flags::Pierce_shields]) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]))
{
swp->current_primary_bank = i;
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, shipp->ship_name, wip->name));
nprintf(("AI", "%i: Ship %s selecting weapon %s (>10%% shields)\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i]].name));
return i;
}
}
@@ -5432,63 +5432,63 @@ int ai_select_primary_weapon(object *objp, object *other_objp, Weapon::Info_Flag
// Is the target shielded by less then 50%?
if (enemy_remaining_shield <= 0.50f)
{
// Should be using best balanced shield/hull gun
float i_balancedfactor_prev = 0; // Previous weapon bank "balanced" factor (this is the safe way to do it)
int i_balancedfactor_prev_bank = -1; // Bank which gave us this "balanced" factor
// Should be using best balanced shield gun
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest average hull and shield * damage / fire delay factor
for (int i = 0; i < swp->num_primary_banks; i++)
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((((wip->armor_factor + wip->shield_factor) * wip->damage) / wip->fire_wait) > i_balancedfactor_prev)
if ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
{
// This weapon is the new candidate
i_balancedfactor_prev = ((((wip->armor_factor + wip->shield_factor) * wip->damage) / wip->fire_wait));
i_balancedfactor_prev_bank = i;
i_hullfactor_prev = ((((Weapon_info[swp->primary_bank_weapons[i]].armor_factor + Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait));
i_hullfactor_prev_bank = i;
}
}
}
}
if (i_balancedfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
if (i_hullfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
{
i_balancedfactor_prev_bank = 0; // Just switch to the first one
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_balancedfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (<50%% shields)\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_balancedfactor_prev_bank]].name));
return i_balancedfactor_prev_bank; // Return
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (<50%% shields)\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name));
return i_hullfactor_prev_bank; // Return
}
else
{
// Should be using best shield destroying gun
float i_shieldfactor_prev = 0; // Previous weapon bank shield factor (this is the safe way to do it)
int i_shieldfactor_prev_bank = -1; // Bank which gave us this shield factor
int i;
float i_hullfactor_prev = 0; // Previous weapon bank hull factor (this is the safe way to do it)
int i_hullfactor_prev_bank = -1; // Bank which gave us this hull factor
// Find the weapon with the highest average hull and shield * damage / fire delay factor
for (int i = 0; i < swp->num_primary_banks; i++)
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) // Make sure there is a weapon in the bank
if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank
{
auto wip = &Weapon_info[swp->primary_bank_weapons[i]];
if ((((wip->shield_factor) * wip->damage) / wip->fire_wait) > i_shieldfactor_prev)
if ((((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * Weapon_info[swp->primary_bank_weapons[i]].damage) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait) > i_hullfactor_prev)
{
if ( !(wip->wi_flags[Weapon::Info_Flags::Capital_plus]) )
if ( !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags[Weapon::Info_Flags::Capital_plus]) )
{
// This weapon is the new candidate
i_shieldfactor_prev = ( ((wip->shield_factor) * (wip->damage)) / wip->fire_wait );
i_shieldfactor_prev_bank = i;
i_hullfactor_prev = ( ((Weapon_info[swp->primary_bank_weapons[i]].shield_factor) * (Weapon_info[swp->primary_bank_weapons[i]].damage)) / Weapon_info[swp->primary_bank_weapons[i]].fire_wait );
i_hullfactor_prev_bank = i;
}
}
}
}
if (i_shieldfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
if (i_hullfactor_prev_bank == -1) // In the unlikely instance we don't find at least 1 candidate weapon
{
i_shieldfactor_prev_bank = 0; // Just switch to the first one
i_hullfactor_prev_bank = 0; // Just switch to the first one
}
swp->current_primary_bank = i_shieldfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (>50%% shields)\n", Framecount, shipp->ship_name, Weapon_info[swp->primary_bank_weapons[i_shieldfactor_prev_bank]].name));
return i_shieldfactor_prev_bank; // Return
swp->current_primary_bank = i_hullfactor_prev_bank; // Select the best weapon
nprintf(("AI", "%i: Ship %s selecting weapon %s (>50%% shields)\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i_hullfactor_prev_bank]].name));
return i_hullfactor_prev_bank; // Return
}
}
+1 -1
View File
@@ -1626,7 +1626,7 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
status = SHIP_STATUS_ARRIVED;
}
// goal ship is still on the arrival list
else if ( mission_check_ship_yet_to_arrive(aigp->target_name) )
else if ( mission_parse_get_arrival_ship(aigp->target_name) )
{
status = SHIP_STATUS_NOT_ARRIVED;
}
+3 -3
View File
@@ -856,11 +856,11 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
// flags for weapon types
if (beam_flag)
eeo.eeo_flags |= EEOF_BEAM;
if (flak_flag)
else if (flak_flag)
eeo.eeo_flags |= EEOF_FLAK;
if (laser_flag)
else if (laser_flag)
eeo.eeo_flags |= EEOF_LASER;
if (missile_flag)
else if (missile_flag)
eeo.eeo_flags |= EEOF_MISSILE;
eeo.enemy_team_mask = enemy_team_mask;
+2 -68
View File
@@ -38,9 +38,6 @@
#include <limits>
char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
// During cfile_init, verify that Pathtypes[n].index == n for each item
// Each path must have a valid parent that can be tracable all the way back to the root
// so that we can create directories when we need to.
@@ -103,8 +100,6 @@ static char Cfile_stack[CFILE_STACK_MAX][CFILE_ROOT_DIRECTORY_LEN];
std::array<CFILE, MAX_CFILE_BLOCKS> Cfile_block_list;
static const char *Cfile_cdrom_dir = NULL;
//
// Function prototypes for internally-called functions
//
@@ -147,47 +142,15 @@ void cfile_close()
#define MIN_NUM_PATH_COMPONENTS 3 /* Drive + directory + file */
#endif
/**
* @brief Determine if the given path is in the root directory
*
* @param exe_path Path to executable
*
* @return true if root directory, false if not
*/
static bool cfile_in_root_dir(const char *exe_path)
{
int new_token;
int token_count = 0;
const char *p = exe_path;
Assert(exe_path != NULL);
do {
new_token = 0;
while (*p == DIR_SEPARATOR_CHAR) {
p++;
}
while ((*p != '\0') && (*p != DIR_SEPARATOR_CHAR)) {
new_token = 1;
p++;
}
token_count += new_token;
} while (*p != '\0');
return (token_count < MIN_NUM_PATH_COMPONENTS);
}
/**
* @brief Initialize the cfile system. Called once at application start.
*
* @param exe_dir Path to a file (not a directory)
* @param cdrom_dir Path to a CD drive mount point (may be NULL)
*
* @return 0 On success
* @return 1 On error
*/
int cfile_init(const char *exe_dir, const char *cdrom_dir)
int cfile_init(const SCP_vector<cfile::ModRoot>& modRoots)
{
// initialize encryption
encrypt_init();
@@ -196,36 +159,8 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
return 0;
}
char buf[CFILE_ROOT_DIRECTORY_LEN];
strncpy(buf, exe_dir, CFILE_ROOT_DIRECTORY_LEN - 1);
buf[CFILE_ROOT_DIRECTORY_LEN - 1] = '\0';
// are we in a root directory?
if(cfile_in_root_dir(buf)){
os::dialogs::Message(os::dialogs::MESSAGEBOX_ERROR, "FreeSpace2/Fred2 cannot be run from a drive root directory!");
return 1;
}
// This needs to be set here because cf_build_secondary_filelist assumes it to be true
cfile_inited = 1;
/*
* Determine the executable's directory. Note that DIR_SEPARATOR_CHAR
* is guaranteed to be found in the string else cfile_in_root_dir()
* would have failed.
*/
char *p;
p = strrchr(buf, DIR_SEPARATOR_CHAR);
*p = '\0';
cfile_chdir(buf);
// set root directory
strcpy_s(Cfile_root_dir, buf);
strcpy_s(Cfile_user_dir, os_get_config_path().c_str());
// Initialize the block list with proper data
Cfile_block_list.fill({});
@@ -233,8 +168,7 @@ int cfile_init(const char *exe_dir, const char *cdrom_dir)
// 32 bit CRC table init
cf_chksum_long_init();
Cfile_cdrom_dir = cdrom_dir;
cf_build_secondary_filelist(Cfile_cdrom_dir);
cf_build_secondary_filelist(modRoots);
return 0;
}
+14 -3
View File
@@ -165,11 +165,22 @@ extern const char *Get_file_list_child;
// cfile directory. valid after cfile_init() returns successfully
#define CFILE_ROOT_DIRECTORY_LEN 256
extern char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN];
extern char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN];
namespace cfile {
enum class ModRootType { Unknown, Folder, Package };
enum class LocationType { Unknown, SecondaryMod, PrimaryMod, GameRoot };
struct ModRoot {
ModRootType type = ModRootType::Unknown;
SCP_string path;
LocationType location_type = LocationType::Unknown;
bool user_location = false;
};
} // namespace cfile
//================= LOW-LEVEL FUNCTIONS ==================
int cfile_init(const char *exe_dir, const char *cdrom_dir=NULL);
int cfile_init(const SCP_vector<cfile::ModRoot>& modRoots);
void cfile_close();
// add an extension to a filename if it doesn't already have it
+266
View File
@@ -0,0 +1,266 @@
#define _CFILE_INTERNAL
#include "cfilemod.h"
#include "cfile.h"
#include "cmdline/cmdline.h"
#include "osapi/osapi.h"
#include "cfilesystem.h"
#ifdef SCP_UNIX
#include <glob.h>
#include <sys/types.h>
#include <dirent.h>
#include <fnmatch.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#endif
namespace cfile {
namespace {
typedef struct cf_root_sort {
SCP_string path;
int cf_type;
} cf_root_sort;
// packfile sort function
bool cf_packfile_sort_func(const cf_root_sort& r1, const cf_root_sort& r2) {
// if the 2 directory types are the same, do a string compare
if (r1.cf_type == r2.cf_type) {
return (stricmp(r1.path.c_str(), r2.path.c_str()) < 0);
}
// otherwise return them in order of CF_TYPE_* precedence
return (r1.cf_type < r2.cf_type);
}
// Go through a root and look for pack files
void build_pack_list(SCP_vector<ModRoot>& mod_roots,
const SCP_string& search_path,
LocationType location_type,
bool user_location) {
char filespec[MAX_PATH_LEN];
// allocate a temporary array of temporary roots so we can easily sort them
SCP_vector<cf_root_sort> temp_roots_sort;
// now just setup all the root info
for (int i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
strcpy_s(filespec, search_path.c_str());
if (strlen(Pathtypes[i].path)) {
strcat_s(filespec, Pathtypes[i].path);
if (filespec[strlen(filespec) - 1] != DIR_SEPARATOR_CHAR)
strcat_s(filespec, DIR_SEPARATOR_STR);
}
#if defined _WIN32
strcat_s( filespec, "*.vp" );
intptr_t find_handle;
_finddata_t find;
find_handle = _findfirst( filespec, &find );
if (find_handle != -1) {
do {
// add the new item
if (!(find.attrib & _A_SUBDIR)) {
// get a temp pointer
rptr_sort = &temp_roots_sort[root_index++];
// fill in all the proper info
strcpy_s(rptr_sort->path, root->path);
if(strlen(Pathtypes[i].path)) {
strcat_s(rptr_sort->path, Pathtypes[i].path );
strcat_s(rptr_sort->path, DIR_SEPARATOR_STR);
}
strcat_s(rptr_sort->path, find.name );
rptr_sort->roottype = CF_ROOTTYPE_PACK;
rptr_sort->cf_type = i;
}
} while (!_findnext(find_handle, &find));
_findclose( find_handle );
}
#elif defined SCP_UNIX
strcat_s(filespec, "*.[vV][pP]");
glob_t globinfo;
memset(&globinfo, 0, sizeof(globinfo));
int status = glob(filespec, 0, NULL, &globinfo);
if (status == 0) {
for (uint j = 0; j < globinfo.gl_pathc; j++) {
// Determine if this is a regular file
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
stat(globinfo.gl_pathv[j], &statbuf);
if (S_ISREG(statbuf.st_mode)) {
cf_root_sort sort;
// fill in all the proper info
sort.path = globinfo.gl_pathv[j];
sort.cf_type = i;
temp_roots_sort.push_back(sort);
}
}
globfree(&globinfo);
}
#endif
}
// sort the roots
std::sort(temp_roots_sort.begin(), temp_roots_sort.end(), cf_packfile_sort_func);
// now insert them all into the real root list properly
for (const auto& pack_root : temp_roots_sort) {
ModRoot root;
root.type = ModRootType::Package;
root.path = pack_root.path;
root.user_location = user_location;
root.location_type = location_type;
mod_roots.push_back(root);
}
}
char normalize_directory_separator(char in) {
if (in == '/') {
return DIR_SEPARATOR_CHAR;
}
return in;
}
void
add_mod_roots(SCP_vector<ModRoot>& mod_roots, const char* mod_cmdline, const SCP_string& rootDirectory, bool user_location) {
if (mod_cmdline) {
bool primary = true;
for (const char* cur_pos = mod_cmdline; strlen(cur_pos) != 0; cur_pos += (strlen(cur_pos) + 1)) {
SCP_stringstream ss;
ss << rootDirectory;
if (rootDirectory.back() != DIR_SEPARATOR_CHAR) {
ss << DIR_SEPARATOR_CHAR;
}
ss << cur_pos << DIR_SEPARATOR_STR;
SCP_string rootPath = ss.str();
// normalize the path to the native path format
std::transform(rootPath.begin(), rootPath.end(), rootPath.begin(), normalize_directory_separator);
ModRoot root;
root.type = ModRootType::Folder;
root.path = rootPath;
root.user_location = user_location;
if (primary) {
root.location_type = LocationType::PrimaryMod;
} else {
root.location_type = LocationType::SecondaryMod;
}
mod_roots.push_back(root);
build_pack_list(mod_roots, rootPath, root.location_type, user_location);
primary = false;
}
}
}
}
SCP_vector<ModRoot> getModRootsFromModCmdline(const SCP_string& content_root, const char* mod_cmdline) {
SCP_vector<ModRoot> mod_roots;
if (os_is_legacy_mode()) {
// =========================================================================
#ifdef WIN32
// Nothing to do here, Windows uses the current directory as the base
#else
add_mod_roots(mod_roots, mod_cmdline, os_get_legacy_user_dir(), true);
ModRoot root;
root.type = ModRootType::Folder;
root.path = os_get_legacy_user_dir();
root.user_location = true;
root.location_type = LocationType::GameRoot;
// do we already have a slash? as in the case of a root directory install
if (root.path.back() != DIR_SEPARATOR_CHAR) {
root.path += DIR_SEPARATOR_STR; // put trailing backslash on for easier path construction
}
mod_roots.push_back(root);
// Next, check any VP files under the current directory.
build_pack_list(mod_roots, root.path, root.location_type, root.user_location);
#endif
// =========================================================================
} else if (!Cmdline_portable_mode) {
// =========================================================================
// now look for mods under the users HOME directory to use before system ones
add_mod_roots(mod_roots, mod_cmdline, os_get_config_path(), true);
// =========================================================================
// =========================================================================
// set users HOME directory as default for loading and saving files
ModRoot root;
root.type = ModRootType::Folder;
root.path = os_get_config_path();
root.user_location = true;
root.location_type = LocationType::GameRoot;
// do we already have a slash? as in the case of a root directory install
if (root.path.back() != DIR_SEPARATOR_CHAR) {
root.path += DIR_SEPARATOR_STR; // put trailing backslash on for easier path construction
}
mod_roots.push_back(root);
// Next, check any VP files under the current directory.
build_pack_list(mod_roots, root.path, root.location_type, root.user_location);
// =========================================================================
}
add_mod_roots(mod_roots, mod_cmdline, content_root, false);
ModRoot root;
root.type = ModRootType::Folder;
root.path = content_root;
root.user_location = false;
root.location_type = LocationType::GameRoot;
// do we already have a slash? as in the case of a root directory install
if (root.path.back() != DIR_SEPARATOR_CHAR) {
root.path += DIR_SEPARATOR_STR; // put trailing backslash on for easier path construction
}
mod_roots.push_back(root);
//======================================================
// Next, check any VP files under the current directory.
build_pack_list(mod_roots, root.path, root.location_type, root.user_location);
return mod_roots;
}
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include "globalincs/pstypes.h"
#include "cfile/cfile.h"
namespace cfile {
SCP_vector<ModRoot> getModRootsFromModCmdline(const SCP_string& content_root, const char* mod_cmdline);
}
+86 -352
View File
@@ -160,379 +160,113 @@ cf_root *cf_create_root()
return &Root_blocks[block]->roots[offset];
}
// return the # of packfiles which exist
int cf_get_packfile_count(cf_root *root)
static bool has_mod_location(const SCP_vector<cfile::ModRoot>& modRoots)
{
SCP_string filespec;
int i;
int packfile_count;
// count up how many packfiles we're gonna have
packfile_count = 0;
for (i=CF_TYPE_ROOT; i<CF_MAX_PATH_TYPES; i++ )
for (const auto& root : modRoots)
{
filespec = root->path;
if(strlen(Pathtypes[i].path))
if (root.location_type == cfile::LocationType::PrimaryMod)
{
filespec += Pathtypes[ i ].path;
if ( filespec[ filespec.length( ) - 1 ] != DIR_SEPARATOR_CHAR )
{
filespec += DIR_SEPARATOR_STR;
}
}
#if defined _WIN32
filespec += "*.vp";
intptr_t find_handle;
_finddata_t find;
find_handle = _findfirst( filespec.c_str( ), &find );
if (find_handle != -1) {
do {
if (!(find.attrib & _A_SUBDIR)) {
packfile_count++;
}
} while (!_findnext(find_handle, &find));
_findclose( find_handle );
}
#elif defined SCP_UNIX
filespec += "*.[vV][pP]";
glob_t globinfo;
memset(&globinfo, 0, sizeof(globinfo));
int status = glob(filespec.c_str( ), 0, NULL, &globinfo);
if (status == 0) {
for (unsigned int j = 0; j < globinfo.gl_pathc; j++) {
// Determine if this is a regular file
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
stat(globinfo.gl_pathv[j], &statbuf);
if (S_ISREG(statbuf.st_mode)) {
packfile_count++;
}
}
globfree(&globinfo);
}
#endif
}
return packfile_count;
}
// packfile sort function
bool cf_packfile_sort_func(const cf_root_sort &r1, const cf_root_sort &r2)
{
// if the 2 directory types are the same, do a string compare
if (r1.cf_type == r2.cf_type) {
return (stricmp(r1.path, r2.path) < 0);
}
// otherwise return them in order of CF_TYPE_* precedence
return (r1.cf_type < r2.cf_type);
}
// Go through a root and look for pack files
void cf_build_pack_list( cf_root *root )
{
char filespec[MAX_PATH_LEN];
int i;
cf_root_sort *temp_roots_sort, *rptr_sort;
int temp_root_count, root_index;
// determine how many packfiles there are
temp_root_count = cf_get_packfile_count(root);
if (temp_root_count <= 0)
return;
// allocate a temporary array of temporary roots so we can easily sort them
temp_roots_sort = (cf_root_sort*)vm_malloc(sizeof(cf_root_sort) * temp_root_count);
if (temp_roots_sort == NULL) {
Int3();
return;
}
// now just setup all the root info
root_index = 0;
for (i = CF_TYPE_ROOT; i < CF_MAX_PATH_TYPES; i++) {
strcpy_s( filespec, root->path );
if ( strlen(Pathtypes[i].path) ) {
strcat_s( filespec, Pathtypes[i].path );
if ( filespec[strlen(filespec)-1] != DIR_SEPARATOR_CHAR )
strcat_s( filespec, DIR_SEPARATOR_STR );
}
#if defined _WIN32
strcat_s( filespec, "*.vp" );
intptr_t find_handle;
_finddata_t find;
find_handle = _findfirst( filespec, &find );
if (find_handle != -1) {
do {
// add the new item
if (!(find.attrib & _A_SUBDIR)) {
Assert(root_index < temp_root_count);
// get a temp pointer
rptr_sort = &temp_roots_sort[root_index++];
// fill in all the proper info
strcpy_s(rptr_sort->path, root->path);
if(strlen(Pathtypes[i].path)) {
strcat_s(rptr_sort->path, Pathtypes[i].path );
strcat_s(rptr_sort->path, DIR_SEPARATOR_STR);
}
strcat_s(rptr_sort->path, find.name );
rptr_sort->roottype = CF_ROOTTYPE_PACK;
rptr_sort->cf_type = i;
}
} while (!_findnext(find_handle, &find));
_findclose( find_handle );
}
#elif defined SCP_UNIX
strcat_s( filespec, "*.[vV][pP]" );
glob_t globinfo;
memset(&globinfo, 0, sizeof(globinfo));
int status = glob(filespec, 0, NULL, &globinfo);
if (status == 0) {
for (uint j = 0; j < globinfo.gl_pathc; j++) {
// Determine if this is a regular file
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
stat(globinfo.gl_pathv[j], &statbuf);
if ( S_ISREG(statbuf.st_mode) ) {
Assert(root_index < temp_root_count);
// get a temp pointer
rptr_sort = &temp_roots_sort[root_index++];
// fill in all the proper info
strcpy_s(rptr_sort->path, globinfo.gl_pathv[j] );
rptr_sort->roottype = CF_ROOTTYPE_PACK;
rptr_sort->cf_type = i;
}
}
globfree(&globinfo);
}
#endif
}
// these should always be the same
Assert(root_index == temp_root_count);
// sort the roots
std::sort(temp_roots_sort, temp_roots_sort + temp_root_count, cf_packfile_sort_func);
// now insert them all into the real root list properly
for (i = 0; i < temp_root_count; i++) {
auto new_root = cf_create_root();
new_root->location_flags = root->location_flags;
strcpy_s( new_root->path, root->path );
#ifndef NDEBUG
uint chksum = 0;
cf_chksum_pack(temp_roots_sort[i].path, &chksum);
mprintf(("Found root pack '%s' with a checksum of 0x%08x\n", temp_roots_sort[i].path, chksum));
#endif
// mwa -- 4/2/98 put in the next 2 lines because the path name needs to be there
// to find the files.
strcpy_s(new_root->path, temp_roots_sort[i].path);
new_root->roottype = CF_ROOTTYPE_PACK;
}
// free up the temp list
vm_free(temp_roots_sort);
}
static char normalize_directory_separator(char in)
{
if (in == '/')
{
return DIR_SEPARATOR_CHAR;
}
return in;
}
static void cf_add_mod_roots(const char* rootDirectory, uint32_t basic_location)
{
if (Cmdline_mod)
{
bool primary = true;
for (const char* cur_pos=Cmdline_mod; strlen(cur_pos) != 0; cur_pos+= (strlen(cur_pos)+1))
{
SCP_stringstream ss;
ss << rootDirectory;
if (rootDirectory[strlen(rootDirectory) - 1] != DIR_SEPARATOR_CHAR)
{
ss << DIR_SEPARATOR_CHAR;
}
ss << cur_pos << DIR_SEPARATOR_STR;
SCP_string rootPath = ss.str();
if (rootPath.size() + 1 >= CF_MAX_PATHNAME_LENGTH) {
Error(LOCATION, "The length of mod directory path '%s' exceeds the maximum of %d!\n", rootPath.c_str(), CF_MAX_PATHNAME_LENGTH);
}
// normalize the path to the native path format
std::transform(rootPath.begin(), rootPath.end(), rootPath.begin(), normalize_directory_separator);
cf_root* root = cf_create_root();
strncpy(root->path, rootPath.c_str(), CF_MAX_PATHNAME_LENGTH-1);
if (primary) {
root->location_flags = basic_location | CF_LOCATION_TYPE_PRIMARY_MOD;
} else {
root->location_flags = basic_location | CF_LOCATION_TYPE_SECONDARY_MODS;
}
root->roottype = CF_ROOTTYPE_PATH;
cf_build_pack_list(root);
primary = false;
return true;
}
}
return false;
}
void cf_build_root_list(const char *cdrom_dir)
void cf_build_root_list(const SCP_vector<cfile::ModRoot>& modRoots)
{
Num_roots = 0;
Num_path_roots = 0;
cf_root *root = nullptr;
auto has_mod = has_mod_location(modRoots);
if (os_is_legacy_mode())
mprintf(("CFile root configuration:\n"));
// Go through the roots specified and convert them to the internal data structure
for (const auto& root : modRoots)
{
// =========================================================================
#ifdef WIN32
// Nothing to do here, Windows uses the current directory as the base
#else
cf_add_mod_roots(os_get_legacy_user_dir(), CF_LOCATION_ROOT_USER);
root = cf_create_root();
strncpy(root->path, os_get_legacy_user_dir(), CF_MAX_PATHNAME_LENGTH - 1);
root->location_flags |= CF_LOCATION_ROOT_USER | CF_LOCATION_TYPE_ROOT;
if (Cmdline_mod == nullptr || strlen(Cmdline_mod) <= 0) {
// If there are no mods then the root is the primary mod
root->location_flags |= CF_LOCATION_TYPE_PRIMARY_MOD;
if (root.path.size() >= CF_MAX_PATHNAME_LENGTH - 1)
{
Error(LOCATION, "Mod root path '%s' is longer than the maximum %d!", root.path.c_str(), CF_MAX_PATHNAME_LENGTH - 1);
return;
}
// do we already have a slash? as in the case of a root directory install
if ((strlen(root->path) < (CF_MAX_PATHNAME_LENGTH - 1)) && (root->path[strlen(root->path) - 1] != DIR_SEPARATOR_CHAR)) {
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
}
root->roottype = CF_ROOTTYPE_PATH;
auto cfile_root = cf_create_root();
memset(cfile_root, 0, sizeof(*cfile_root));
// Next, check any VP files under the current directory.
cf_build_pack_list(root);
strcpy_s(cfile_root->path, root.path.c_str());
if (root.user_location)
{
cfile_root->location_flags |= CF_LOCATION_ROOT_USER;
} else {
cfile_root->location_flags |= CF_LOCATION_ROOT_GAME;
}
if (root.location_type == cfile::LocationType::SecondaryMod)
{
cfile_root->location_flags |= CF_LOCATION_TYPE_SECONDARY_MODS;
} else if (root.location_type == cfile::LocationType::PrimaryMod)
{
cfile_root->location_flags |= CF_LOCATION_TYPE_PRIMARY_MOD;
} else if (root.location_type == cfile::LocationType::GameRoot)
{
cfile_root->location_flags |= CF_LOCATION_TYPE_ROOT;
if (!has_mod)
{
// If we do not have a mod then game roots are also primary mods
cfile_root->location_flags |= CF_LOCATION_TYPE_PRIMARY_MOD;
}
} else {
UNREACHABLE("Unknown root location type!");
}
switch (root.type)
{
case cfile::ModRootType::Folder:
cfile_root->roottype = CF_ROOTTYPE_PATH;
break;
case cfile::ModRootType::Package:
cfile_root->roottype = CF_ROOTTYPE_PACK;
break;
default:
UNREACHABLE("Unknown root type!");
break;
}
if (root.type == cfile::ModRootType::Folder)
{
size_t path_len = strlen(cfile_root->path);
// do we already have a slash? as in the case of a root directory install
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (cfile_root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
strcat_s(cfile_root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
}
}
#ifndef NDEBUG
switch (root.type)
{
case cfile::ModRootType::Folder:
mprintf((" Found root folder '%s'\n", root.path.c_str()));
break;
case cfile::ModRootType::Package: {
uint chksum = 0;
cf_chksum_pack(root.path.c_str(), &chksum);
mprintf((" Found root pack '%s' with a checksum of 0x%08x\n", root.path.c_str(), chksum));
break;
}
default:
UNREACHABLE("Unknown root type!");
break;
}
#endif
// =========================================================================
}
else if (!Cmdline_portable_mode)
{
// =========================================================================
// now look for mods under the users HOME directory to use before system ones
cf_add_mod_roots(Cfile_user_dir, CF_LOCATION_ROOT_USER);
// =========================================================================
// =========================================================================
// set users HOME directory as default for loading and saving files
root = cf_create_root();
strcpy_s(root->path, Cfile_user_dir);
root->location_flags |= CF_LOCATION_ROOT_USER | CF_LOCATION_TYPE_ROOT;
if (Cmdline_mod == nullptr || strlen(Cmdline_mod) <= 0) {
// If there are no mods then the root is the primary mod
root->location_flags |= CF_LOCATION_TYPE_PRIMARY_MOD;
}
// do we already have a slash? as in the case of a root directory install
if ((strlen(root->path) < (CF_MAX_PATHNAME_LENGTH - 1)) && (root->path[strlen(root->path) - 1] != DIR_SEPARATOR_CHAR)) {
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
}
root->roottype = CF_ROOTTYPE_PATH;
// Next, check any VP files under the current directory.
cf_build_pack_list(root);
// =========================================================================
}
char working_directory[CF_MAX_PATHNAME_LENGTH];
if ( !_getcwd(working_directory, CF_MAX_PATHNAME_LENGTH ) ) {
Error(LOCATION, "Can't get current working directory -- %d", errno );
}
cf_add_mod_roots(working_directory, CF_LOCATION_ROOT_GAME);
root = cf_create_root();
root->location_flags |= CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT;
if (Cmdline_mod == nullptr || strlen(Cmdline_mod) <= 0) {
// If there are no mods then the root is the primary mod
root->location_flags |= CF_LOCATION_TYPE_PRIMARY_MOD;
}
strcpy_s(root->path, working_directory);
size_t path_len = strlen(root->path);
// do we already have a slash? as in the case of a root directory install
if ( (path_len < (CF_MAX_PATHNAME_LENGTH-1)) && (root->path[path_len-1] != DIR_SEPARATOR_CHAR) ) {
strcat_s(root->path, DIR_SEPARATOR_STR); // put trailing backslash on for easier path construction
}
root->roottype = CF_ROOTTYPE_PATH;
//======================================================
// Next, check any VP files under the current directory.
cf_build_pack_list(root);
//======================================================
// Check the real CD if one...
if ( cdrom_dir && (strlen(cdrom_dir) < CF_MAX_PATHNAME_LENGTH) ) {
root = cf_create_root();
strcpy_s( root->path, cdrom_dir );
root->roottype = CF_ROOTTYPE_PATH;
//======================================================
// Next, check any VP files in the CD-ROM directory.
cf_build_pack_list(root);
}
// The final root is the in-memory root
root = cf_create_root();
auto root = cf_create_root();
root->location_flags = CF_LOCATION_ROOT_MEMORY | CF_LOCATION_TYPE_ROOT;
memset(root->path, 0, sizeof(root->path));
root->roottype = CF_ROOTTYPE_MEMORY;
}
// Given a lower case list of file extensions
@@ -923,7 +657,7 @@ void cf_build_file_list()
}
void cf_build_secondary_filelist(const char *cdrom_dir)
void cf_build_secondary_filelist(const SCP_vector<cfile::ModRoot>& modRoots)
{
int i;
@@ -944,7 +678,7 @@ void cf_build_secondary_filelist(const char *cdrom_dir)
mprintf(( "Building file index...\n" ));
// build the list of searchable roots
cf_build_root_list(cdrom_dir);
cf_build_root_list(modRoots);
// build the list of files themselves
cf_build_file_list();
+1 -1
View File
@@ -15,7 +15,7 @@
#include "cfile/cfile.h"
// Builds a list of all the files
void cf_build_secondary_filelist( const char *cdrom_path );
void cf_build_secondary_filelist(const SCP_vector<cfile::ModRoot>& modRoots);
void cf_free_secondary_filelist();
// Internal stuff
+328 -205
View File
@@ -34,6 +34,9 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
#include "cfile/cfile.h"
#include "cfile/cfilemod.h"
#ifdef SCP_UNIX
#include "osapi/osapi.h"
#include <dirent.h>
@@ -71,23 +74,36 @@ enum class flag_output_type {
Json_V1,
};
enum class flag_input_type {
Flags,
Stdin_Json_V1,
};
// variables
class cmdline_parm {
public:
cmdline_parm *next, *prev;
const char *name; // name of parameter, must start with '-' char
const char *help; // help text for this parameter
const bool stacks; // whether this arg stacks with each use or is replaced by newest use (should only be used for strings!!)
char *args; // string value for parameter arguments (NULL if no arguments)
int name_found; // true if parameter on command line, otherwise false
const int arg_type; // from enum cmdline_arg_type; used for help
cmdline_parm *next = nullptr, *prev = nullptr;
const char* name; // name of parameter, must start with '-' char
const char* help; // help text for this parameter
const bool stacks; // whether this arg stacks with each use or is replaced by newest use (should only be used for
// strings!!)
SCP_string args; // string value for parameter arguments (empty if no arguments)
bool name_found; // true if parameter on command line, otherwise false
const int arg_type; // from enum cmdline_arg_type; used for help
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false) noexcept;
cmdline_parm(const char* name, const char* help, const int arg_type, const bool stacks = false) noexcept;
~cmdline_parm() noexcept;
int found();
cmdline_parm(const cmdline_parm& other) = delete;
cmdline_parm& operator=(const cmdline_parm& other) = delete;
cmdline_parm(cmdline_parm&& other) = delete;
cmdline_parm& operator=(cmdline_parm&& other) = delete;
bool found();
int get_int();
float get_float();
char *str();
SCP_string str();
bool check_if_args_is_valid();
bool has_param();
};
@@ -152,7 +168,6 @@ typedef struct
} Flag;
// clang-format off
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
Flag exe_params[] =
{
@@ -168,7 +183,6 @@ Flag exe_params[] =
{ "-post_process", "Enable post processing", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-smaa", "Enable SMAA anti-aliasing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-smaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
@@ -250,7 +264,6 @@ Flag exe_params[] =
{ "-profile_frame_time","Profile engine subsystems", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_timings", },
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
};
// clang-format on
// forward declaration
const char * get_param_desc(const char *flag_name);
@@ -278,11 +291,11 @@ cmdline_parm mouse_coords("-coords", NULL, AT_NONE); // Cmdline_mouse_coords
cmdline_parm timeout("-timeout", "Multiplayer network timeout (secs)", AT_INT); // Cmdline_timeout
cmdline_parm bit32_arg("-32bit", "Deprecated", AT_NONE); // (only here for retail compatibility reasons, doesn't actually do anything)
char *Cmdline_connect_addr = NULL;
char *Cmdline_game_name = NULL;
char *Cmdline_game_password = NULL;
char *Cmdline_rank_above = NULL;
char *Cmdline_rank_below = NULL;
SCP_string Cmdline_connect_addr;
SCP_string Cmdline_game_name;
SCP_string Cmdline_game_password;
SCP_string Cmdline_rank_above;
SCP_string Cmdline_rank_below;
int Cmdline_cd_check = 1;
int Cmdline_client_dodamage = 0;
int Cmdline_closed_game = 0;
@@ -325,8 +338,6 @@ cmdline_parm postprocess_arg("-post_process", NULL, AT_NONE);
cmdline_parm bloom_intensity_arg("-bloom_intensity", "Set bloom intensity, requires -post_process", AT_INT);
cmdline_parm fxaa_arg("-fxaa", NULL, AT_NONE);
cmdline_parm fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-9), requires -post_process and -fxaa", AT_INT);
cmdline_parm smaa_arg("-smaa", nullptr, AT_NONE);
cmdline_parm smaa_preset_arg("-smaa_preset", "SMAA quality (0-9), requires -post_process and -smaa", AT_INT);
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
cmdline_parm fb_thrusters_arg("-fb_thrusters", NULL, AT_NONE);
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
@@ -397,7 +408,7 @@ int Cmdline_no_enhanced_sound = 0;
// MOD related
cmdline_parm mod_arg("-mod", "List of folders to overwrite/add-to the default data", AT_STRING, true); // Cmdline_mod -- DTP modsupport
char *Cmdline_mod = NULL; //DTP for mod argument
SCP_vector<cfile::ModRoot> Cmdline_mod; // DTP for mod argument
// Multiplayer/Network related
cmdline_parm almission_arg("-almission", "Autoload multiplayer mission", AT_STRING); // Cmdline_almission -- DTP for autoload Multi mission
@@ -407,15 +418,19 @@ cmdline_parm missioncrcspew_arg("-missioncrcs", NULL, AT_STRING); // Cmdline_sp
cmdline_parm tablecrcspew_arg("-tablecrcs", NULL, AT_STRING); // Cmdline_spew_table_crcs
cmdline_parm objupd_arg("-cap_object_update", "Multiplayer object update cap (0-3)", AT_INT);
char *Cmdline_almission = NULL; //DTP for autoload multi mission.
SCP_string Cmdline_almission; // DTP for autoload multi mission.
int Cmdline_ingamejoin = 0;
int Cmdline_mpnoreturn = 0;
char *Cmdline_spew_mission_crcs = NULL;
char *Cmdline_spew_table_crcs = NULL;
SCP_string Cmdline_spew_mission_crcs;
SCP_string Cmdline_spew_table_crcs;
int Cmdline_objupd = 3; // client object updates on LAN by default
// Launcher related options
cmdline_parm portable_mode("-portable_mode", NULL, AT_NONE);
cmdline_parm
stdin_flags("-stdin_flags",
"Tells FSO to read flags from stdin. Parameter is format if data supplied. Possible values: json_v1",
AT_STRING);
bool Cmdline_portable_mode = false;
@@ -447,7 +462,7 @@ int Cmdline_no_pbo = 0;
int Cmdline_ati_color_swap = 0;
int Cmdline_no_3d_sound = 0;
int Cmdline_drawelements = 0;
char* Cmdline_keyboard_layout = NULL;
SCP_string Cmdline_keyboard_layout;
bool Cmdline_gl_finish = false;
bool Cmdline_no_geo_sdr_effects = false;
bool Cmdline_set_cpu_affinity = false;
@@ -484,8 +499,7 @@ cmdline_parm show_video_info("-show_video_info", NULL, AT_NONE); //Cmdline_show_
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_window
char *Cmdline_start_mission = NULL;
SCP_string Cmdline_start_mission;
int Cmdline_dis_collisions = 0;
int Cmdline_dis_weapons = 0;
bool Cmdline_output_sexp_info = false;
@@ -500,8 +514,8 @@ int Cmdline_show_stats = 0;
int Cmdline_save_render_targets = 0;
int Cmdline_window = 0;
int Cmdline_fullscreen_window = 0;
char *Cmdline_res = 0;
char *Cmdline_center_res = 0;
SCP_string Cmdline_res;
SCP_string Cmdline_center_res;
int Cmdline_verify_vps = 0;
int Cmdline_reparse_mainhall = 0;
bool Cmdline_profile_write_file = false;
@@ -552,8 +566,8 @@ void cmdline_debug_print_cmdline()
for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
if ( parmp->name_found ) {
if ( parmp->args != NULL ) {
mprintf(("\n %s %s", parmp->name, parmp->args));
if (!parmp->args.empty()) {
mprintf(("\n %s %s", parmp->name, parmp->args.c_str()));
} else {
mprintf(("\n %s", parmp->name));
}
@@ -659,14 +673,13 @@ char *drop_extra_chars(char *str)
return str;
}
/*
* @brief Processes one argument for the given parameter
*
* @param param The parameter to check
* @param argc The argument count
* @param argc The argument values
* @param argc The current index
* @param argv The argument values
* @param index The current index
* @return @c true when an extra parameter was found, @c false otherwise
*/
bool parm_stuff_args(cmdline_parm *parm, int argc, char *argv[], int index)
@@ -683,47 +696,17 @@ bool parm_stuff_args(cmdline_parm *parm, int argc, char *argv[], int index)
}
else
{
char* saved_args = NULL;
if (parm->args != NULL) {
if (parm->stacks) {
saved_args = parm->args;
if (parm->stacks) {
if (!parm->args.empty())
{
// Avoid adding the , at the start
parm->args += ",";
}
else {
delete[] parm->args;
}
parm->args = NULL;
}
size_t argsize = strlen(argv[index + 1]);
size_t buffersize = argsize;
if (saved_args != NULL)
{
// Add one for the , separating args
buffersize += strlen(saved_args) + 1;
}
buffersize += 1; // Null-terminator
parm->args = new char[buffersize];
memset(parm->args, 0, buffersize);
if (saved_args != NULL)
{
// saved args go first, then new arg
strcpy_s(parm->args, buffersize, saved_args);
// add a separator too, so that we can tell the args apart
strcat_s(parm->args, buffersize, ",");
// now the new arg
strcat_s(parm->args, buffersize, argv[index + 1]);
delete[] saved_args;
parm->args += argv[index + 1];
}
else
{
strcpy_s(parm->args, buffersize, argv[index + 1]);
parm->args = argv[index + 1];
}
return true;
@@ -755,7 +738,7 @@ void os_parse_parms(int argc, char *argv[])
for (parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
if (!stricmp(parmp->name, argv[i]))
{
parmp->name_found = 1;
parmp->name_found = true;
if (parm_stuff_args(parmp, argc, argv, i))
{
i++;
@@ -936,11 +919,8 @@ bool has_cmdline_only_flag(int argc, char *argv[])
static void reset_cmdline_parms()
{
for (cmdline_parm *parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
if (parmp->args != NULL) {
delete[] parmp->args;
parmp->args = NULL;
}
parmp->name_found = 0;
parmp->args.clear();
parmp->name_found = false;
}
}
@@ -1036,11 +1016,14 @@ void os_init_cmdline(int argc, char *argv[])
* @param arg_type_ parameters arguement type (if any)
* @param stacks_ can the parameter be stacked
*/
cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_type_, const bool stacks_) noexcept:
name(name_), help(help_), stacks(stacks_), arg_type(arg_type_)
cmdline_parm::cmdline_parm(const char* name_, const char* help_, const int arg_type_, const bool stacks_) noexcept
: name(name_), help(help_), stacks(stacks_), arg_type(arg_type_)
{
args = NULL;
name_found = 0;
if (stacks) {
Assertion(arg_type == AT_STRING, "Only string arguments can stack!");
}
name_found = false;
if (Parm_list_inited == 0) {
Assertion(&Parm_list == this, "Coding error! 1st initialised cmdline_parm must be static Parm_list\n");
@@ -1059,20 +1042,12 @@ cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_t
// destructor - frees any allocated memory
cmdline_parm::~cmdline_parm() noexcept
{
#ifndef FRED
if (args) {
delete [] args;
args = NULL;
}
#endif
}
cmdline_parm::~cmdline_parm() noexcept = default;
// checks if the objects args variable is valid
// returns true if it is, shows an error box and returns false if not valid.
bool cmdline_parm::check_if_args_is_valid() {
if ( args == NULL ) {
if (args.empty()) {
Error(__FILE__, __LINE__,
"Command line flag passed that requires an argument, but the argument is missing!\r\n"
"The flag is '%s', make sure that you have an argument that follows it.\r\n"
@@ -1086,10 +1061,7 @@ bool cmdline_parm::check_if_args_is_valid() {
// returns - true if the parameter exists on the command line, otherwise false
int cmdline_parm::found()
{
return name_found;
}
bool cmdline_parm::found() { return name_found; }
// returns - the interger representation for the parameter argument
int cmdline_parm::get_int()
@@ -1097,22 +1069,12 @@ int cmdline_parm::get_int()
Assertion(arg_type == AT_INT, "Coding error! Cmdline arg (%s) called cmdline_parm::get_int() with invalid arg_type (%s)", name, cmdline_arg_types[arg_type]);
check_if_args_is_valid();
size_t offset = 0;
if (stacks) {
// first off, DON'T STACK NON-STRINGS!!
Int3();
// secondly, we still need to get it right for the user's sake...
char *moron = strstr(args, ",");
if ( moron && ((strlen(moron) + 1) < strlen(args)) ) {
// we get the last arg, since it's the newest one
offset = strlen(args) - strlen(moron) + 1;
}
try {
return std::stoi(args);
} catch (const std::exception& e) {
Warning(LOCATION, "Failed to convert '%s' to a float for parameter '%s'!", args.c_str(), name);
return 0;
}
return atoi(args+offset);
}
@@ -1122,36 +1084,24 @@ float cmdline_parm::get_float()
Assertion(arg_type == AT_FLOAT, "Coding error! Cmdline arg (%s) called cmdline_parm::get_float() with invalid arg_type (%s)", name, cmdline_arg_types[arg_type]);
check_if_args_is_valid();
size_t offset = 0;
if (stacks) {
// first off, DON'T STACK NON-STRINGS!!
Int3();
// secondly, we still need to get it right for the user's sake
char *moron = strstr(args, ",");
if ( moron && ((strlen(moron) + 1) < strlen(args)) ) {
// we get the last arg, since it's the newest one
offset = strlen(args) - strlen(moron) + 1;
}
try {
return std::stof(args);
} catch (const std::exception& e) {
Warning(LOCATION, "Failed to convert '%s' to a float for parameter '%s'!", args.c_str(), name);
return 0.0f;
}
return (float)atof(args+offset);
}
// returns - the string value for the parameter argument
char *cmdline_parm::str()
SCP_string cmdline_parm::str()
{
Assertion(arg_type == AT_STRING, "Coding error! Cmdline arg (%s) called cmdline_parm::str() with invalid arg_type (%s)", name, cmdline_arg_types[arg_type]);
check_if_args_is_valid();
return args;
}
bool cmdline_parm::has_param() {
return args != nullptr;
}
bool cmdline_parm::has_param() { return !args.empty(); }
#ifdef SCP_UNIX
// Return a vector with all filesystem names of "parent/dir" relative to parent.
@@ -1212,39 +1162,31 @@ static SCP_vector<SCP_string> unix_get_dir_names(const SCP_string& parent, const
}
// For case sensitive filesystems (e.g. Linux/BSD) perform case-insensitive dir matches.
static void handle_unix_modlist(char **modlist, size_t *len)
static SCP_string handle_unix_modlist(const SCP_string& modlist)
{
// search filesystem for given paths
SCP_vector<SCP_string> mod_paths;
for (char *cur_mod = strtok(*modlist, ","); cur_mod != NULL; cur_mod = strtok(NULL, ","))
{
SCP_stringstream iss(modlist);
SCP_string cur_mod;
while (std::getline(iss, cur_mod, ',')) {
SCP_vector<SCP_string> this_mod_paths = unix_get_dir_names(".", cur_mod);
// Ignore non-existing mods for unit tests
if (!running_unittests && this_mod_paths.empty()) {
ReleaseWarning(LOCATION, "Can't find mod '%s'. Ignoring.", cur_mod);
ReleaseWarning(LOCATION, "Can't find mod '%s'. Ignoring.", cur_mod.c_str());
}
mod_paths.insert(mod_paths.end(), this_mod_paths.begin(), this_mod_paths.end());
}
// create new char[] to replace modlist
size_t total_len = 0;
SCP_vector<SCP_string>::iterator ii, end = mod_paths.end();
for (ii = mod_paths.begin(); ii != end; ++ii) {
total_len += ii->length() + 1;
}
char *new_modlist = new char[total_len + 1];
memset(new_modlist, 0, total_len + 1);
end = mod_paths.end();
for (ii = mod_paths.begin(); ii != end; ++ii) {
strcat_s(new_modlist, total_len + 1, ii->c_str());
strcat_s(new_modlist, total_len + 1, ","); // replace later with NUL
// create new string to replace modlist
SCP_string new_modlist;
for (const auto& path : mod_paths) {
new_modlist += path;
new_modlist += ","; // replace later with NUL
}
// make the rest of the modlist manipulation unaware that anything happened here
delete [] *modlist;
*modlist = new_modlist;
*len = total_len;
return new_modlist;
}
#endif /* SCP_UNIX */
@@ -1302,6 +1244,7 @@ static json_t* json_get_v1() {
json_array_append_new(caps_array, json_string("No D3D"));
json_array_append_new(caps_array, json_string("New Sound"));
json_array_append_new(caps_array, json_string("SDL"));
json_array_append_new(caps_array, json_string("Stdin Flags: Json V1"));
json_object_set_new(root, "caps", caps_array);
}
@@ -1492,16 +1435,218 @@ static void write_flags() {
case flag_output_type::Binary:
write_flags_file();
break;
case flag_output_type::Json_V1:
case flag_output_type::Json_V1: {
json_t* root = json_get_v1();
json_dumpf(root, stdout, JSON_INDENT(4));
json_decref(root);
break;
}
}
}
bool SetCmdlineParams()
static bool validate_version(json_t* rootEl)
{
const auto version_el = json_object_get(rootEl, "version");
if (version_el == nullptr) {
printf("Version element is missing!\n");
return false;
}
if (!json_is_number(version_el)) {
printf("Version value is not a number!\n");
return false;
}
if (json_integer_value(version_el) != 1) {
printf("Version value %" JSON_INTEGER_FORMAT " is not supported!\n", json_integer_value(version_el));
return false;
}
return true;
}
static cfile::ModRootType mapModRootType(const char* rootStr) {
if (!stricmp(rootStr, "folder")) {
return cfile::ModRootType::Folder;
} else if (!stricmp(rootStr, "package")) {
return cfile::ModRootType::Package;
} else {
return cfile::ModRootType::Unknown;
}
}
static cfile::LocationType mapLocationType(const char* rootStr) {
if (!stricmp(rootStr, "game_root")) {
return cfile::LocationType::GameRoot;
} else if (!stricmp(rootStr, "primary_mod")) {
return cfile::LocationType::PrimaryMod;
} else if (!stricmp(rootStr, "secondary_mod")) {
return cfile::LocationType::SecondaryMod;
} else {
return cfile::LocationType::Unknown;
}
}
static void stuff_mod_option(cmdline_parm* param, json_t* el)
{
if (!json_is_array(el))
{
printf("Value for option %s must be an array!", param->name);
return;
}
SCP_vector<cfile::ModRoot> roots;
size_t i;
json_t* modObj;
json_array_foreach(el, i, modObj)
{
const auto typeEl = json_object_get(modObj, "type");
const auto pathEl = json_object_get(modObj, "path");
const auto locationEl = json_object_get(modObj, "location_type");
if (typeEl == nullptr || pathEl == nullptr || locationEl == nullptr)
{
printf("A required mod root element is missing: Type %p, Path %p, Location %p", typeEl, pathEl, locationEl);
continue;
}
if (!json_is_string(typeEl) || !json_is_string(pathEl) || !json_is_string(locationEl))
{
printf("An element had a wrong type: Type %d, Path %d, Location %d", json_typeof(typeEl), json_typeof(pathEl), json_typeof(locationEl));
continue;
}
const auto userEl = json_object_get(modObj, "user");
if (userEl != nullptr && !json_is_boolean(userEl))
{
printf("User element type is not a boolean!");
continue;
}
cfile::ModRoot root;
root.type = mapModRootType(json_string_value(typeEl));
root.path = json_string_value(pathEl);
root.location_type = mapLocationType(json_string_value(locationEl));
root.user_location = userEl == nullptr ? false : json_boolean_value(userEl);
roots.push_back(root);
}
Cmdline_mod = roots;
}
static void stuff_json_option(cmdline_parm* param, json_t* el)
{
if (param == &mod_arg)
{
// The -mod parameter is handled specially since it is not a simple string
stuff_mod_option(param, el);
return;
}
switch (param->arg_type) {
case AT_NONE:
if (!json_is_boolean(el)) {
printf("Value for option %s must be a boolean!", param->name);
return;
}
param->name_found = json_is_true(el);
break;
case AT_INT:
if (!json_is_number(el)) {
printf("Value for option %s must be a number!", param->name);
return;
}
param->name_found = true;
param->args = std::to_string(json_integer_value(el));
break;
case AT_FLOAT:
if (!json_is_number(el)) {
printf("Value for option %s must be a number!", param->name);
return;
}
param->name_found = true;
param->args = std::to_string(json_real_value(el));
break;
case AT_STRING:
if (!json_is_string(el)) {
printf("Value for option %s must be a string!", param->name);
return;
}
param->name_found = true;
param->args.assign(json_string_value(el), json_string_length(el));
break;
default:
UNREACHABLE("Unknown arg type %d.", param->arg_type);
return;
}
}
static bool parse_json_flags(json_t* rootEl)
{
if (!json_is_object(rootEl)) {
printf("Root element must be an object!\n");
return false;
}
if (!validate_version(rootEl)) {
return false;
}
const auto flagsEl = json_object_get(rootEl, "flags");
if (flagsEl == nullptr) {
printf("Flags element is missing!\n");
return false;
}
if (!json_is_object(flagsEl)) {
printf("Flags element is not an object!\n");
return false;
}
const char* flagName;
json_t* flagValue;
json_object_foreach(flagsEl, flagName, flagValue)
{
for (auto parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
if (!stricmp(parmp->name, flagName)) {
stuff_json_option(parmp, flagValue);
}
}
}
return true;
}
static bool SetCmdlineParams(flag_input_type inputType);
static bool SetCmdlineParamsFromStdin(const SCP_string& format)
{
if (format != "json_v1") {
// Invalid format!
printf("INPUT TYPE '%s' IS NOT SUPPORTED!\n", format.c_str());
return false;
}
json_error_t error;
json_t* flagsEl = json_loadf(stdin, JSON_DISABLE_EOF_CHECK, &error);
if (flagsEl == nullptr) {
printf("Failed to parse JSON: %s(%d:%d): %s\n", error.source, error.line, error.column, error.text);
return false;
}
if (!parse_json_flags(flagsEl)) {
return false;
}
return SetCmdlineParams(flag_input_type::Stdin_Json_V1);
}
static bool SetCmdlineParams(flag_input_type inputType)
// Sets externed variables used for communication cmdline information
{
//getcwd(FreeSpace_Directory, 256); // set the directory to our fs2 root
@@ -1513,6 +1658,10 @@ bool SetCmdlineParams()
return false;
}
if (inputType == flag_input_type::Flags && stdin_flags.found()) {
return SetCmdlineParamsFromStdin(stdin_flags.str());
}
if (no_fpscap.found())
{
Cmdline_NoFPSCap = 1;
@@ -1544,8 +1693,8 @@ bool SetCmdlineParams()
Cmdline_spew_mission_crcs = missioncrcspew_arg.str();
// strip off blank space at end if it's there
if ( Cmdline_spew_mission_crcs[strlen(Cmdline_spew_mission_crcs)-1] == ' ' ) {
Cmdline_spew_mission_crcs[strlen(Cmdline_spew_mission_crcs)-1] = '\0';
if (Cmdline_spew_mission_crcs.back() == ' ') {
Cmdline_spew_mission_crcs.resize(Cmdline_spew_mission_crcs.size() - 1);
}
}
@@ -1553,8 +1702,8 @@ bool SetCmdlineParams()
Cmdline_spew_table_crcs = tablecrcspew_arg.str();
// strip off blank space at end if it's there
if ( Cmdline_spew_table_crcs[strlen(Cmdline_spew_table_crcs)-1] == ' ' ) {
Cmdline_spew_table_crcs[strlen(Cmdline_spew_table_crcs)-1] = '\0';
if (Cmdline_spew_table_crcs.back() == ' ') {
Cmdline_spew_table_crcs.resize(Cmdline_spew_table_crcs.size() - 1);
}
}
@@ -1620,8 +1769,8 @@ bool SetCmdlineParams()
Cmdline_game_name = gamename_arg.str();
// be sure that this string fits in our limits
if ( strlen(Cmdline_game_name) > MAX_GAMENAME_LEN ) {
Cmdline_game_name[MAX_GAMENAME_LEN-1] = '\0';
if (Cmdline_game_name.size() > MAX_GAMENAME_LEN - 1) {
Cmdline_game_name.resize(MAX_GAMENAME_LEN - 1);
}
}
@@ -1630,8 +1779,8 @@ bool SetCmdlineParams()
Cmdline_game_password = gamepassword_arg.str();
// be sure that this string fits in our limits
if ( strlen(Cmdline_game_name) > MAX_PASSWD_LEN ) {
Cmdline_game_name[MAX_PASSWD_LEN-1] = '\0';
if (Cmdline_game_password.size() > MAX_GAMENAME_LEN - 1) {
Cmdline_game_password.resize(MAX_GAMENAME_LEN - 1);
}
}
@@ -1700,12 +1849,13 @@ bool SetCmdlineParams()
int width = 0;
int height = 0;
if ( sscanf(Cmdline_res, "%dx%d", &width, &height) == 2 ) {
if (sscanf(Cmdline_res.c_str(), "%dx%d", &width, &height) == 2) {
SCP_string override;
sprintf(override, "{\"width\":%d,\"height\":%d}", width, height);
sprintf(override, R"({"width":%d,"height":%d})", width, height);
options::OptionsManager::instance()->setOverride("Graphics.Resolution", override);
} else {
mprintf(("Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".", Cmdline_res));
mprintf(("Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".",
Cmdline_res.c_str()));
}
}
if(center_res_arg.found()){
@@ -1738,35 +1888,32 @@ bool SetCmdlineParams()
Cmdline_noparseerrors = 1;
}
if(mod_arg.found() ) {
Cmdline_mod = mod_arg.str();
// Legacy mod handling is handled here
if (inputType == flag_input_type::Flags && mod_arg.found()) {
auto modCmdline = mod_arg.str();
// strip off blank space it it's there
if ( Cmdline_mod[strlen(Cmdline_mod)-1] == ' ' ) {
Cmdline_mod[strlen(Cmdline_mod)-1] = '\0';
if (modCmdline.back() == ' ') {
modCmdline.resize(modCmdline.size() - 1);
}
// Ok - mod stacking support
size_t len = strlen(Cmdline_mod);
char *modlist = new char[len+2];
memset( modlist, 0, len + 2 );
strcpy_s(modlist, len+2, Cmdline_mod);
#ifdef SCP_UNIX
// handle case-insensitive searching
handle_unix_modlist(&modlist, &len);
modCmdline = handle_unix_modlist(modCmdline);
#endif
// null terminate each individual
for (size_t i = 0; i < len; i++)
for (auto& ch : modCmdline)
{
if (modlist[i] == ',')
modlist[i] = '\0';
if (ch == ',')
ch = '\0';
}
//copy over - we don't have to delete[] Cmdline_mod because it's a pointer to an automatic global char*
Cmdline_mod = modlist;
char whee[MAX_PATH_LEN];
memset(whee, 0, sizeof(whee));
_getcwd(whee, MAX_PATH_LEN-1);
Cmdline_mod = cfile::getModRootsFromModCmdline(whee, modCmdline.c_str());
}
@@ -1887,30 +2034,6 @@ bool SetCmdlineParams()
Gr_aa_mode_last_frame = Gr_aa_mode;
}
if (smaa_arg.found()) {
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
if (smaa_preset_arg.found()) {
switch (smaa_preset_arg.get_int()) {
case 0:
Gr_aa_mode = AntiAliasMode::SMAA_Low;
break;
case 1:
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
break;
case 2:
Gr_aa_mode = AntiAliasMode::SMAA_High;
break;
case 3:
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
break;
default:
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
break;
}
}
}
if ( glow_arg.found() )
Cmdline_glow = 0;
@@ -2214,7 +2337,7 @@ int parse_cmdline(int argc, char *argv[])
// --------------- Kazan -------------
// If you're looking for the list of if (someparam.found()) { cmdline_someparam = something; } look above at this function
// I did this because of fred2_parse_cmdline()
return SetCmdlineParams();
return SetCmdlineParams(flag_input_type::Flags);
}
const char * get_param_desc(const char *flag_name)
+18 -13
View File
@@ -12,6 +12,7 @@
#ifndef FS_CMDLINE_HEADER_FILE
#define FS_CMDLINE_HEADER_FILE
#include "globalincs/pstypes.h"
int parse_cmdline(int argc, char *argv[]);
@@ -24,11 +25,11 @@ int parse_cmdline(int argc, char *argv[]);
// RETAIL OPTIONS ----------------------------------------------
extern char *Cmdline_connect_addr;
extern char *Cmdline_game_name;
extern char *Cmdline_game_password;
extern char *Cmdline_rank_above;
extern char *Cmdline_rank_below;
extern SCP_string Cmdline_connect_addr;
extern SCP_string Cmdline_game_name;
extern SCP_string Cmdline_game_password;
extern SCP_string Cmdline_rank_above;
extern SCP_string Cmdline_rank_below;
extern int Cmdline_cd_check;
extern int Cmdline_client_dodamage;
extern int Cmdline_closed_game;
@@ -46,8 +47,8 @@ extern int Cmdline_timeout;
extern int Cmdline_use_last_pilot;
extern int Cmdline_window;
extern int Cmdline_fullscreen_window;
extern char *Cmdline_res;
extern char *Cmdline_center_res;
extern SCP_string Cmdline_res;
extern SCP_string Cmdline_center_res;
// FSO OPTIONS -------------------------------------------------
@@ -96,14 +97,18 @@ extern int Cmdline_stretch_menu;
extern int Cmdline_voice_recognition;
extern int Cmdline_no_enhanced_sound;
namespace cfile {
struct ModRoot;
} // namespace cfile
// MOD related
extern char *Cmdline_mod; // DTP for mod support
extern SCP_vector<cfile::ModRoot> Cmdline_mod; // DTP for mod support
// Multiplayer/Network related
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
extern SCP_string Cmdline_almission; // DTP for autoload mission (for multi only)
extern int Cmdline_ingamejoin;
extern int Cmdline_mpnoreturn;
extern char *Cmdline_spew_mission_crcs;
extern char *Cmdline_spew_table_crcs;
extern SCP_string Cmdline_spew_mission_crcs;
extern SCP_string Cmdline_spew_table_crcs;
extern int Cmdline_objupd;
// Launcher related options
@@ -119,7 +124,7 @@ extern int Cmdline_mipmap;
extern int Cmdline_ati_color_swap;
extern int Cmdline_no_3d_sound;
extern int Cmdline_drawelements;
extern char* Cmdline_keyboard_layout;
extern SCP_string Cmdline_keyboard_layout;
extern bool Cmdline_gl_finish;
extern bool Cmdline_no_geo_sdr_effects;
extern bool Cmdline_set_cpu_affinity;
@@ -130,7 +135,7 @@ extern bool Cmdline_alternate_registry_path;
#endif
// Developer/Testing related
extern char *Cmdline_start_mission;
extern SCP_string Cmdline_start_mission;
extern int Cmdline_dis_collisions;
extern int Cmdline_dis_weapons;
extern bool Cmdline_output_sexp_info;
+48
View File
@@ -0,0 +1,48 @@
{
"version": 1,
"flags": {
"-bool_option": false,
"-number_option": 5.8,
"-string_option": "asdf",
"-mod": [
{
"type": "folder",
"path": "/home/fso/mediavps",
"user": true,
"location_type": "primary_mod"
},
{
"type": "folder",
"path": "/home/fso",
"user": true,
"location_type": "game_root"
},
{
"type": "folder",
"path": "/path/to/fso/mediavps",
"user": false,
"location_type": "primary_mod"
},
{
"type": "package",
"path": "/path/to/fso/mediavps/MVPS-Z.vp",
"location_type": "primary_mod"
},
{
"type": "package",
"path": "/path/to/fso/mediavps/MVPS-X.vp",
"location_type": "primary_mod"
},
{
"type": "folder",
"path": "/path/to/fso",
"location_type": "game_root"
},
{
"type": "package",
"path": "/path/to/fso/retail.vp",
"location_type": "game_root"
}
]
}
}
File diff suppressed because it is too large. Load diff
@@ -1,23 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
#include "SMAA.sdr"
in vec2 fragTexCoord;
in vec2 fragPixcoord;
in vec4 fragOffset[3];
out vec4 fragOut0;
uniform sampler2D edgesTex;
uniform sampler2D areaTex;
uniform sampler2D searchTex;
void main() {
fragOut0 = SMAABlendingWeightCalculationPS(fragTexCoord, fragPixcoord, fragOffset, edgesTex, areaTex, searchTex, vec4(0.0));
}
@@ -1,22 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
#include "SMAA.sdr"
in vec4 vertPosition;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec2 fragPixcoord;
out vec4 fragOffset[3];
void main() {
gl_Position = vertPosition;
fragTexCoord = vertTexCoord;
SMAABlendingWeightCalculationVS(vertTexCoord, fragPixcoord, fragOffset);
}
@@ -1,20 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
#include "SMAA.sdr"
in vec2 fragTexCoord;
in vec4 fragOffset[3];
out vec4 fragOut0;
uniform sampler2D colorTex;
void main() {
fragOut0 = vec4(SMAALumaEdgeDetectionPS(fragTexCoord, fragOffset, colorTex), 0.0, 1.0);
}
@@ -1,21 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
#include "SMAA.sdr"
in vec4 vertPosition;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec4 fragOffset[3];
void main() {
gl_Position = vertPosition;
fragTexCoord = vertTexCoord;
SMAAEdgeDetectionVS(vertTexCoord, fragOffset);
}
@@ -1,21 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
#include "SMAA.sdr"
in vec2 fragTexCoord;
in vec4 fragOffset;
out vec4 fragOut0;
uniform sampler2D colorTex;
uniform sampler2D blendTex;
void main() {
fragOut0 = SMAANeighborhoodBlendingPS(fragTexCoord, fragOffset, colorTex, blendTex);
}
@@ -1,21 +0,0 @@
uniform vec2 smaa_rt_metrics;
#define SMAA_RT_METRICS vec4(1.0 / smaa_rt_metrics, smaa_rt_metrics)
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
#include "SMAA.sdr"
in vec4 vertPosition;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
out vec4 fragOffset;
void main() {
gl_Position = vertPosition;
fragTexCoord = vertTexCoord;
SMAANeighborhoodBlendingVS(vertTexCoord, fragOffset);
}
+2 -2
View File
@@ -1678,7 +1678,7 @@ void fs2netd_spew_table_checksums(const char *outfile)
char description[512] = { 0 };
char filename[65] = { 0 };
size_t offset = 0;
char *p = NULL;
const char *p = nullptr;
if ( Table_valid_status.empty() ) {
return;
@@ -1693,7 +1693,7 @@ void fs2netd_spew_table_checksums(const char *outfile)
return;
}
p = Cmdline_spew_table_crcs;
p = Cmdline_spew_table_crcs.c_str();
while (*p && (offset < sizeof(description))) {
if (*p == '"' && offset < sizeof(description)-1) {
+1 -1
View File
@@ -450,7 +450,7 @@ SCP_string dump_stacktrace();
// DEBUG compile time catch for dangerous uses of memset/memcpy/memmove
// This is disabled for VS2013 and lower since that doesn't support the necessary features
#if !defined(NDEBUG) && !defined(USING_THIRD_PARTY_LIBS) && (!defined(_MSC_VER) || _MSC_VER >= 1900)
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(SCP_HAVE_STD_IS_TRIVIALLY_COPYABLE)
#if SCP_COMPILER_CXX_AUTO_TYPE && SCP_COMPILER_CXX_STATIC_ASSERT && defined(HAVE_STD_IS_TRIVIALLY_COPYABLE)
// feature support seems to be: gcc clang msvc
// auto 4.4 2.9 2010
// std::is_trivial 4.5 ? 2012 (2010 only duplicates std::is_pod)
+1
View File
@@ -4,6 +4,7 @@
#pragma once
#include "scp_compiler_detection.h"
#include "platformChecks.h"
#define SCP_TOKEN_CONCAT1(x, y) x ## y
#define SCP_TOKEN_CONCAT(x, y) SCP_TOKEN_CONCAT1(x, y)
-1
View File
@@ -61,7 +61,6 @@ version get_executable_version() {
version::version(int major_in, int minor_in, int build_in, int revision_in) :
major(major_in), minor(minor_in), build(build_in), revision(revision_in) {
}
bool version::isValid() const { return major != 0 || minor != 0 || build != 0 || revision != 0; }
bool version::operator<(const version& v) const {
if (major < v.major) {
-2
View File
@@ -57,8 +57,6 @@ struct version {
version(int major, int minor, int build, int revision);
bool isValid() const;
bool operator<(const version& other) const;
bool operator==(const version& other) const;
bool operator!=(const version& other) const;
+5 -12
View File
@@ -304,11 +304,7 @@ static auto AAOption = options::OptionBuilder<AntiAliasMode>("Graphics.AAMode",
.values({{AntiAliasMode::None, "None"},
{AntiAliasMode::FXAA_Low, "FXAA Low"},
{AntiAliasMode::FXAA_Medium, "FXAA Medium"},
{AntiAliasMode::FXAA_High, "FXAA High"},
{AntiAliasMode::SMAA_Low, "SMAA Low"},
{AntiAliasMode::SMAA_Medium, "SMAA Medium"},
{AntiAliasMode::SMAA_High, "SMAA High"},
{AntiAliasMode::SMAA_Ultra, "SMAA Ultra"}})
{AntiAliasMode::FXAA_High, "FXAA High"}})
.default_val(AntiAliasMode::None)
.bind_to(&Gr_aa_mode)
.importance(79)
@@ -318,9 +314,6 @@ bool gr_is_fxaa_mode(AntiAliasMode mode)
{
return mode == AntiAliasMode::FXAA_Low || mode == AntiAliasMode::FXAA_Medium || mode == AntiAliasMode::FXAA_High;
}
bool gr_is_smaa_mode(AntiAliasMode mode) {
return mode == AntiAliasMode::SMAA_Low || mode == AntiAliasMode::SMAA_Medium || mode == AntiAliasMode::SMAA_High || mode == AntiAliasMode::SMAA_Ultra;
}
bool Gr_post_processing_enabled = false;
@@ -1255,11 +1248,11 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
}
}
if (Cmdline_res != nullptr) {
if (!Cmdline_res.empty()) {
int tmp_width = 0;
int tmp_height = 0;
if ( sscanf(Cmdline_res, "%dx%d", &tmp_width, &tmp_height) == 2 ) {
if ( sscanf(Cmdline_res.c_str(), "%dx%d", &tmp_width, &tmp_height) == 2 ) {
width = tmp_width;
height = tmp_height;
}
@@ -1267,11 +1260,11 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
Gr_enable_soft_particles = Cmdline_softparticles != 0;
}
if (Cmdline_center_res != NULL) {
if (!Cmdline_center_res.empty()) {
int tmp_center_width = 0;
int tmp_center_height = 0;
if ( (sscanf(Cmdline_center_res, "%dx%d", &tmp_center_width, &tmp_center_height) == 2) && (tmp_center_width > 0) && (tmp_center_height > 0) ) {
if ( (sscanf(Cmdline_center_res.c_str(), "%dx%d", &tmp_center_width, &tmp_center_height) == 2) && (tmp_center_width > 0) && (tmp_center_height > 0) ) {
center_aspect_ratio = (float)tmp_center_width / (float)tmp_center_height;
}
}
+1 -13
View File
@@ -47,21 +47,14 @@ extern flagset<FramebufferEffects> Gr_framebuffer_effects;
enum class AntiAliasMode {
None,
FXAA_Low,
FXAA_Medium,
FXAA_High,
SMAA_Low,
SMAA_Medium,
SMAA_High,
SMAA_Ultra,
FXAA_High
};
extern AntiAliasMode Gr_aa_mode;
extern AntiAliasMode Gr_aa_mode_last_frame;
bool gr_is_fxaa_mode(AntiAliasMode mode);
bool gr_is_smaa_mode(AntiAliasMode mode);
extern bool Gr_post_processing_enabled;
@@ -191,11 +184,6 @@ enum shader_type {
SDR_TYPE_DECAL,
SDR_TYPE_SCENE_FOG,
SDR_TYPE_ROCKET_UI,
SDR_TYPE_POST_PROCESS_SMAA_EDGE,
SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT,
SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING,
NUM_SHADER_TYPES
};
File diff suppressed because it is too large. Load diff
-134
View File
@@ -1,134 +0,0 @@
/**
* Copyright (C) 2013 Jorge Jimenez ([email protected])
* Copyright (C) 2013 Jose I. Echevarria ([email protected])
* Copyright (C) 2013 Belen Masia ([email protected])
* Copyright (C) 2013 Fernando Navarro ([email protected])
* Copyright (C) 2013 Diego Gutierrez ([email protected])
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to
* do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. As clarification, there
* is no requirement that the copyright notice and permission be included in
* binary distributions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef SEARCHTEX_H
#define SEARCHTEX_H
#define SEARCHTEX_WIDTH 64
#define SEARCHTEX_HEIGHT 16
#define SEARCHTEX_PITCH SEARCHTEX_WIDTH
#define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
// clang-format off
/**
* Stored in R8 format. Load it in the following format:
* - DX9: D3DFMT_L8
* - DX10: DXGI_FORMAT_R8_UNORM
*/
static const unsigned char searchTexBytes[] = {
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
// clang-format on
#endif
+3 -3
View File
@@ -37,7 +37,7 @@ void opengl_clear_deferred_buffers()
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_CLEAR, 0) );
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
opengl_shader_set_current();
@@ -263,7 +263,7 @@ void gr_opengl_deferred_lighting_finish()
uniformAligner.getOffset(element_index),
sizeof(graphics::deferred_light_data),
buffer->bufferHandle());
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
++element_index;
break;
case Light_Type::Cone:
@@ -335,7 +335,7 @@ void gr_opengl_deferred_lighting_finish()
Current_shader->program->Uniforms.setUniformf("zNear", Min_draw_distance);
Current_shader->program->Uniforms.setUniformf("zFar", Max_draw_distance);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
} else {
// Transfer the resolved lighting back to the color texture
// TODO: Maybe this could be improved so that it doesn't require the copy back operation?
+5 -23
View File
@@ -534,7 +534,7 @@ void gr_opengl_scene_texture_end()
}
if ( Gr_post_processing_enabled && !PostProcessing_override ) {
gr_opengl_post_process_end();
gr_post_process_end();
} else {
GR_DEBUG_SCOPE("Draw scene texture");
TRACE_SCOPE(tracing::DrawSceneTexture);
@@ -551,7 +551,7 @@ void gr_opengl_scene_texture_end()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
opengl_shader_set_passthrough(true, High_dynamic_range);
opengl_shader_set_passthrough(true);
GL_state.Array.BindArrayBuffer(0);
@@ -650,7 +650,7 @@ void gr_opengl_update_distortion()
GLboolean blend = GL_state.Blend(GL_FALSE);
GLboolean cull = GL_state.CullFace(GL_FALSE);
opengl_shader_set_passthrough(true, High_dynamic_range);
opengl_shader_set_passthrough(true);
GL_state.PushFramebufferState();
GL_state.BindFrameBuffer(Distortion_framebuffer);
@@ -695,7 +695,7 @@ void gr_opengl_update_distortion()
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, vertices, sizeof(vertex) * 4);
opengl_shader_set_passthrough(false, High_dynamic_range);
opengl_shader_set_passthrough(false);
vertex distortion_verts[33];
@@ -864,25 +864,7 @@ void opengl_draw_textured_quad(GLfloat x1,
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(glVertices));
}
void opengl_draw_full_screen_textured(GLfloat u1, GLfloat v1, GLfloat u2, GLfloat v2)
{
GR_DEBUG_SCOPE("Draw full screen triangle");
GLfloat glVertices[3][4] = {
{-1.f, -1.f, u1, v1},
{3.f, -1.f, u2 * 2.f, v1},
{-1.f, 3.f, u1, v2 * 2.f},
};
vertex_layout vert_def;
vert_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(GLfloat) * 4, 0);
vert_def.add_vertex_component(vertex_format_data::TEX_COORD2, sizeof(GLfloat) * 4, sizeof(GLfloat) * 2);
opengl_render_primitives_immediate(PRIM_TYPE_TRIS, &vert_def, 3, glVertices, sizeof(glVertices));
opengl_render_primitives_immediate(PRIM_TYPE_TRISTRIP, &vert_def, 4, glVertices, sizeof(GLfloat) * 4 * 4);
}
void gr_opengl_render_decals(decal_material* material_info,
-14
View File
@@ -64,20 +64,6 @@ void gr_opengl_render_rocket_primitives(interface_material* material_info, primi
void opengl_draw_textured_quad(GLfloat x1, GLfloat y1, GLfloat u1, GLfloat v1,
GLfloat x2, GLfloat y2, GLfloat u2, GLfloat v2 );
/**
* @brief Draw "something" so that the entire screen is covered and the corners use the UV values that are provided.
*
* @details This actually draws a a single oversized triangle that covers the screen in such a way so that the provided
* UV values are generated by the GPU in the corners of the screen. This is better than drawing two triangles since then
* the diagonal would be shaded differently for the two triangles causing visual differences.
*
* @param u1 The U value of the lower left corner.
* @param v1 The V value of the lower left corner.
* @param u2 The U value of the upper right corner.
* @param v2 The V value of the upper right corner.
*/
void opengl_draw_full_screen_textured(GLfloat u1, GLfloat v1, GLfloat u2, GLfloat v2);
inline GLenum opengl_primitive_type(primitive_type prim_type);
void gr_opengl_start_decal_pass();
+64 -366
View File
@@ -1,17 +1,12 @@
#include "gropenglpostprocessing.h"
#include "ShaderProgram.h"
#include "SmaaAreaTex.h"
#include "SmaaSearchTex.h"
#include "freespace.h"
#include "gropengl.h"
#include "gropengldraw.h"
#include "gropenglshader.h"
#include "gropenglstate.h"
#include "cmdline/cmdline.h"
#include "freespace.h"
#include "def_files/def_files.h"
#include "gropengl.h"
#include "gropengldraw.h"
#include "gropenglpostprocessing.h"
#include "gropenglshader.h"
#include "gropenglstate.h"
#include "io/timer.h"
#include "lighting/lighting.h"
#include "mod_table/mod_table.h"
@@ -19,6 +14,8 @@
#include "parse/parselo.h"
#include "ship/ship.h"
#include "tracing/tracing.h"
#include "ShaderProgram.h"
extern bool PostProcessing_override;
extern int opengl_check_framebuffer();
@@ -78,18 +75,6 @@ static GLuint Post_framebuffer_id[2] = { 0 };
static int Post_texture_width = 0;
static int Post_texture_height = 0;
static GLuint Smaa_edge_detection_fb = 0;
static GLuint Smaa_edges_tex = 0;
static GLuint Smaa_blending_weight_fb = 0;
static GLuint Smaa_blend_tex = 0;
static GLuint Smaa_neighborhood_blending_fb = 0;
static GLuint Smaa_output_tex = 0;
static GLuint Smaa_search_tex = 0;
static GLuint Smaa_area_tex = 0;
void opengl_post_pass_tonemap()
{
GR_DEBUG_SCOPE("Tonemapping");
@@ -104,7 +89,7 @@ void opengl_post_pass_tonemap()
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
void opengl_post_pass_bloom()
@@ -139,7 +124,7 @@ void opengl_post_pass_bloom()
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_color_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
}
// ------ end bright pass ------
@@ -179,7 +164,7 @@ void opengl_post_pass_bloom()
glViewport(0, 0, bloom_width, bloom_height);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
}
}
}
@@ -203,7 +188,7 @@ void opengl_post_pass_bloom()
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
}
@@ -278,7 +263,7 @@ void opengl_post_pass_fxaa() {
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
// set and configure post shader ..
opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) );
@@ -292,124 +277,11 @@ void opengl_post_pass_fxaa() {
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_luminance_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_shader_set_current();
}
static void smaa_detect_edges()
{
GR_DEBUG_SCOPE("SMAA Detect Edges");
TRACE_SCOPE(tracing::SMAAEdgeDetection);
GL_state.BindFrameBuffer(Smaa_edge_detection_fb);
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, clearValues);
// Do the edge detection step
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
static void smaa_calculate_blending_weights()
{
GR_DEBUG_SCOPE("SMAA Blending Weights calculation");
TRACE_SCOPE(tracing::SMAACalculateBlendingWeights);
GL_state.BindFrameBuffer(Smaa_blending_weight_fb);
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, clearValues);
// Do the edge detection step
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setUniformi("edgesTex", 0);
Current_shader->program->Uniforms.setUniformi("areaTex", 1);
Current_shader->program->Uniforms.setUniformi("searchTex", 2);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_edges_tex);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_area_tex);
GL_state.Texture.Enable(2, GL_TEXTURE_2D, Smaa_search_tex);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
static void smaa_neighborhood_blending()
{
GR_DEBUG_SCOPE("SMAA Neighborhood Blending");
TRACE_SCOPE(tracing::SMAANeighborhoodBlending);
GL_state.BindFrameBuffer(Smaa_neighborhood_blending_fb);
GLfloat clearValues[] = {0.0f, 0.0f, 0.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, clearValues);
// Do the edge detection step
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0));
// basic/default uniforms
Current_shader->program->Uniforms.setUniformi("colorTex", 0);
Current_shader->program->Uniforms.setUniformi("blendTex", 1);
Current_shader->program->Uniforms.setUniform2f("smaa_rt_metrics", i2fl(Post_texture_width),
i2fl(Post_texture_height));
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Scene_ldr_texture);
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Smaa_blend_tex);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
}
void smaa_resolve()
{
GR_DEBUG_SCOPE("SMAA Resolve");
TRACE_SCOPE(tracing::SMAAResolve);
opengl_shader_set_passthrough(true, false);
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Smaa_output_tex);
// Copy SMAA output back to the original framebuffer
if (GL_rendering_to_texture) {
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, 0.0f, (float)gr_screen.max_w, (float)gr_screen.max_h,
Scene_texture_u_scale, Scene_texture_v_scale);
} else {
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, Scene_texture_v_scale, (float)gr_screen.max_w,
(float)gr_screen.max_h, Scene_texture_u_scale, 0.0f);
}
}
void opengl_post_pass_smaa()
{
GR_DEBUG_SCOPE("SMAA");
TRACE_SCOPE(tracing::SMAA);
GL_state.PushFramebufferState();
GL_state.ColorMask(true, true, true, true);
smaa_detect_edges();
smaa_calculate_blending_weights();
smaa_neighborhood_blending();
GL_state.PopFramebufferState();
smaa_resolve();
}
extern GLuint Shadow_map_depth_texture;
extern GLuint Scene_depth_texture;
extern GLuint Cockpit_depth_texture;
@@ -460,7 +332,7 @@ void opengl_post_lightshafts()
GL_state.Blend(GL_TRUE);
GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
GL_state.Blend(GL_FALSE);
break;
@@ -490,14 +362,10 @@ void gr_opengl_post_process_end()
// do tone mapping
opengl_post_pass_tonemap();
// Do Post processing AA
if (!GL_rendering_to_texture) {
if (gr_is_smaa_mode(Gr_aa_mode)) {
opengl_post_pass_smaa();
} else if (gr_is_fxaa_mode(Gr_aa_mode) && !fxaa_unavailable) {
opengl_post_pass_fxaa();
}
}
// Do FXAA
if (gr_is_fxaa_mode(Gr_aa_mode) && !fxaa_unavailable && !GL_rendering_to_texture) {
opengl_post_pass_fxaa();
}
// render lightshafts
opengl_post_lightshafts();
@@ -554,7 +422,7 @@ void gr_opengl_post_process_end()
GL_state.Texture.Enable(1, GL_TEXTURE_2D, Scene_depth_texture);
opengl_draw_full_screen_textured(0.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale);
opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale);
//Shadow Map debug window
//#define SHADOW_DEBUG
@@ -837,58 +705,9 @@ static bool opengl_post_init_table()
}
}
static void set_fxaa_defines(SCP_stringstream& sflags)
void opengl_post_shader_header(SCP_stringstream &sflags, shader_type shader_t, int flags)
{
// Since we require OpenGL 3.2 we always have support for GLSL 130
sflags << "#define FXAA_GLSL_120 0\n";
sflags << "#define FXAA_GLSL_130 1\n";
if (GLSL_version >= 400) {
// The gather function became part of the standard with GLSL 4.00
sflags << "#define FXAA_GATHER4_ALPHA 1\n";
}
switch (Gr_aa_mode) {
case AntiAliasMode::None:
sflags << "#define FXAA_QUALITY_PRESET 10\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_Low:
sflags << "#define FXAA_QUALITY_PRESET 12\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/8.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/16.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_Medium:
sflags << "#define FXAA_QUALITY_PRESET 26\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/24.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_High:
sflags << "#define FXAA_QUALITY_PRESET 39\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/15.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
default:
UNREACHABLE("Unhandled FXAA mode!");
}
}
void set_smaa_defines(SCP_stringstream& sflags)
{
// Define what GLSL version we use
if (GLSL_version >= 400) {
sflags << "#define SMAA_GLSL_4\n";
} else {
sflags << "#define SMAA_GLSL_3\n";
}
}
void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, int flags)
{
if (shader_t == SDR_TYPE_POST_PROCESS_MAIN) {
if ( shader_t == SDR_TYPE_POST_PROCESS_MAIN ) {
for (size_t idx = 0; idx < Post_effects.size(); idx++) {
if (flags & (1 << idx)) {
sflags << "#define ";
@@ -896,15 +715,46 @@ void opengl_post_shader_header(SCP_stringstream& sflags, shader_type shader_t, i
sflags << "\n";
}
}
} else if (shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS) {
} else if ( shader_t == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ) {
char temp[64];
sprintf(temp, "#define SAMPLE_NUM %d\n", ls_samplenum);
sflags << temp;
} else if (shader_t == SDR_TYPE_POST_PROCESS_FXAA) {
set_fxaa_defines(sflags);
} else if (shader_t == SDR_TYPE_POST_PROCESS_SMAA_EDGE || shader_t == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
shader_t == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
set_smaa_defines(sflags);
} else if ( shader_t == SDR_TYPE_POST_PROCESS_FXAA ) {
// Since we require OpenGL 3.2 we always have support for GLSL 130
sflags << "#define FXAA_GLSL_120 0\n";
sflags << "#define FXAA_GLSL_130 1\n";
if (GLSL_version >= 400) {
// The gather function became part of the standard with GLSL 4.00
sflags << "#define FXAA_GATHER4_ALPHA 1\n";
}
switch (Gr_aa_mode) {
case AntiAliasMode::None:
sflags << "#define FXAA_QUALITY_PRESET 10\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_Low:
sflags << "#define FXAA_QUALITY_PRESET 12\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/8.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/16.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_Medium:
sflags << "#define FXAA_QUALITY_PRESET 26\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/12.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/24.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
case AntiAliasMode::FXAA_High:
sflags << "#define FXAA_QUALITY_PRESET 39\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD (1.0/15.0)\n";
sflags << "#define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/32.0)\n";
sflags << "#define FXAA_QUALITY_SUBPIX 0.33\n";
break;
}
}
}
@@ -933,17 +783,11 @@ bool opengl_post_init_shaders()
Cmdline_bloom_intensity = 0;
}
if (gr_is_fxaa_mode(Gr_aa_mode))
{
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0);
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0);
}
if (gr_is_smaa_mode(Gr_aa_mode)) {
// Precompile the SMAA shaders if enabled
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_EDGE, 0);
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, 0);
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, 0);
if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) < 0 ||
gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) < 0 ) {
Gr_aa_mode = AntiAliasMode::None;
fxaa_unavailable = true;
mprintf(("Error while compiling FXAA shaders. FXAA will be unavailable.\n"));
}
return true;
@@ -981,148 +825,6 @@ void opengl_setup_bloom_textures()
GL_state.BindFrameBuffer(0);
}
void setup_smaa_edges_resources()
{
glGenTextures(1, &Smaa_edges_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Smaa_edges_tex);
opengl_set_object_label(GL_TEXTURE, Smaa_edges_tex, "SMAA Edge detection texture");
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &Smaa_edge_detection_fb);
GL_state.BindFrameBuffer(Smaa_edge_detection_fb);
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_edge_detection_fb, "SMAA Edge detection framebuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_edges_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
void setup_smaa_blending_weight_resources()
{
glGenTextures(1, &Smaa_blend_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Smaa_blend_tex);
opengl_set_object_label(GL_TEXTURE, Smaa_blend_tex, "SMAA Blending weight calculation texture");
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &Smaa_blending_weight_fb);
GL_state.BindFrameBuffer(Smaa_blending_weight_fb);
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_blending_weight_fb, "SMAA Blending widght calculation framebuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_blend_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
void setup_smaa_neighborhood_blending_resources()
{
glGenTextures(1, &Smaa_output_tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(Smaa_output_tex);
opengl_set_object_label(GL_TEXTURE, Smaa_output_tex, "SMAA output texture");
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, Post_texture_width, Post_texture_height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenFramebuffers(1, &Smaa_neighborhood_blending_fb);
GL_state.BindFrameBuffer(Smaa_neighborhood_blending_fb);
opengl_set_object_label(GL_FRAMEBUFFER, Smaa_neighborhood_blending_fb, "SMAA neighborhood blending framebuffer");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Smaa_output_tex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
static GLuint load_smaa_texture(GLsizei width, GLsizei height, GLenum format, const uint8_t* pixels, const char* name)
{
GLuint tex;
glGenTextures(1, &tex);
GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(tex);
opengl_set_object_label(GL_TEXTURE, tex, name);
if (GLAD_GL_ARB_texture_storage) {
glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, format, Post_texture_width, Post_texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
nullptr);
}
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format == GL_RG8 ? GL_RG : GL_RED, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return tex;
}
static void setup_smaa_resources()
{
GL_state.PushFramebufferState();
Smaa_area_tex = load_smaa_texture(AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG8, areaTexBytes, "SMAA Area Texture");
Smaa_search_tex =
load_smaa_texture(SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_R8, searchTexBytes, "SMAA Search Texture");
setup_smaa_edges_resources();
setup_smaa_blending_weight_resources();
setup_smaa_neighborhood_blending_resources();
GL_state.PopFramebufferState();
}
// generate and test the framebuffer and textures that we are going to use
static bool opengl_post_init_framebuffer()
{
@@ -1142,10 +844,6 @@ static bool opengl_post_init_framebuffer()
opengl_setup_bloom_textures();
if (gr_is_smaa_mode(Gr_aa_mode)) {
setup_smaa_resources();
}
GL_state.BindFrameBuffer(0);
rval = true;
@@ -2,9 +2,6 @@
#ifndef _GROPENGLPOSTPROCESSING_H
#define _GROPENGLPOSTPROCESSING_H
#include "globalincs/pstypes.h"
#include "graphics/opengl/gropenglshader.h"
void opengl_post_process_init();
void opengl_post_process_shutdown();
+5 -30
View File
@@ -143,15 +143,6 @@ static opengl_shader_type_t GL_shader_types[] = {
{ SDR_TYPE_ROCKET_UI, "rocketui-v.sdr", "rocketui-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::COLOR, opengl_vert_attrib::TEXCOORD }, "libRocket UI" },
{ SDR_TYPE_POST_PROCESS_SMAA_EDGE, "smaa-edge-v.sdr", "smaa-edge-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Edge detection" },
{ SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT, "smaa-blend-v.sdr", "smaa-blend-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Blending weight calculation" },
{ SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING, "smaa-neighbour-v.sdr", "smaa-neighbour-f.sdr", nullptr,
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "SMAA Neighborhood Blending" },
};
// clang-format on
@@ -379,13 +370,11 @@ static SCP_string opengl_shader_get_header(shader_type type_id, int flags, bool
sflags << "#define HAS_GEOMETRY_SHADER\n";
}
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS ||
type_id == SDR_TYPE_POST_PROCESS_FXAA || type_id == SDR_TYPE_POST_PROCESS_SMAA_EDGE ||
type_id == SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT ||
type_id == SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING) {
if (type_id == SDR_TYPE_POST_PROCESS_MAIN || type_id == SDR_TYPE_POST_PROCESS_LIGHTSHAFTS || type_id == SDR_TYPE_POST_PROCESS_FXAA) {
// ignore looking for variants. main post process, lightshafts, and FXAA shaders need special headers to be hacked in
opengl_post_shader_header(sflags, type_id, flags);
} else {
}
else {
for (int i = 0; i < GL_num_shader_variants; ++i) {
opengl_shader_variant_t &variant = GL_shader_variants[i];
@@ -894,20 +883,6 @@ static void opengl_purge_shader_cache_type(const char* ext) {
SCP_string filter("*.");
filter += ext;
// Previously the cache files were stored in the mod directory. Since we have a better system now, those files
// should be cleaned out. This is only needed if we have a mod directory since otherwise we would delete the actual
// cache files
if (Cmdline_mod != nullptr && strlen(Cmdline_mod) > 0) {
SCP_vector<SCP_string> cache_files;
cf_get_file_list(cache_files, CF_TYPE_CACHE, filter.c_str(), CF_SORT_NONE, nullptr,
CF_LOCATION_TYPE_PRIMARY_MOD | CF_LOCATION_TYPE_SECONDARY_MODS);
for (auto& file : cache_files) {
cf_delete((file + "." + ext).c_str(), CF_TYPE_CACHE,
CF_LOCATION_TYPE_PRIMARY_MOD | CF_LOCATION_TYPE_SECONDARY_MODS);
}
}
SCP_vector<SCP_string> cache_files;
SCP_vector<file_list_info> file_info;
cf_get_file_list(cache_files, CF_TYPE_CACHE, filter.c_str(), CF_SORT_NONE, &file_info,
@@ -1003,7 +978,7 @@ GLint opengl_shader_get_attribute(opengl_vert_attrib::attrib_id attribute)
return Current_shader->program->getAttributeLocation(attribute);
}
void opengl_shader_set_passthrough(bool textured, bool hdr)
void opengl_shader_set_passthrough(bool textured)
{
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0));
@@ -1015,7 +990,7 @@ void opengl_shader_set_passthrough(bool textured, bool hdr)
Current_shader->program->Uniforms.setUniformi("alphaTexture", 0);
Current_shader->program->Uniforms.setUniformi("srgb", hdr ? 1 : 0);
Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0);
Current_shader->program->Uniforms.setUniformf("intensity", 1.0f);
Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold);
+1 -1
View File
@@ -164,7 +164,7 @@ void opengl_shader_compile_deferred_light_clear_shader();
void opengl_shader_compile_passthrough_shader();
void opengl_shader_set_passthrough(bool textured, bool hdr);
void opengl_shader_set_passthrough(bool textured = true);
void opengl_shader_set_default_material(bool textured, bool alpha, vec4* clr, float color_scale, uint32_t array_index, const material::clip_plane& clip_plane);
+1
View File
@@ -199,6 +199,7 @@ void opengl_tcache_flush()
extern void opengl_kill_all_render_targets();
void opengl_tex_array_storage(GLenum target, GLint levels, GLenum format, GLint width, GLint height, GLint frames);
void opengl_tcache_shutdown()
{
opengl_kill_all_render_targets();
-1
View File
@@ -87,7 +87,6 @@ void gr_opengl_get_bitmap_from_texture(void* data_out, int bitmap_num);
size_t opengl_export_render_target( int slot, int width, int height, int alpha, int num_mipmaps, ubyte *image_data );
void opengl_set_texture_target(GLenum target = GL_TEXTURE_2D);
void opengl_set_texture_face(GLenum face = GL_TEXTURE_2D);
void opengl_tex_array_storage(GLenum target, GLint levels, GLenum format, GLint width, GLint height, GLint frames);
int gr_opengl_tcache_set(int bitmap_handle, int bitmap_type, float *u_scale, float *v_scale, uint32_t *array_index, int stage = 0);
int gr_opengl_preload(int bitmap_num, int is_aabitmap);
+2 -3
View File
@@ -223,15 +223,14 @@ void ChttpGet::WorkerThread()
if(strnicmp("HTTP/",p,5)==0)
{
char *pcode;
pcode = strchr(p,' ');
if(pcode == nullptr)
pcode = strchr(p,' ')+1;
if(!pcode)
{
m_State = HTTP_STATE_UNKNOWN_ERROR;
fclose(LOCALFILE);
return;
}
pcode++;
pcode[3] = '\0';
irsp = atoi(pcode);
-8
View File
@@ -1422,10 +1422,6 @@ void process_player_ship_keys(int k)
}
}
//Cyborg17 - Linking this function to restart sound if needed. This is to avoid having to
//check for subspace every frame.
extern void game_start_subspace_ambient_sound();
/**
* Handler for when player hits 'ESC' during the game
*/
@@ -1452,10 +1448,6 @@ void game_do_end_mission_popup()
break;
case 2:
// Cyborg17 - best place to check for this *one* looping sound.
if (Game_subspace_effect) {
game_start_subspace_ambient_sound();
}
gameseq_post_event(GS_EVENT_ENTER_GAME);
break;
+5
View File
@@ -128,6 +128,11 @@ int jpeg_read_header(const char *real_filename, CFILE *img_cfp, int *w, int *h,
jpeg_file = img_cfp;
}
Assert( jpeg_file != NULL );
if (jpeg_file == NULL)
return JPEG_ERROR_READING;
// set the basic/default error code
Jpeg_Set_Error(JPEG_ERROR_NONE);
+1
View File
@@ -1592,6 +1592,7 @@ void labviewer_change_ship_lod(Tree* caller)
void labviewer_change_ship(Tree* caller)
{
Lab_selected_index = caller->GetSelectedItem()->GetData();
Lab_last_selected_object = caller->GetSelectedItem();
labviewer_change_ship_lod(caller);
+28 -33
View File
@@ -4045,7 +4045,7 @@ int parse_wing_create_ships( wing *wingp, int num_to_create, int force, int spec
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))
if (mission_parse_get_arrival_ship(name))
return 0;
// since this wing cannot arrive from this place, we need to mark the wing as destroyed and
@@ -5688,16 +5688,29 @@ bool parse_mission(mission *pm, int flags)
strcat_s(text, pm->name);
}
strcat_s(text, "\", and the current mod is \"");
strcat_s(text, "\", and the current mod root is \"");
if (Cmdline_mod == NULL || *Cmdline_mod == 0) {
strcat_s(text, "<retail default> ");
} else {
for (char *mod_token = Cmdline_mod; *mod_token != '\0'; mod_token += strlen(mod_token) + 1) {
strcat_s(text, mod_token);
strcat_s(text, " ");
// Try to find the first non-user, folder root and display that. Not ideal but better than nothing I guess...
// We go through all the specified mod roots and find the first non-user folder. If that does not exist then
// user folders will be considered next. If that also fails, a default value is used.
SCP_string modRoot = "<Unknown>";
for (const auto& consider_user : {false, true})
{
for (const auto& root : Cmdline_mod)
{
if (root.type != cfile::ModRootType::Folder)
{
continue;
}
if (root.user_location && !consider_user) {
continue;
}
modRoot = root.path;
}
}
strcat_s(text, modRoot.c_str());
strcpy(text + strlen(text) - 1, "\".)\n\n You can continue to load the mission, but it is quite likely that you will encounter a large number of mysterious errors. It is recommended that you either select a ");
strcat(text, (Game_mode & GM_CAMPAIGN_MODE) ? "campaign" : "mission");
@@ -5852,10 +5865,8 @@ bool post_process_mission()
sprintf(error_msg, "%s.\n\nIn sexpression: %s\n(Error appears to be: %s)", sexp_error_message(result), sexp_str.c_str(), Sexp_nodes[bad_node].text);
Warning(LOCATION, "%s", error_msg.c_str());
// syntax errors are recoverable in Fred but not FS
if (!Fred_running) {
return false;
}
// syntax errors are unrecoverable, so abort
return false;
}
}
}
@@ -6538,8 +6549,8 @@ p_object *mission_parse_get_arrival_ship(const char *name)
{
p_object *p_objp;
if (name == nullptr)
return nullptr;
if (name == NULL)
return NULL;
for (p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp))
{
@@ -6549,7 +6560,7 @@ p_object *mission_parse_get_arrival_ship(const char *name)
}
}
return nullptr;
return NULL;
}
/**
@@ -6575,22 +6586,6 @@ p_object *mission_parse_get_arrival_ship(ushort net_signature)
return NULL;
}
/**
* Because player ships remain on the arrival list (see parse_wing_create_ships), testing for yet-to-arrive by merely
* checking the list will produce false positives for player ships. So this function also checks whether the object was created.
*/
bool mission_check_ship_yet_to_arrive(const char *name)
{
p_object *p_objp = mission_parse_get_arrival_ship(name);
if (p_objp == nullptr)
return false;
if (p_objp->created_object != nullptr)
return false;
return true;
}
/**
* Sets the arrival location of a parse object according to the arrival location of the object.
* @return objnum of anchor ship if there is one, -1 otherwise.
@@ -6810,7 +6805,7 @@ int mission_did_ship_arrive(p_object *objp)
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))
if (mission_parse_get_arrival_ship(name))
return -1;
mission_parse_mark_non_arrival(objp); // Goober5000
@@ -7197,7 +7192,7 @@ int mission_do_departure(object *objp, bool goal_is_to_warp)
name = Parse_names[anchor];
// see if ship is yet to arrive. If so, then warp.
if (mission_check_ship_yet_to_arrive(name))
if (mission_parse_get_arrival_ship(name))
{
mprintf(("Anchor ship %s hasn't arrived yet! Trying to warp...\n", name));
goto try_to_warp;
-1
View File
@@ -482,7 +482,6 @@ extern char Neb2_texture_name[MAX_FILENAME_LEN];
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);
int parse_create_object(p_object *objp);
+2 -2
View File
@@ -1265,7 +1265,7 @@ void wl_load_icons(int weapon_class)
icon = &Wl_icons[weapon_class];
if(!Cmdline_weapon_choice_3d || (wip->render_type == WRT_LASER && !strlen(wip->tech_model)) || strlen(Weapon_info[weapon_class].icon_filename) )
if(!Cmdline_weapon_choice_3d || (wip->render_type == WRT_LASER && !strlen(wip->tech_model)))
{
first_frame = bm_load_animation(Weapon_info[weapon_class].icon_filename, &num_frames, nullptr, nullptr, nullptr, false, CF_TYPE_INTERFACE);
@@ -1276,7 +1276,7 @@ void wl_load_icons(int weapon_class)
multi_send_anti_timeout_ping();
if ( (first_frame == -1 && icon->model_index == -1) || (Cmdline_weapon_choice_3d && !strlen(wip->anim_filename)) )
if ( first_frame == -1 && icon->model_index == -1)
{
if(strlen(wip->tech_model))
{
-78
View File
@@ -48,12 +48,6 @@ SCP_string Window_icon_path;
bool Disable_built_in_translations;
bool Weapon_shockwaves_respect_huge;
bool Using_in_game_options;
std::tuple<ubyte, ubyte, ubyte> Arc_color_damage_p1;
std::tuple<ubyte, ubyte, ubyte> Arc_color_damage_p2;
std::tuple<ubyte, ubyte, ubyte> Arc_color_damage_s1;
std::tuple<ubyte, ubyte, ubyte> Arc_color_emp_p1;
std::tuple<ubyte, ubyte, ubyte> Arc_color_emp_p2;
std::tuple<ubyte, ubyte, ubyte> Arc_color_emp_s1;
void parse_mod_table(const char *filename)
{
@@ -273,72 +267,6 @@ void parse_mod_table(const char *filename)
mprintf(("Game Settings Table: $BMPMAN Slot Limit is deprecated and should be removed. It is not needed anymore.\n"));
}
if (optional_string("$EMP Arc Color:")) {
if (optional_string("+Primary Color Option 1:")) {
int rgb[3];
stuff_int_list(rgb, 3);
if ((rgb[0] >= 0 && rgb[0] <= 255) && (rgb[1] >= 0 && rgb[1] <= 255) && (rgb[2] >= 0 && rgb[2] <= 255)) {
Arc_color_emp_p1 = std::make_tuple(static_cast<ubyte>(rgb[0]), static_cast<ubyte>(rgb[1]), static_cast<ubyte>(rgb[2]));
} else {
error_display(0, "$EMP Arc Color: +Primary Color Option 1 is %i, %i, %i. "
"One or more of these values is not within the range of 0-255. Assuming default color.", rgb[0], rgb[1], rgb[2]);
}
}
if (optional_string("+Primary Color Option 2:")) {
int rgb[3];
stuff_int_list(rgb, 3);
if ((rgb[0] >= 0 && rgb[0] <= 255) && (rgb[1] >= 0 && rgb[1] <= 255) && (rgb[2] >= 0 && rgb[2] <= 255)) {
Arc_color_emp_p2 = std::make_tuple(static_cast<ubyte>(rgb[0]), static_cast<ubyte>(rgb[1]), static_cast<ubyte>(rgb[2]));
} else {
error_display(0, "$EMP Arc Color: +Primary Color Option 2 is %i, %i, %i. "
"One or more of these values is not within the range of 0-255. Assuming default color.", rgb[0], rgb[1], rgb[2]);
}
}
if (optional_string("+Secondary Color Option 1:")) {
int rgb[3];
stuff_int_list(rgb, 3);
if ((rgb[0] >= 0 && rgb[0] <= 255) && (rgb[1] >= 0 && rgb[1] <= 255) && (rgb[2] >= 0 && rgb[2] <= 255)) {
Arc_color_emp_s1 = std::make_tuple(static_cast<ubyte>(rgb[0]), static_cast<ubyte>(rgb[1]), static_cast<ubyte>(rgb[2]));
} else {
error_display(0,"$EMP Arc Color: +Secondary Color Option 1 is %i, %i, %i. "
"One or more of these values is not within the range of 0-255. Assuming default color.", rgb[0], rgb[1], rgb[2]);
}
}
}
if (optional_string("$Damage Arc Color:")) {
if (optional_string("+Primary Color Option 1:")) {
int rgb[3];
stuff_int_list(rgb, 3);
if ((rgb[0] >= 0 && rgb[0] <= 255) && (rgb[1] >= 0 && rgb[1] <= 255) && (rgb[2] >= 0 && rgb[2] <= 255)) {
Arc_color_damage_p1 = std::make_tuple(static_cast<ubyte>(rgb[0]), static_cast<ubyte>(rgb[1]), static_cast<ubyte>(rgb[2]));
} else {
error_display(0, "Damage Arc Color: +Primary Color Option 1 is %i, %i, %i. "
"One or more of these values is not within the range of 0-255. Assuming default color.", rgb[0], rgb[1], rgb[2]);
}
}
if (optional_string("+Primary Color Option 2:")) {
int rgb[3];
stuff_int_list(rgb, 3);
if ((rgb[0] >= 0 && rgb[0] <= 255) && (rgb[1] >= 0 && rgb[1] <= 255) && (rgb[2] >= 0 && rgb[2] <= 255)) {
Arc_color_damage_p2 = std::make_tuple(static_cast<ubyte>(rgb[0]), static_cast<ubyte>(rgb[1]), static_cast<ubyte>(rgb[2]));
} else {
error_display(0, "$Damage Arc Color: +Primary Color Option 2 is %i, %i, %i. "
"One or more of these values is not within the range of 0-255. Assuming default color.", rgb[0], rgb[1], rgb[2]);
}
}
if (optional_string("+Secondary Color Option 1:")) {
int rgb[3];
stuff_int_list(rgb, 3);
if ((rgb[0] >= 0 && rgb[0] <= 255) && (rgb[1] >= 0 && rgb[1] <= 255) && (rgb[2] >= 0 && rgb[2] <= 255)) {
Arc_color_damage_s1 = std::make_tuple(static_cast<ubyte>(rgb[0]), static_cast<ubyte>(rgb[1]), static_cast<ubyte>(rgb[2]));
} else {
error_display(0, "$Damage Arc Color: +Secondary Color Option 1 is %i, %i, %i. "
"One or more of these values is not within the range of 0-255. Assuming default color.", rgb[0], rgb[1], rgb[2]);
}
}
}
optional_string("#NETWORK SETTINGS");
if (optional_string("$FS2NetD port:")) {
@@ -557,10 +485,4 @@ void mod_table_reset() {
Disable_built_in_translations = false;
Weapon_shockwaves_respect_huge = false;
Using_in_game_options = false;
Arc_color_damage_p1 = std::make_tuple(static_cast<ubyte>(64), static_cast<ubyte>(64), static_cast<ubyte>(225));
Arc_color_damage_p2 = std::make_tuple(static_cast<ubyte>(128), static_cast<ubyte>(128), static_cast<ubyte>(255));
Arc_color_damage_s1 = std::make_tuple(static_cast<ubyte>(200), static_cast<ubyte>(200), static_cast<ubyte>(255));
Arc_color_emp_p1 = std::make_tuple(static_cast<ubyte>(64), static_cast<ubyte>(64), static_cast<ubyte>(5));
Arc_color_emp_p2 = std::make_tuple(static_cast<ubyte>(128), static_cast<ubyte>(128), static_cast<ubyte>(10));
Arc_color_emp_s1 = std::make_tuple(static_cast<ubyte>(255), static_cast<ubyte>(255), static_cast<ubyte>(10));
}
-6
View File
@@ -39,12 +39,6 @@ extern SCP_string Window_icon_path;
extern bool Disable_built_in_translations;
extern bool Weapon_shockwaves_respect_huge;
extern bool Using_in_game_options;
extern std::tuple<ubyte, ubyte, ubyte> Arc_color_damage_p1;
extern std::tuple<ubyte, ubyte, ubyte> Arc_color_damage_p2;
extern std::tuple<ubyte, ubyte, ubyte> Arc_color_damage_s1;
extern std::tuple<ubyte, ubyte, ubyte> Arc_color_emp_p1;
extern std::tuple<ubyte, ubyte, ubyte> Arc_color_emp_p2;
extern std::tuple<ubyte, ubyte, ubyte> Arc_color_emp_s1;
void mod_table_init();
+2 -8
View File
@@ -1325,14 +1325,8 @@ int model_collide(mc_info *mc_info_obj)
// Check all the the highest detail model polygons and subobjects for intersections
// Don't check it or its children if it is destroyed
if ( Mc_pmi ) {
if ( !Mc_pmi->submodel[Mc_pm->detail[0]].blown_off ) {
mc_check_subobj(Mc_pm->detail[0]);
}
} else {
if ( !Mc_pm->submodel[Mc_pm->detail[0]].blown_off ) {
mc_check_subobj(Mc_pm->detail[0]);
}
if (!Mc_pm->submodel[Mc_pm->detail[0]].blown_off) {
mc_check_subobj( Mc_pm->detail[0] );
}
}
+1 -3
View File
@@ -4422,15 +4422,13 @@ void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *
}
polymodel_instance *pmi = model_get_instance(model_instance_num);
submodel_instance *child_submodel_instance = &pmi->submodel[pm->detail[0]];
int i = child_submodel->first_child;
while ( i >= 0 ) {
child_submodel = &pm->submodel[i];
child_submodel_instance = &pmi->submodel[i];
// Don't check it or its children if it is destroyed or it is a replacement (non-moving)
if ( !child_submodel_instance->blown_off && (child_submodel->i_replace == -1) && !child_submodel->no_collisions && !child_submodel->nocollide_this_only) {
if ( !child_submodel->blown_off && (child_submodel->i_replace == -1) && !child_submodel->no_collisions && !child_submodel->nocollide_this_only) {
// Only look for submodels that rotate or intrinsic-rotate
if (child_submodel->movement_type == MOVEMENT_TYPE_ROT || child_submodel->movement_type == MOVEMENT_TYPE_INTRINSIC_ROTATE) {
+15 -10
View File
@@ -20,7 +20,6 @@
#include "graphics/uniforms.h"
#include "io/timer.h"
#include "math/staticrand.h"
#include "mod_table/mod_table.h"
#include "model/modelrender.h"
#include "nebula/neb.h"
#include "particle/particle.h"
@@ -832,6 +831,13 @@ void model_render_add_lightning( model_draw_list *scene, model_render_params* in
float width = 0.9f;
color primary, secondary;
const int AR = 64;
const int AG = 64;
const int AB = 5;
const int AR2 = 128;
const int AG2 = 128;
const int AB2 = 10;
Assert( sm->num_arcs > 0 );
if ( interp->get_model_flags() & MR_SHOW_OUTLINE_PRESET ) {
@@ -858,23 +864,23 @@ void model_render_add_lightning( model_draw_list *scene, model_render_params* in
// "normal", FreeSpace 1 style arcs
case MARC_TYPE_NORMAL:
if ( (rand()>>4) & 1 ) {
gr_init_color(&primary, std::get<0>(Arc_color_damage_p1), std::get<1>(Arc_color_damage_p1), std::get<2>(Arc_color_damage_p1));
gr_init_color(&primary, 64, 64, 255);
} else {
gr_init_color(&primary, std::get<0>(Arc_color_damage_p2), std::get<1>(Arc_color_damage_p2), std::get<2>(Arc_color_damage_p2));
gr_init_color(&primary, 128, 128, 255);
}
gr_init_color(&primary, std::get<0>(Arc_color_damage_s1), std::get<1>(Arc_color_damage_s1), std::get<2>(Arc_color_damage_s1));
gr_init_color(&secondary, 200, 200, 255);
break;
// "EMP" style arcs
case MARC_TYPE_EMP:
if ( (rand()>>4) & 1 ) {
gr_init_color(&primary, std::get<0>(Arc_color_emp_p1), std::get<1>(Arc_color_emp_p1), std::get<2>(Arc_color_emp_p1));
gr_init_color(&primary, AR, AG, AB);
} else {
gr_init_color(&primary, std::get<0>(Arc_color_emp_p2), std::get<1>(Arc_color_emp_p2), std::get<2>(Arc_color_emp_p2));
gr_init_color(&primary, AR2, AG2, AB2);
}
gr_init_color(&primary, std::get<0>(Arc_color_emp_s1), std::get<1>(Arc_color_emp_s1), std::get<2>(Arc_color_emp_s1));
gr_init_color(&secondary, 255, 255, 10);
break;
default:
@@ -2534,8 +2540,7 @@ void model_render_debug(int model_num, matrix *orient, vec3d * pos, uint flags,
gr_zbuffer_set(save_gr_zbuffering_mode);
}
void model_render_immediate(model_render_params* render_info, int model_num, matrix* orient, vec3d* pos, int render,
bool sort)
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d * pos, int render, bool sort)
{
model_draw_list model_list;
@@ -2577,7 +2582,7 @@ void model_render_immediate(model_render_params* render_info, int model_num, mat
}
}
void model_render_queue(model_render_params* interp, model_draw_list* scene, int model_num, matrix* orient, vec3d* pos)
void model_render_queue(model_render_params *interp, model_draw_list *scene, int model_num, matrix *orient, vec3d *pos)
{
int i;
+2 -4
View File
@@ -296,10 +296,8 @@ public:
void reset();
};
void model_render_immediate(model_render_params* render_info, int model_num, matrix* orient, vec3d* pos,
int render = MODEL_RENDER_ALL, bool sort = true);
void model_render_queue(model_render_params* render_info, model_draw_list* scene, int model_num, matrix* orient,
vec3d* pos);
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d * pos, int render = MODEL_RENDER_ALL, bool sort = true);
void model_render_queue(model_render_params *render_info, model_draw_list* scene, int model_num, matrix *orient, vec3d *pos);
void submodel_render_immediate(model_render_params *render_info, int model_num, int submodel_num, matrix *orient, vec3d * pos);
void submodel_render_queue(model_render_params *render_info, model_draw_list *scene, int model_num, int submodel_num, matrix *orient, vec3d * pos);
void model_render_buffers(model_draw_list* scene, model_material *rendering_material, model_render_params* interp, vertex_buffer *buffer, polymodel *pm, int mn, int detail_level, uint tmap_flags);
+2 -2
View File
@@ -1370,8 +1370,8 @@ void process_accept_player_data( ubyte *data, header *hinfo )
if ( stop == APD_END_DATA ) {
// if joining a game automatically, set the connect address to NULl so we don't try and
// do this next time we enter a game
if (Cmdline_connect_addr != NULL) {
Cmdline_connect_addr = NULL;
if (!Cmdline_connect_addr.empty()) {
Cmdline_connect_addr.clear();
}
// send my stats to the server if I'm not in observer mode
+23 -26
View File
@@ -945,8 +945,7 @@ void multi_join_game_init()
// if starting a network game, then go to the create game screen
if ( Cmdline_start_netgame ) {
multi_join_create_game();
} else if ( Cmdline_connect_addr != NULL ) {
char *p;
} else if ( !Cmdline_connect_addr.empty() ) {
short port_num;
int ip_addr;
@@ -956,13 +955,11 @@ void multi_join_game_init()
// create the address, looking out for port number at the end
port_num = DEFAULT_GAME_PORT;
p = strrchr(Cmdline_connect_addr, ':');
if ( p ) {
*p = '\0';
p++;
port_num = (short)atoi(p);
const auto number_end = Cmdline_connect_addr.find(':');
if ( number_end != SCP_string::npos ) {
port_num = (short)atoi(Cmdline_connect_addr.substr(0, number_end).c_str());
}
ip_addr = inet_addr(Cmdline_connect_addr);
ip_addr = inet_addr(Cmdline_connect_addr.c_str());
memcpy(Multi_autojoin_addr.addr, &ip_addr, 4);
Multi_autojoin_addr.port = port_num;
@@ -1006,7 +1003,7 @@ void multi_join_game_do_frame()
}
// when joining a network game, wait for the server query to come back, and then join the game
if ( Cmdline_connect_addr != NULL ) {
if ( !Cmdline_connect_addr.empty() ) {
int rval;
if ( !Multi_did_autojoin ) {
@@ -1014,7 +1011,7 @@ void multi_join_game_do_frame()
if ( rval == 0 ) {
// cancel was hit. Send the user back to the main hall
gameseq_post_event(GS_EVENT_MAIN_MENU);
Cmdline_connect_addr = NULL; // reset this value.
Cmdline_connect_addr.clear(); // reset this value.
}
// when we get here, we have the data -- join the game.
@@ -2270,7 +2267,7 @@ void multi_sg_select_rank_default();
// function which takes a rank name and returns the index. Useful for commandline options
// for above and below rank. We return the index of the rank in the Ranks[] array. If
// the rank isn't found, we return -1
int multi_start_game_rank_from_name( char *rank ) {
int multi_start_game_rank_from_name( const char *rank ) {
int i;
for ( i = 0; i <= MAX_FREESPACE2_RANK; i++ ) {
@@ -2355,8 +2352,8 @@ void multi_start_game_init()
// if starting a netgame, set the name of the game and any other options that are appropriate
if ( Cmdline_start_netgame ) {
if ( Cmdline_game_name != NULL ) {
strcpy_s( Multi_sg_netgame->name, Cmdline_game_name );
if ( !Cmdline_game_name.empty() ) {
strcpy_s( Multi_sg_netgame->name, Cmdline_game_name.c_str() );
Multi_sg_game_name.set_text(Multi_sg_netgame->name);
}
@@ -2366,21 +2363,21 @@ void multi_start_game_init()
Multi_sg_netgame->mode = NG_MODE_CLOSED;
} else if ( Cmdline_restricted_game ) {
Multi_sg_netgame->mode = NG_MODE_RESTRICTED;
} else if ( Cmdline_game_password != NULL ) {
} else if ( !Cmdline_game_password.empty() ) {
Multi_sg_netgame->mode = NG_MODE_PASSWORD;
strcpy_s(Multi_sg_netgame->passwd, Cmdline_game_password);
strcpy_s(Multi_sg_netgame->passwd, Cmdline_game_password.c_str());
Multi_sg_game_passwd.set_text(Multi_sg_netgame->passwd);
}
// deal with rank above and rank below
if ( (Cmdline_rank_above != NULL) || (Cmdline_rank_below != NULL) ) {
if ( (!Cmdline_rank_above.empty()) || (!Cmdline_rank_below.empty()) ) {
int rank;
char *rank_str;
const char *rank_str;
if ( Cmdline_rank_above != NULL ) {
rank_str = Cmdline_rank_above;
if ( !Cmdline_rank_above.empty() ) {
rank_str = Cmdline_rank_above.c_str();
} else {
rank_str = Cmdline_rank_below;
rank_str = Cmdline_rank_below.c_str();
}
// try and get the rank index from the name -- if found, then set the rank base
@@ -2391,7 +2388,7 @@ void multi_start_game_init()
Multi_sg_netgame->rank_base = Multi_sg_rank_select;
// now an arbitrary decision
if ( Cmdline_rank_above != NULL ) {
if ( !Cmdline_rank_above.empty() ) {
Multi_sg_netgame->mode = NG_MODE_RANK_ABOVE;
} else {
Multi_sg_netgame->mode = NG_MODE_RANK_BELOW;
@@ -3647,7 +3644,7 @@ void multi_create_game_do()
//DTP CHECK ALMISSION FLAG HERE AND SKIP THE BITMAP LOADING PROGRESS
//SINCE WE ALREADY HAVE A MISSION SELECTED IF THIS MISSION IS A VALID MULTIPLAYER MISSION
//IF NOT A VALID MULTIPLAYER MISSION CONTINUE LOADING, MAYBE CALL POPUP.
if ((Cmdline_almission) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)) { //
if ((!Cmdline_almission.empty()) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)) { //
multi_create_list_do(); //uhm here because off, hehe, my mind is failing right now
// DTP Var section for the is mission multi player Check.
@@ -3655,7 +3652,7 @@ void multi_create_game_do()
char mission_name[NAME_LENGTH+1];
int flags;
char *filename;
filename = cf_add_ext( Cmdline_almission, FS_MISSION_FILE_EXT ); //DTP ADD EXTENSION needed next line
filename = cf_add_ext( Cmdline_almission.c_str(), FS_MISSION_FILE_EXT ); //DTP ADD EXTENSION needed next line
flags = mission_parse_is_multi(filename, mission_name); //DTP flags will set if mission is multi
if (flags) { //only continue if mission is multiplayer mission
@@ -3663,7 +3660,7 @@ void multi_create_game_do()
ng = &Netgame;
char almissionname[256]; // needed, for the strncpy below
strncpy(almissionname, Cmdline_almission,MAX_FILENAME_LEN); //DTP; copying name from cmd_almission line
strncpy(almissionname, Cmdline_almission.c_str(), MAX_FILENAME_LEN); //DTP; copying name from cmd_almission line
Netgame.options.respawn = 99; //override anything //for debugging, i often forget this.
ng->respawn = Netgame.options.respawn;
@@ -3676,13 +3673,13 @@ void multi_create_game_do()
Multi_sync_mode = MULTI_SYNC_PRE_BRIEFING; //DTP must be set before a call to gameseq_post_event(GS_EVENT_MULTI_MISSION_SYNC) is done as it is below.
gameseq_post_event(GS_EVENT_MULTI_MISSION_SYNC);//DTP STart game
Cmdline_almission = NULL; // we don't want to autoload anymore do we, we will be able to quit. halleluja. Startgame has already been disabled, so no need to turn of "Cmdline_start_netgame"
Cmdline_almission.clear(); // we don't want to autoload anymore do we, we will be able to quit. halleluja. Startgame has already been disabled, so no need to turn of "Cmdline_start_netgame"
return; // we don't need to check or set regarding ships/weapons anything as we are already progressing into mission so return
}
else {
popup(PF_BODY_BIG | PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR(" Not a multi player-mission",9999)); //DTP startgame popup pilot error
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
Cmdline_almission = NULL; //DTP make sure this gets nullified.
Cmdline_almission.clear(); //DTP make sure this gets nullified.
}
}
+2 -2
View File
@@ -3263,7 +3263,7 @@ void multi_spew_pxo_checksums(int max_files, const char *outfile)
char filename[65] = { 0 };
char gametype[32] = { 0 };
size_t offset = 0;
char *p = NULL;
const char *p = nullptr;
// allocate filename space
file_names = (char**)vm_malloc(sizeof(char*) * max_files);
@@ -3285,7 +3285,7 @@ void multi_spew_pxo_checksums(int max_files, const char *outfile)
if (out == NULL)
goto Done;
p = Cmdline_spew_mission_crcs;
p = Cmdline_spew_mission_crcs.c_str();
while (*p && (offset < sizeof(description))) {
if (*p == '"') {
+3 -3
View File
@@ -1993,17 +1993,17 @@ unsigned int psnet_ras_status()
return INADDR_ANY;
}
pRasEnumConnections = (DWORD (__stdcall *)(LPRASCONN, LPDWORD, LPDWORD))(void*)GetProcAddress(ras_handle, "RasEnumConnectionsA");
pRasEnumConnections = (DWORD (__stdcall *)(LPRASCONN, LPDWORD, LPDWORD))GetProcAddress(ras_handle, "RasEnumConnectionsA");
if (!pRasEnumConnections) {
FreeLibrary( ras_handle );
return INADDR_ANY;
}
pRasGetConnectStatus = (DWORD (__stdcall *)(HRASCONN, LPRASCONNSTATUS))(void*)GetProcAddress(ras_handle, "RasGetConnectStatusA");
pRasGetConnectStatus = (DWORD (__stdcall *)(HRASCONN, LPRASCONNSTATUS))GetProcAddress(ras_handle, "RasGetConnectStatusA");
if (!pRasGetConnectStatus) {
FreeLibrary( ras_handle );
return INADDR_ANY;
}
pRasGetProjectionInfo = (DWORD (__stdcall *)(HRASCONN, RASPROJECTION, LPVOID, LPDWORD))(void*)GetProcAddress(ras_handle, "RasGetProjectionInfoA");
pRasGetProjectionInfo = (DWORD (__stdcall *)(HRASCONN, RASPROJECTION, LPVOID, LPDWORD))GetProcAddress(ras_handle, "RasGetProjectionInfoA");
if (!pRasGetProjectionInfo) {
FreeLibrary( ras_handle );
return INADDR_ANY;
+7 -7
View File
@@ -111,7 +111,7 @@ char title_str[512];
static HWND Multi_gen_dialog = NULL; // the dialog itself
// dialog proc for this dialog
INT_PTR CALLBACK std_gen_dialog_proc(HWND /*hwndDlg*/, UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
BOOL CALLBACK std_gen_dialog_proc(HWND /*hwndDlg*/, UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
{
switch(uMsg){
case WM_INITDIALOG:
@@ -483,7 +483,7 @@ int std_connect_lindex_to_npindex(int index)
}
// message handler for the connect tab
INT_PTR CALLBACK connect_proc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
BOOL CALLBACK connect_proc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg){
// initialize the dialog
@@ -1016,7 +1016,7 @@ HTREEITEM std_multi_get_goal_item(char *goal_string,int type)
}
// message handler for the multiplayer tab
INT_PTR CALLBACK multi_proc(HWND hwndDlg,UINT uMsg,WPARAM /*wParam*/,LPARAM lParam)
BOOL CALLBACK multi_proc(HWND hwndDlg,UINT uMsg,WPARAM /*wParam*/,LPARAM lParam)
{
switch(uMsg){
// initialize the page
@@ -1271,7 +1271,7 @@ int std_pinfo_player_is_active(net_player *p)
}
// message handler for the player info tab
INT_PTR CALLBACK player_info_proc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
BOOL CALLBACK player_info_proc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
int player_num;
char callsign[40];
@@ -1453,7 +1453,7 @@ void std_gs_init_godstuff_controls()
}
// message handler for the godstuff tab
INT_PTR CALLBACK godstuff_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
BOOL CALLBACK godstuff_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
@@ -1607,7 +1607,7 @@ void std_debug_init_debug_controls(HWND hwndDlg)
}
// message handler for the godstuff tab
INT_PTR CALLBACK debug_proc(HWND hwndDlg,UINT uMsg,WPARAM /*wParam*/,LPARAM lParam)
BOOL CALLBACK debug_proc(HWND hwndDlg,UINT uMsg,WPARAM /*wParam*/,LPARAM lParam)
{
switch(uMsg){
// initialize the dialog
@@ -2343,7 +2343,7 @@ static void standalone_do_systray(int mode)
}
// just like the osapi version for the nonstandalone mode of FreeSpace
DWORD standalone_process(LPVOID /*lparam*/)
DWORD standalone_process(WORD /*lparam*/)
{
MSG msg;
+1 -1
View File
@@ -130,7 +130,7 @@ namespace
}
userSIDInitialized = true;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1400
#if _MSC_VER >= 1400
if (userSIDValid)
{
if (needsWOW64())
+1132 -2005
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1170,7 +1170,7 @@ extern int get_sexp_main(void); // Returns start node
extern int run_sexp(const char* sexpression); // debug and lua sexps
extern int stuff_sexp_variable_list();
extern int eval_sexp(int cur_node, int referenced_node = -1);
extern int eval_num(int n, bool &is_nan, bool &is_nan_forever);
extern int eval_num(int n);
extern bool is_sexp_true(int cur_node, int referenced_node = -1);
extern int query_operator_return_type(int op);
extern int query_operator_argument_type(int op, int argnum);
+2 -3
View File
@@ -124,10 +124,9 @@ luacpp::LuaValue LuaSEXP::sexpToLua(int node, int argnum) const {
return LuaValue::createValue(_action.getLuaState(), value);
}
case OPF_NUMBER: {
bool is_nan, is_nan_forever;
auto res = eval_num(node, is_nan, is_nan_forever);
auto res = eval_num(node);
float value;
if (is_nan || is_nan_forever) {
if (res == SEXP_NAN || res == SEXP_NAN_FOREVER) {
value = std::numeric_limits<float>::quiet_NaN();
} else {
value = (float) res;
+1 -1
View File
@@ -850,7 +850,7 @@ void physics_apply_shock(vec3d *direction_vec, float pressure, physics_info *pi,
vm_vec_normalize_safe ( direction_vec );
area.xyz.x = (max->xyz.y - min->xyz.y) * (max->xyz.z - min->xyz.z);
area.xyz.x = (max->xyz.y - min->xyz.z) * (max->xyz.z - min->xyz.z);
area.xyz.y = (max->xyz.x - min->xyz.x) * (max->xyz.z - min->xyz.z);
area.xyz.z = (max->xyz.x - min->xyz.x) * (max->xyz.y - min->xyz.y);
+1 -1
View File
@@ -128,7 +128,7 @@ class pilotfile {
// --------------------------------------------------------------------
// PLR specific
// --------------------------------------------------------------------
void plr_reset_data(bool reset_all);
void plr_reset_data();
void plr_close();
void plr_read_flags();
+4 -10
View File
@@ -682,7 +682,7 @@ void pilotfile::plr_write_settings()
handler->endSectionWrite();
}
void pilotfile::plr_reset_data(bool reset_all)
void pilotfile::plr_reset_data()
{
// internals
m_have_flags = false;
@@ -691,11 +691,7 @@ void pilotfile::plr_reset_data(bool reset_all)
m_data_invalid = false;
// set all the entries in the control config arrays to -1 (undefined)
// Cyborg17 - clear_all is false when we are just trying to verify the file, but true when we load the whole thing.
// Otherwise, we can end up getting rid of a pilot's controls by accident.
if (reset_all) {
control_config_clear();
}
control_config_clear();
// init stats
p->stats.init();
@@ -801,8 +797,7 @@ bool pilotfile::load_player(const char* callsign, player* _p, bool force_binary)
mprintf(("PLR => Loading '%s' with version %d...\n", filename.c_str(), version));
//true resets everything, false sets up file verify.
plr_reset_data(true);
plr_reset_data();
// the point of all this: read in the PLR contents
handler->beginSectionRead();
@@ -1021,8 +1016,7 @@ bool pilotfile::verify(const char *fname, int *rank, char *valid_language)
mprintf(("PLR => Verifying '%s' with version %d...\n", filename.c_str(), version));
// true resets everything, false sets up file verify.
plr_reset_data(false);
plr_reset_data();
bool have_flags = false;
bool have_info = false;
+25 -42
View File
@@ -2,14 +2,14 @@
//
#include "scripting/ade.h"
#include "ade_api.h"
#include "def_files/def_files.h"
#include "mod_table/mod_table.h"
#include "scripting/lua/LuaFunction.h"
#include "ship/ship.h"
#include "ade.h"
#include "ade_api.h"
#include "ade_args.h"
#include "def_files/def_files.h"
#include "globalincs/version.h"
#include "mod_table/mod_table.h"
#include "scripting/api/objs/asteroid.h"
#include "scripting/api/objs/beam.h"
#include "scripting/api/objs/debris.h"
@@ -17,8 +17,6 @@
#include "scripting/api/objs/ship.h"
#include "scripting/api/objs/waypoint.h"
#include "scripting/api/objs/weapon.h"
#include "scripting/lua/LuaFunction.h"
#include "ship/ship.h"
namespace {
using namespace scripting;
@@ -279,12 +277,6 @@ const ade_table_entry& ade_manager::getEntry(size_t idx) const {
ade_table_entry::ade_table_entry() { memset(Subentries, 0, sizeof(Subentries)); }
//Think of n_mtb_ldx as the parent metatable
int ade_table_entry::SetTable(lua_State* L, int p_amt_ldx, int p_mtb_ldx) {
if (DeprecationVersion.isValid() &&
mod_supports_version(DeprecationVersion.major, DeprecationVersion.minor, DeprecationVersion.build)) {
// The deprecation mechanism. Do not set this or any of its children if we are past the deprecation version
return 1;
}
uint i;
int cleanup_items = 0;
int mtb_ldx = INT_MAX;
@@ -634,23 +626,12 @@ void ade_table_entry::OutputMeta(FILE *fp)
fprintf(fp, "<dd>%s</dd>\n", Description);
}
if (DeprecationVersion.isValid()) {
if (DeprecationMessage != nullptr) {
fprintf(fp, "<dd><b>Deprecated starting with version %d.%d.%d:</b> %s</dd>\n",
DeprecationVersion.major, DeprecationVersion.minor, DeprecationVersion.build,
DeprecationMessage);
} else {
fprintf(fp, "<dd><b>Deprecated starting with version %d.%d.%d.</b></dd>\n",
DeprecationVersion.major, DeprecationVersion.minor, DeprecationVersion.build);
}
}
//***Result: ReturnDescription
if (ReturnDescription != nullptr) {
fprintf(fp, "<dd><b>Returns:</b> %s<br>&nbsp;</dd>\n", ReturnDescription);
} else {
fputs("<dd><b>Returns:</b> Nothing<br>&nbsp;</dd>\n", fp);
}
//***Result: ReturnDescription
if(ReturnDescription != NULL) {
fprintf(fp, "<dd><b>Returns:</b> %s<br>&nbsp;</dd>\n", ReturnDescription);
} else {
fputs("<dd><b>Returns:</b> Nothing<br>&nbsp;</dd>\n", fp);
}
}
break;
default:
@@ -742,10 +723,13 @@ const char *ade_lib::GetName() const
return getTableEntry(GetIdx()).GetName();
}
ade_func::ade_func(const char* name, lua_CFunction func, const ade_lib_handle& parent, const char* args,
const char* desc, const char* ret_type, const char* ret_desc,
const gameversion::version& deprecation_version, const char* deprecation_message)
{
ade_func::ade_func(const char* name,
lua_CFunction func,
const ade_lib_handle& parent,
const char* args,
const char* desc,
const char* ret_type,
const char* ret_desc) {
Assertion(strcmp(name, "__gc") != 0, "__gc is a reserved function name! An API function may not use it!");
ade_table_entry ate;
@@ -758,16 +742,17 @@ ade_func::ade_func(const char* name, lua_CFunction func, const ade_lib_handle& p
ate.Description = desc;
ate.ReturnType = ret_type;
ate.ReturnDescription = ret_desc;
ate.DeprecationVersion = deprecation_version;
ate.DeprecationMessage = deprecation_message;
LibIdx = ade_manager::getInstance()->getEntry(parent.GetIdx()).AddSubentry(ate);
}
ade_virtvar::ade_virtvar(const char* name, lua_CFunction func, const ade_lib_handle& parent, const char* args,
const char* desc, const char* ret_type, const char* ret_desc,
const gameversion::version& deprecation_version, const char* deprecation_message)
{
ade_virtvar::ade_virtvar(const char* name,
lua_CFunction func,
const ade_lib_handle& parent,
const char* args,
const char* desc,
const char* ret_type,
const char* ret_desc) {
Assertion(strcmp(name, "__gc") != 0, "__gc is a reserved function name! An API function may not use it!");
ade_table_entry ate;
@@ -780,8 +765,6 @@ ade_virtvar::ade_virtvar(const char* name, lua_CFunction func, const ade_lib_han
ate.Description = desc;
ate.ReturnType = ret_type;
ate.ReturnDescription = ret_desc;
ate.DeprecationVersion = deprecation_version;
ate.DeprecationMessage = deprecation_message;
LibIdx = ade_manager::getInstance()->getEntry(parent.GetIdx()).AddSubentry(ate);
}
+2 -3
View File
@@ -5,7 +5,8 @@
#define FS2_OPEN_ADE_H
#include "globalincs/pstypes.h"
#include "globalincs/version.h"
#include "platformChecks.h"
#include <utility>
extern "C" {
#include <lauxlib.h>
@@ -122,8 +123,6 @@ class ade_table_entry {
const char* Description = nullptr;
const char* ReturnType = nullptr;
const char* ReturnDescription = nullptr;
gameversion::version DeprecationVersion;
const char* DeprecationMessage = nullptr;
//Subentries, of course
//WMC - I have HAD it with these motherfriendly vectors
+6 -57
View File
@@ -4,7 +4,6 @@
#ifndef FS2_OPEN_ADE_API_H_H
#define FS2_OPEN_ADE_API_H_H
#include "globalincs/version.h"
#include "scripting/ade.h"
#include "scripting/ade_args.h"
@@ -228,9 +227,8 @@ class ade_lib : public ade_lib_handle {
*/
class ade_func : public ade_lib_handle {
public:
ade_func(const char* name, lua_CFunction func, const ade_lib_handle& parent, const char* args, const char* desc,
const char* ret_type, const char* ret_desc, const gameversion::version& deprecation_version,
const char* deprecation_message);
ade_func(const char* name, lua_CFunction func, const ade_lib_handle& parent, const char* args = nullptr,
const char* desc = nullptr, const char* ret_type = nullptr, const char* ret_desc = nullptr);
};
/**
@@ -249,31 +247,7 @@ class ade_func : public ade_lib_handle {
*/
#define ADE_FUNC(name, parent, args, desc, ret_type, ret_desc) \
static int parent##_##name##_f(lua_State* L); \
::scripting::ade_func parent##_##name(#name, parent##_##name##_f, parent, args, desc, ret_type, ret_desc, \
::gameversion::version(), nullptr); \
static int parent##_##name##_f(lua_State* L)
/**
* @brief Declare a deprecated API function
*
* Immediately after this macro the function body should follow. This function is marked as deprecated and will be
* handled specially if the targetted engine version is higher than the specified version.
*
* @param name The name of the function, this may not be a string
* @param parent The library or object containing this function
* @param args Documentation for parameters of the function
* @param desc Description of what the function does
* @param ret_type The type of the returned value
* @param ret_desc Documentation for the returned value
* @param deprecate_version Version starting from which this function is deprecated.
* @param deprecated_msg Message for the deprecation notice. May be nullptr.
*
* @ingroup ade_api
*/
#define ADE_FUNC_DEPRECATED(name, parent, args, desc, ret_type, ret_desc, deprecate_version, deprecated_msg) \
static int parent##_##name##_f(lua_State* L); \
::scripting::ade_func parent##_##name(#name, parent##_##name##_f, parent, args, desc, ret_type, ret_desc, \
deprecate_version, deprecated_msg); \
::scripting::ade_func parent##_##name(#name, parent##_##name##_f, parent, args, desc, ret_type, ret_desc); \
static int parent##_##name##_f(lua_State* L)
/**
@@ -281,9 +255,8 @@ class ade_func : public ade_lib_handle {
*/
class ade_virtvar : public ade_lib_handle {
public:
ade_virtvar(const char* name, lua_CFunction func, const ade_lib_handle& parent, const char* args, const char* desc,
const char* ret_type, const char* ret_desc, const gameversion::version& deprecation_version,
const char* deprecation_message);
ade_virtvar(const char* name, lua_CFunction func, const ade_lib_handle& parent, const char* args = nullptr,
const char* desc = nullptr, const char* ret_type = nullptr, const char* ret_desc = nullptr);
};
/**
@@ -303,31 +276,7 @@ class ade_virtvar : public ade_lib_handle {
*/
#define ADE_VIRTVAR(name, parent, args, desc, ret_type, ret_desc) \
static int parent##_##name##_f(lua_State* L); \
::scripting::ade_virtvar parent##_##name(#name, parent##_##name##_f, parent, args, desc, ret_type, ret_desc, \
::gameversion::version(), nullptr); \
static int parent##_##name##_f(lua_State* L)
/**
* @brief Declare a deprecated API variable
*
* Use this to handle forms of type vec.x and vec['x']. Basically an indexer for a specific variable. Format string
* should be "o*%", where * is indexing value, and % is the value to set to when LUA_SETTTING_VAR is set
*
* @param name The name of the variable, this may not be a string
* @param parent The library or object containing this field
* @param args Documentation for the type of the value that may be assigned
* @param desc Description of what the variable does
* @param ret_type The type of the returned value
* @param ret_desc Documentation for the returned value
* @param deprecate_version Version starting from which this function is deprecated.
* @param deprecated_msg Message for the deprecation notice. May be nullptr.
*
* @ingroup ade_api
*/
#define ADE_VIRTVAR_DEPRECATED(name, parent, args, desc, ret_type, ret_desc, deprecate_version, deprecated_msg) \
static int parent##_##name##_f(lua_State* L); \
::scripting::ade_virtvar parent##_##name(#name, parent##_##name##_f, parent, args, desc, ret_type, ret_desc, \
deprecate_version, deprecated_msg); \
::scripting::ade_virtvar parent##_##name(#name, parent##_##name##_f, parent, args, desc, ret_type, ret_desc); \
static int parent##_##name##_f(lua_State* L)
/**
-138
View File
@@ -2,19 +2,16 @@
//
#include "graphics.h"
#include "scripting/api/objs/camera.h"
#include "scripting/api/objs/enums.h"
#include "scripting/api/objs/font.h"
#include "scripting/api/objs/model.h"
#include "scripting/api/objs/movie_player.h"
#include "scripting/api/objs/object.h"
#include "scripting/api/objs/particle.h"
#include "scripting/api/objs/streaminganim.h"
#include "scripting/api/objs/subsystem.h"
#include "scripting/api/objs/texture.h"
#include "scripting/api/objs/vecmath.h"
#include <asteroid/asteroid.h>
#include <camera/camera.h>
#include <debris/debris.h>
@@ -1591,140 +1588,5 @@ ADE_FUNC(openMovie, l_Graphics, "string name, boolean looping = false",
return ade_set_args(L, "o", l_MoviePlayer.Set(movie_player_h(std::move(player))));
}
ADE_FUNC(createPersistentParticle, l_Graphics,
"vector Position, vector Velocity, number Lifetime, number Radius, enumeration Type, [number Tracer "
"length=-1, boolean Reverse=false, texture Texture=Nil, object Attached Object=Nil]",
"Creates a persistent particle. Persistent variables are handled specially by the engine so that this "
"function can return a handle to the caller. Only use this if you absolutely need it. Use createParticle if "
"the returned handle is not required. Use PARTICLE_* enumerations for type."
"Reverse reverse animation, if one is specified"
"Attached object specifies object that Position will be (and always be) relative to.",
"particle", "Handle to the created particle")
{
particle::particle_info pi;
pi.type = particle::PARTICLE_DEBUG;
pi.optional_data = -1;
pi.attached_objnum = -1;
pi.attached_sig = -1;
pi.reverse = false;
// Need to consume tracer_length parameter but it isn't used anymore
float temp;
enum_h* type = nullptr;
bool rev = false;
object_h* objh = nullptr;
texture_h* texture = nullptr;
if (!ade_get_args(L, "ooffo|fboo", l_Vector.Get(&pi.pos), l_Vector.Get(&pi.vel), &pi.lifetime, &pi.rad,
l_Enum.GetPtr(&type), &temp, &rev, l_Texture.GetPtr(&texture), l_Object.GetPtr(&objh)))
return ADE_RETURN_NIL;
if (type != nullptr) {
switch (type->index) {
case LE_PARTICLE_DEBUG:
pi.type = particle::PARTICLE_DEBUG;
break;
case LE_PARTICLE_FIRE:
pi.type = particle::PARTICLE_FIRE;
break;
case LE_PARTICLE_SMOKE:
pi.type = particle::PARTICLE_SMOKE;
break;
case LE_PARTICLE_SMOKE2:
pi.type = particle::PARTICLE_SMOKE2;
break;
case LE_PARTICLE_BITMAP:
if (texture == nullptr || !texture->isValid()) {
LuaError(L, "Invalid texture specified for createParticle()!");
return ADE_RETURN_NIL;
} else {
pi.optional_data = texture->handle;
pi.type = particle::PARTICLE_BITMAP;
}
break;
}
}
if (rev)
pi.reverse = false;
if (objh != nullptr && objh->IsValid()) {
pi.attached_objnum = OBJ_INDEX(objh->objp);
pi.attached_sig = objh->objp->signature;
}
particle::WeakParticlePtr p = particle::createPersistent(&pi);
if (!p.expired())
return ade_set_args(L, "o", l_Particle.Set(particle_h(p)));
else
return ADE_RETURN_NIL;
}
ADE_FUNC(createParticle, l_Graphics,
"vector Position, vector Velocity, number Lifetime, number Radius, enumeration Type, [number Tracer "
"length=-1, boolean Reverse=false, texture Texture=Nil, object Attached Object=Nil]",
"Creates a non-persistent particle. Use PARTICLE_* enumerations for type."
"Reverse reverse animation, if one is specified"
"Attached object specifies object that Position will be (and always be) relative to.",
"boolean", "true if particle was created, false otherwise")
{
particle::particle_info pi;
pi.type = particle::PARTICLE_DEBUG;
pi.optional_data = -1;
pi.attached_objnum = -1;
pi.attached_sig = -1;
pi.reverse = false;
// Need to consume tracer_length parameter but it isn't used anymore
float temp;
enum_h* type = nullptr;
bool rev = false;
object_h* objh = nullptr;
texture_h* texture = nullptr;
if (!ade_get_args(L, "ooffo|fboo", l_Vector.Get(&pi.pos), l_Vector.Get(&pi.vel), &pi.lifetime, &pi.rad,
l_Enum.GetPtr(&type), &temp, &rev, l_Texture.GetPtr(&texture), l_Object.GetPtr(&objh)))
return ADE_RETURN_FALSE;
if (type != nullptr) {
switch (type->index) {
case LE_PARTICLE_DEBUG:
pi.type = particle::PARTICLE_DEBUG;
break;
case LE_PARTICLE_FIRE:
pi.type = particle::PARTICLE_FIRE;
break;
case LE_PARTICLE_SMOKE:
pi.type = particle::PARTICLE_SMOKE;
break;
case LE_PARTICLE_SMOKE2:
pi.type = particle::PARTICLE_SMOKE2;
break;
case LE_PARTICLE_BITMAP:
if (texture == nullptr || !texture->isValid()) {
LuaError(L, "Invalid texture specified for createParticle()!");
return ADE_RETURN_NIL;
} else {
pi.optional_data = texture->handle;
pi.type = particle::PARTICLE_BITMAP;
}
break;
}
}
if (rev)
pi.reverse = false;
if (objh != nullptr && objh->IsValid()) {
pi.attached_objnum = OBJ_INDEX(objh->objp);
pi.attached_sig = objh->objp->signature;
}
particle::create(&pi);
return ADE_RETURN_TRUE;
}
} // namespace api
} // namespace scripting
+6 -8
View File
@@ -56,14 +56,12 @@ ADE_FUNC(avdTest, l_Testing, NULL, "Test the AVD Physics code", NULL, NULL)
return ADE_RETURN_NIL;
}
ADE_FUNC_DEPRECATED(createParticle, l_Testing,
"vector Position, vector Velocity, number Lifetime, number Radius, enumeration Type, [number "
"Tracer length=-1, boolean Reverse=false, texture Texture=Nil, object Attached Object=Nil]",
"Creates a particle. Use PARTICLE_* enumerations for type."
"Reverse reverse animation, if one is specified"
"Attached object specifies object that Position will be (and always be) relative to.",
"particle", "Handle to the created particle", gameversion::version(19, 0, 0, 0),
"Not available in the testing library anymore. Use gr.createPersistentParticle instead.")
ADE_FUNC(createParticle, l_Testing, "vector Position, vector Velocity, number Lifetime, number Radius, enumeration Type, [number Tracer length=-1, boolean Reverse=false, texture Texture=Nil, object Attached Object=Nil]",
"Creates a particle. Use PARTICLE_* enumerations for type."
"Reverse reverse animation, if one is specified"
"Attached object specifies object that Position will be (and always be) relative to.",
"particle",
"Handle to the created particle")
{
particle::particle_info pi;
pi.type = particle::PARTICLE_DEBUG;
+46 -52
View File
@@ -757,11 +757,6 @@ static int lightningtype_match(char *p)
#define SHIP_MULTITEXT_LENGTH 4096
#define DEFAULT_DELTA_BANK_CONST 0.5f
const float DEFAULT_ASK_HELP_SHIELD_PERCENT = 0.1f; // percent shields at which ship will ask for help
const float DEFAULT_ASK_HELP_HULL_PERCENT = 0.3f; // percent hull at which ship will ask for help
const float AWACS_HELP_HULL_HI = 0.75f; // percent hull at which ship will ask for help
const float AWACS_HELP_HULL_LOW = 0.25f; // percent hull at which ship will ask for help
#define CHECK_THEN_COPY(attribute) \
do {\
if (other.attribute != NULL)\
@@ -970,9 +965,6 @@ void ship_info::clone(const ship_info& other)
scan_range_normal = other.scan_range_normal;
scan_range_capital = other.scan_range_capital;
ask_help_shield_percent = other.ask_help_shield_percent;
ask_help_hull_percent = other.ask_help_hull_percent;
memcpy(ct_info, other.ct_info, sizeof(trail_info) * MAX_SHIP_CONTRAILS);
ct_count = other.ct_count;
@@ -1252,9 +1244,6 @@ void ship_info::move(ship_info&& other)
scan_range_normal = other.scan_range_normal;
scan_range_capital = other.scan_range_capital;
ask_help_shield_percent = other.ask_help_shield_percent;
ask_help_hull_percent = other.ask_help_hull_percent;
std::swap(ct_info, other.ct_info);
ct_count = other.ct_count;
@@ -1636,9 +1625,6 @@ ship_info::ship_info()
scan_range_normal = CARGO_REVEAL_MIN_DIST;
scan_range_capital = CAP_CARGO_REVEAL_MIN_DIST;
ask_help_shield_percent = DEFAULT_ASK_HELP_SHIELD_PERCENT;
ask_help_hull_percent = DEFAULT_ASK_HELP_HULL_PERCENT;
memset(&ct_info, 0, sizeof(trail_info) * MAX_SHIP_CONTRAILS);
ct_count = 0;
@@ -3575,28 +3561,6 @@ static int parse_ship_values(ship_info* sip, const bool is_template, const bool
if(optional_string("$Scan range Capital:"))
stuff_float(&sip->scan_range_capital);
if (optional_string("$Ask Help Shield Percent:")) {
float help_shield_val;
stuff_float(&help_shield_val);
if (help_shield_val > 0.0f && help_shield_val <= 1.0f) {
sip->ask_help_shield_percent = help_shield_val;
} else {
error_display(0,"Ask Help Shield Percent for ship class %s is %f. This value is not within range of 0-1.0."
"Assuming default value of %f.", sip->name, help_shield_val, DEFAULT_ASK_HELP_SHIELD_PERCENT);
}
}
if (optional_string("$Ask Help Hull Percent:")) {
float help_hull_val;
stuff_float(&help_hull_val);
if (help_hull_val > 0.0f && help_hull_val <= 1.0f) {
sip->ask_help_shield_percent = help_hull_val;
} else {
error_display(0,"Ask Help Hull Percent for ship class %s is %f. This value is not within range of 0-1.0."
"Assuming default value of %f.", sip->name, help_hull_val, DEFAULT_ASK_HELP_HULL_PERCENT);
}
}
//Parse the engine sound
parse_game_sound("$EngineSnd:", &sip->engine_snd);
@@ -6863,8 +6827,8 @@ void ship_render_show_ship_cockpit(object *objp)
vec3d cockpit_eye_pos;
matrix dummy;
ship_get_eye(&cockpit_eye_pos, &dummy, objp, true, false); // Get cockpit eye position
ship_get_eye(&cockpit_eye_pos, &dummy, objp, true, false); //Get cockpit eye position
gr_end_view_matrix();
gr_end_proj_matrix();
gr_set_proj_matrix(Proj_fov, gr_screen.clip_aspect, 0.05f, Max_draw_distance);
@@ -6877,9 +6841,7 @@ void ship_render_show_ship_cockpit(object *objp)
render_info.set_object_number(OBJ_INDEX(objp));
render_info.set_detail_level_lock(0);
model_render_immediate(&render_info, Ship_info[Ships[objp->instance].ship_info_index].model_num, &objp->orient,
&objp->pos); // Render ship model with fixed detail level 0 so its not switching LOD when
// moving away from origin
model_render_immediate(&render_info, Ship_info[Ships[objp->instance].ship_info_index].model_num, &objp->orient, &objp->pos); // Render ship model with fixed detail level 0 so its not switching LOD when moving away from origin
Glowpoint_override = false;
gr_end_view_matrix();
@@ -7364,7 +7326,6 @@ void ship_cleanup(int shipnum, int cleanup_mode)
ship *shipp = &Ships[shipnum];
object *objp = &Objects[shipp->objnum];
char *jumpnode_name = nullptr;
// add the information to the exited ship list
switch (cleanup_mode) {
@@ -7405,14 +7366,14 @@ void ship_cleanup(int shipnum, int cleanup_mode)
// add mission log entry?
// (vanished ships and red-alert deleted ships have no log, and destroyed ships are logged in ship_hit_kill)
if ((cleanup_mode == SHIP_DEPARTED_WARP) || (cleanup_mode == SHIP_DEPARTED_BAY) || (cleanup_mode == SHIP_DEPARTED)) {
if ((cleanup_mode == SHIP_DEPARTED_WARP) || (cleanup_mode == SHIP_DEPARTED_BAY) || (cleanup_mode == SHIP_DEPARTED)) {\
// see if this ship departed within the radius of a jump node -- if so, put the node name into
// the secondary mission log field
CJumpNode *jnp = jumpnode_get_which_in(objp);
if (jnp != nullptr)
jumpnode_name = jnp->GetName();
mission_log_add_entry(LOG_SHIP_DEPARTED, shipp->ship_name, jumpnode_name, shipp->wingnum);
if(jnp==NULL)
mission_log_add_entry(LOG_SHIP_DEPARTED, shipp->ship_name, NULL, shipp->wingnum);
else
mission_log_add_entry(LOG_SHIP_DEPARTED, shipp->ship_name, jnp->GetName(), shipp->wingnum);
}
// run "On Ship Depart" conditional hook variable that accounts for all departure types
@@ -7423,9 +7384,8 @@ void ship_cleanup(int shipnum, int cleanup_mode)
const char* departmethod = get_departure_name(cleanup_mode);
Script_system.SetHookObject("Ship", objp);
Script_system.SetHookVar("Method", 's', departmethod);
Script_system.SetHookVar("JumpNode", 's', jumpnode_name);
Script_system.RunCondition(CHA_ONSHIPDEPART);
Script_system.RemHookVars(3, "Ship", "Method", "JumpNode");
Script_system.RemHookVars(2, "Ship", "Method");
}
#ifndef NDEBUG
@@ -12750,6 +12710,36 @@ int ship_type_name_lookup(const char *name)
return -1;
}
// checks the (arrival & departure) state of a ship. Return values:
// -1: has yet to arrive in mission
// 0: is currently in mission
// 1: has been destroyed, departed, or never existed
int ship_query_state(char *name)
{
int i;
// bogus
Assert(name != NULL);
if(name == NULL){
return -1;
}
for (i=0; i<MAX_SHIPS; i++){
if (Ships[i].objnum >= 0){
if ((Objects[Ships[i].objnum].type == OBJ_SHIP) || (Objects[Ships[i].objnum].type == OBJ_START)){
if (!stricmp(name, Ships[i].ship_name)){
return 0;
}
}
}
}
if (mission_parse_get_arrival_ship(name))
return -1;
return 1;
}
// Finds the world position of a subsystem.
// Return true/false for subsystem found/not found.
// Stuff vector *pos with absolute position.
@@ -15413,6 +15403,11 @@ void ship_maybe_praise_self(ship *deader_sp, ship *killer_sp)
Player->praise_self_count++;
}
#define ASK_HELP_SHIELD_PERCENT 0.1 // percent shields at which ship will ask for help
#define ASK_HELP_HULL_PERCENT 0.3 // percent hull at which ship will ask for help
#define AWACS_HELP_HULL_HI 0.75 // percent hull at which ship will ask for help
#define AWACS_HELP_HULL_LOW 0.25 // percent hull at which ship will ask for help
// -----------------------------------------------------------------------------
static void awacs_maybe_ask_for_help(ship *sp, int multi_team_filter)
{
@@ -15451,7 +15446,6 @@ void ship_maybe_ask_for_help(ship *sp)
{
object *objp;
int multi_team_filter = -1;
ship_info* sip = &Ship_info[sp->ship_info_index];
// First check if the player has reached the maximum number of ask_help's for a mission
if ((Builtin_messages[MESSAGE_HELP].max_count > -1) && (Player->ask_help_count >= Builtin_messages[MESSAGE_HELP].max_count))
@@ -15487,14 +15481,14 @@ void ship_maybe_ask_for_help(ship *sp)
return;
// first check if hull is at a critical level
if (objp->hull_strength < sip->ask_help_hull_percent * sp->ship_max_hull_strength)
if (objp->hull_strength < ASK_HELP_HULL_PERCENT * sp->ship_max_hull_strength)
goto play_ask_help;
// check if shields are near critical level
if (objp->flags[Object::Object_Flags::No_shields])
return; // no shields on ship, no don't check shield levels
if (shield_get_strength(objp) > (sip->ask_help_shield_percent * shield_get_max_strength(objp)))
if (shield_get_strength(objp) > (ASK_HELP_SHIELD_PERCENT * shield_get_max_strength(objp)))
return;
play_ask_help:
+2 -3
View File
@@ -1106,9 +1106,6 @@ public:
float scan_range_normal; // this ship can scan other normal/small ships at this range
float scan_range_capital; // this ship can scan other capital/large ships at this range
float ask_help_shield_percent;
float ask_help_hull_percent;
// contrail info
trail_info ct_info[MAX_SHIP_CONTRAILS];
int ct_count;
@@ -1525,6 +1522,8 @@ extern int ship_query_general_type(ship *shipp);
extern int ship_docking_valid(int docker, int dockee);
extern int get_quadrant(vec3d *hit_pnt, object *shipobjp = NULL); // Return quadrant num of given hit point.
extern int ship_query_state(char *name);
int ship_secondary_bank_has_ammo(int shipnum); // check if current secondary bank has ammo
int ship_engine_ok_to_warp(ship *sp); // check if ship has engine power to warp
+23 -3
View File
@@ -213,6 +213,27 @@ static void shipfx_subsystem_maybe_create_live_debris(object *ship_objp, ship *s
}
}
static void set_ship_submodel_as_blown_off(ship *shipp, const char *name)
{
int found = FALSE;
// go through list of ship subsystems and find name
ship_subsys *pss = NULL;
for (pss=GET_FIRST(&shipp->subsys_list); pss!=END_OF_LIST(&shipp->subsys_list); pss=GET_NEXT(pss)) {
if ( subsystem_stricmp(pss->system_info->subobj_name, name) == 0) {
found = TRUE;
break;
}
}
// set its blown off flag to TRUE
Assert(found);
if (found) {
pss->submodel_info_1.blown_off = 1;
}
}
/**
* Create debris for ship submodel which has live debris (at ship death)
* when ship submodel has not already been blown off (and hence liberated live debris)
@@ -263,8 +284,8 @@ static void shipfx_maybe_create_live_debris_at_ship_death( object *ship_objp )
shipfx_subsystem_maybe_create_live_debris(ship_objp, shipp, pss, &exp_center, 3.0f);
// now set subsystem as blown off, so we only get one copy
pmi->submodel[parent].blown_off = true;
pss->submodel_info_1.blown_off = 1;
pm->submodel[parent].blown_off = 1;
set_ship_submodel_as_blown_off(&Ships[ship_objp->instance], pss->system_info->subobj_name);
}
}
}
@@ -1662,7 +1683,6 @@ void shipfx_queue_render_ship_halves_and_debris(model_draw_list *scene, clip_shi
render_info.set_flags(render_flags);
render_info.set_clip_plane(model_clip_plane_pt, clip_plane_norm);
render_info.set_replacement_textures(shipp->ship_replacement_textures);
render_info.set_object_number(shipp->objnum);
model_render_queue(&render_info, scene, pm->id, &half_ship->orient, &orig_ship_world_center);
}
+5 -31
View File
@@ -108,13 +108,10 @@ static bool is_subsys_destroyed(ship *shipp, int submodel)
// do_subobj_destroyed_stuff is called when a subobject for a ship is killed. Separated out
// to separate function on 10/15/97 by MWA for easy multiplayer access. It does all of the
// cool things like blowing off the model (if applicable, writing the logs, etc)
// NOTE: if this function is used with ship_recalc_subsys_strength, it MUST be called first. If
// a child subsystem needs to be destroyed, the strength calculation needs to take it into account.
void do_subobj_destroyed_stuff( ship *ship_p, ship_subsys *subsys, vec3d* hitpos, bool no_explosion )
{
ship_info *sip;
object *ship_objp;
ship_subsys *ssp;
model_subsystem *psub;
vec3d g_subobj_pos;
int type, i, log_index;
@@ -126,27 +123,6 @@ void do_subobj_destroyed_stuff( ship *ship_p, ship_subsys *subsys, vec3d* hitpos
type = psub->type;
get_subsystem_world_pos(ship_objp, subsys, &g_subobj_pos);
// see if this subsystem is on a submodel
if (psub->subobj_num >= 0) {
polymodel *pm = model_get(sip->model_num);
// see if there are any subsystems which have this submodel as a parent
for (ssp = GET_FIRST(&ship_p->subsys_list); ssp != END_OF_LIST(&ship_p->subsys_list); ssp = GET_NEXT(ssp)) {
// is it another subsys which has a submodel?
if (ssp != subsys && ssp->system_info->subobj_num >= 0) {
// is this other submodel a child of the one being destroyed?
if (pm->submodel[ssp->system_info->subobj_num].parent == psub->subobj_num) {
// is it not yet destroyed? (this is a valid check because we already know there is a submodel)
if (!ssp->submodel_info_1.blown_off) {
// then destroy it first
ssp->current_hits = 0;
do_subobj_destroyed_stuff(ship_p, ssp, nullptr, no_explosion);
}
}
}
}
}
// create fireballs when subsys destroy for large ships.
object* objp = &Objects[ship_p->objnum];
@@ -216,8 +192,10 @@ void do_subobj_destroyed_stuff( ship *ship_p, ship_subsys *subsys, vec3d* hitpos
if ( ship_p->subsys_info[type].type_count == 1 ) {
ship_p->subsys_info[type].aggregate_current_hits = 0.0f;
} else {
float hits = 0.0f;
float hits;
ship_subsys *ssp;
hits = 0.0f;
for ( ssp=GET_FIRST(&ship_p->subsys_list); ssp != END_OF_LIST(&ship_p->subsys_list); ssp = GET_NEXT(ssp) ) {
// type matches?
if ( (ssp->system_info->type == type) && !(ssp->flags[Ship::Subsystem_Flags::No_aggregate]) ) {
@@ -674,9 +652,10 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
min_index = i;
}
}
Assert(min_index != -1);
}
Assert(min_index != -1);
float damage_to_apply = 0.0f;
subsystem = subsys_list[min_index].ptr;
range = subsys_list[min_index].range;
@@ -685,11 +664,6 @@ float do_subobj_hit_stuff(object *ship_objp, object *other_obj, vec3d *hitpos, i
Assert(range > 0.0f); // Goober5000 - avoid div-0 below
// Make sure this subsystem still has hitpoints. If it's a child of a parent that was destroyed, it will have been destroyed already.
if (subsystem->current_hits <= 0.0f) {
continue;
}
// only do this for the closest affected subsystem
if ( (j == 0) && (!(parent_armor_flags & SAF_IGNORE_SS_ARMOR))) {
if(subsystem->armor_type_idx > -1)
+4 -11
View File
@@ -62,6 +62,8 @@ add_file_folder("CFile"
cfile/cfilearchive.cpp
cfile/cfilearchive.h
cfile/cfilelist.cpp
cfile/cfilemod.cpp
cfile/cfilemod.h
cfile/cfilesystem.cpp
cfile/cfilesystem.h
)
@@ -197,18 +199,11 @@ add_file_folder("Default files\\\\data\\\\effects"
def_files/data/effects/shadowdebug-f.sdr
def_files/data/effects/shadowdebug-v.sdr
def_files/data/effects/shadows.sdr
def_files/data/effects/shield-impact-v.sdr
def_files/data/effects/shield-impact-f.sdr
def_files/data/effects/SMAA.sdr
def_files/data/effects/smaa-blend-v.sdr
def_files/data/effects/smaa-blend-f.sdr
def_files/data/effects/smaa-edge-v.sdr
def_files/data/effects/smaa-edge-f.sdr
def_files/data/effects/smaa-neighbour-v.sdr
def_files/data/effects/smaa-neighbour-f.sdr
def_files/data/effects/tonemapping-f.sdr
def_files/data/effects/video-f.sdr
def_files/data/effects/video-v.sdr
def_files/data/effects/shield-impact-v.sdr
def_files/data/effects/shield-impact-f.sdr
)
add_file_folder("Default files\\\\data\\\\maps"
@@ -413,8 +408,6 @@ add_file_folder("Graphics\\\\OpenGLGr\\\\OpenGL Headers"
graphics/opengl/gropengltexture.h
graphics/opengl/gropengltnl.h
graphics/opengl/ShaderProgram.h
graphics/opengl/SmaaAreaTex.h
graphics/opengl/SmaaSearchTex.h
)
# Graphics -> Paths
-5
View File
@@ -25,11 +25,6 @@ Category BloomBrightPass("Bloom bright pass", true);
Category BloomIterationStep("Bloom iteration step", true);
Category BloomCompositeStep("Bloom composite step", true);
Category FXAA("FXAA", true);
Category SMAA("SMAA", true);
Category SMAAEdgeDetection("SMAA Edge Detection", true);
Category SMAACalculateBlendingWeights("SMAA Calculate BLending Weights", true);
Category SMAANeighborhoodBlending("SMAA Neighborhood Blending", true);
Category SMAAResolve("SMAA Resolve", true);
Category Lightshafts("Lightshafts", true);
Category DrawPostEffects("Draw post effects", true);
-5
View File
@@ -37,11 +37,6 @@ extern Category BloomBrightPass;
extern Category BloomIterationStep;
extern Category BloomCompositeStep;
extern Category FXAA;
extern Category SMAA;
extern Category SMAAEdgeDetection;
extern Category SMAACalculateBlendingWeights;
extern Category SMAANeighborhoodBlending;
extern Category SMAAResolve;
extern Category Lightshafts;
extern Category DrawPostEffects;
+10 -10
View File
@@ -8,23 +8,23 @@
#include <utility>
#if SCP_HAVE_STRCASECMP || SCP_HAVE_STRNCASECMP
#if SCP_HAVE_STRINGS_H
#if HAVE_STRCASECMP || HAVE_STRNCASECMP
#if HAVE_STRINGS_H
#include <strings.h>
#else
#error strings.h is not available!
#endif
#endif
#if SCP_HAVE__STRICMP || SCP_HAVE__STRNICMP || SCP_HAVE_STRLWR
#if HAVE__STRICMP || HAVE__STRNICMP || HAVE_STRLWR
#include <string.h>
#endif
#if SCP_HAVE_STRCASECMP
#if HAVE_STRCASECMP
inline int stricmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2);
}
#elif SCP_HAVE__STRICMP
#elif HAVE__STRICMP
inline int stricmp(const char* s1, const char* s2) {
return _stricmp(s1, s2);
}
@@ -32,11 +32,11 @@ inline int stricmp(const char* s1, const char* s2) {
#error No case insensitive string comparision available!
#endif
#if SCP_HAVE_STRNCASECMP
#if HAVE_STRNCASECMP
inline int strnicmp(const char* s1, const char* s2, size_t n) {
return strncasecmp(s1, s2, n);
}
#elif SCP_HAVE__STRNICMP
#elif HAVE__STRNICMP
inline int strnicmp(const char* s1, const char* s2, size_t n) {
return _strnicmp(s1, s2, n);
}
@@ -44,7 +44,7 @@ inline int strnicmp(const char* s1, const char* s2, size_t n) {
#error No case insensitive string comparision available!
#endif
#if !SCP_HAVE_STRLWR
#if !HAVE_STRLWR
inline void strlwr(char *s) {
if (s == NULL)
return;
@@ -56,8 +56,8 @@ inline void strlwr(char *s) {
}
#endif
#if !SCP_HAVE_SNPRINTF
#if SCP_HAVE__SNPRINTF
#if !HAVE_SNPRINTF
#if HAVE__SNPRINTF
#define snprintf _snprintf
#else
#error No support for snprintf detected!
+5 -5
View File
@@ -19,15 +19,15 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
#if defined(SCP_HAVE_MALLOC_H)
#if defined(HAVE_MALLOC_H)
#include <malloc.h>
#endif
#ifdef SCP_HAVE_EXECINFO_H
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
#ifdef SCP_HAVE_CXXAPI_H
#ifdef HAVE_CXXAPI_H
#include <cxxabi.h>
#endif
@@ -49,7 +49,7 @@ int filelength(int fd)
SCP_string dump_stacktrace()
{
#ifdef SCP_HAVE_EXECINFO_H
#ifdef HAVE_EXECINFO_H
// The following is adapted from here: https://panthema.net/2008/0901-stacktrace-demangled/
const int ADDR_SIZE = 64;
void *addresses[ADDR_SIZE];
@@ -71,7 +71,7 @@ SCP_string dump_stacktrace()
// Demangle c++ function names to a more readable format using the ABI functions
// TODO: Maybe add configure time checks to check if the required features are available
SCP_stringstream stackstream;
#ifdef SCP_HAVE_CXXAPI_H
#ifdef HAVE_CXXAPI_H
size_t funcnamesize = 256;
char* funcname = reinterpret_cast<char*>(malloc(funcnamesize));
+10 -24
View File
@@ -35,6 +35,7 @@
#include "autopilot/autopilot.h"
#include "bmpman/bmpman.h"
#include "cfile/cfile.h"
#include "cfile/cfilemod.h"
#include "cmdline/cmdline.h"
#include "cmeasure/cmeasure.h"
#include "cutscene/cutscenes.h"
@@ -1684,7 +1685,6 @@ void game_init()
{
int s1 __UNUSED, e1 __UNUSED;
const char *ptr;
char whee[MAX_PATH_LEN];
Game_current_mission_filename[0] = 0;
@@ -1725,17 +1725,11 @@ void game_init()
cmdline_debug_print_cmdline();
#endif
memset(whee, 0, sizeof(whee));
_getcwd(whee, MAX_PATH_LEN-1);
strcat_s(whee, DIR_SEPARATOR_STR);
strcat_s(whee, EXE_FNAME);
//Initialize the libraries
s1 = timer_get_milliseconds();
if ( cfile_init(whee, NULL) ) { // initialize before calling any cfopen stuff!!!
// initialize before calling any cfopen stuff!!!
if ( cfile_init(Cmdline_mod) ) {
exit(1);
}
@@ -5686,17 +5680,17 @@ void game_enter_state( int old_state, int new_state )
// Main_hall_netgame_started = 1;
// main_hall_do_multi_ready();
//} DTP commented out to keep original source
if ( (Cmdline_start_netgame || (Cmdline_connect_addr != NULL)) && (!Main_hall_netgame_started) /*&& (Game_mode == GM_MULTIPLAYER)*/) { // DTP added "&& (game_mode == GM_multiplayer)" so that ppl don't get thrown into Multiplayer with a Singleplayer Pilot.
if ( (Cmdline_start_netgame || (!Cmdline_connect_addr.empty())) && (!Main_hall_netgame_started) /*&& (Game_mode == GM_MULTIPLAYER)*/) { // DTP added "&& (game_mode == GM_multiplayer)" so that ppl don't get thrown into Multiplayer with a Singleplayer Pilot.
Main_hall_netgame_started = 1;
main_hall_do_multi_ready();
}
if(Cmdline_start_mission) {
strcpy_s(Game_current_mission_filename, Cmdline_start_mission);
if(!Cmdline_start_mission.empty()) {
strcpy_s(Game_current_mission_filename, Cmdline_start_mission.c_str());
mprintf(( "Straight to mission '%s'\n", Game_current_mission_filename ));
gameseq_post_event(GS_EVENT_START_GAME);
// This stops the mission from loading again when you go back to the hall
Cmdline_start_mission = NULL;
Cmdline_start_mission.clear();
}
break;
@@ -6738,7 +6732,6 @@ int game_main(int argc, char *argv[])
tmp_mem = NULL;
#endif // _WIN32
if ( !parse_cmdline(argc, argv) ) {
return 1;
}
@@ -6757,10 +6750,10 @@ int game_main(int argc, char *argv[])
game_stop_time();
if (Cmdline_spew_mission_crcs) {
if (!Cmdline_spew_mission_crcs.empty()) {
multi_spew_pxo_checksums(1024, "mission_crcs.csv");
if (Cmdline_spew_table_crcs) {
if (!Cmdline_spew_table_crcs.empty()) {
fs2netd_spew_table_checksums("table_crcs.csv");
}
@@ -6768,7 +6761,7 @@ int game_main(int argc, char *argv[])
return 0;
}
if (Cmdline_spew_table_crcs) {
if (!Cmdline_spew_table_crcs.empty()) {
fs2netd_spew_table_checksums("table_crcs.csv");
game_shutdown();
return 0;
@@ -6965,13 +6958,6 @@ void game_shutdown(void)
cfile_close();
// although the comment in cmdline.cpp said this isn't needed,
// Valgrind disagrees (quite possibly incorrectly), but this is just cleaner
if (Cmdline_mod != NULL) {
delete[] Cmdline_mod;
Cmdline_mod = NULL;
}
lcl_xstr_close();
#if 0 // don't have an updater for fs2_open
+1 -5
View File
@@ -81,12 +81,8 @@ initialize(const std::string& cfilepath, int argc, char* argv[], Editor* editor,
cmdline_debug_print_cmdline();
#endif
// d'oh
// cfile needs a file path...
auto file_path = cfilepath + DIR_SEPARATOR_STR + "qtfred.exe";
listener(SubSystem::CFile);
if (cfile_init(file_path.c_str())) {
if (cfile_init(cfilepath.c_str())) {
return false;
}
-6
View File
@@ -24,8 +24,6 @@ class CFileInitTest : public test::FSTestFixture {
TEST_F(CFileInitTest, wrong_data_case) {
SCP_string cfile_dir(TEST_DATA_PATH);
cfile_dir += DIR_SEPARATOR_CHAR;
cfile_dir += "test"; // Cfile expects something after the path
ASSERT_FALSE(cfile_init(cfile_dir.c_str()));
@@ -34,8 +32,6 @@ TEST_F(CFileInitTest, wrong_data_case) {
TEST_F(CFileInitTest, right_data_case) {
SCP_string cfile_dir(TEST_DATA_PATH);
cfile_dir += DIR_SEPARATOR_CHAR;
cfile_dir += "test"; // Cfile expects something after the path
ASSERT_FALSE(cfile_init(cfile_dir.c_str()));
@@ -129,8 +125,6 @@ TEST(CFileStandalone, test_check_location_flags) {
TEST_F(CFileTest, test_get_path_type)
{
SCP_string cfile_dir(TEST_DATA_PATH);
cfile_dir += DIR_SEPARATOR_CHAR;
cfile_dir += "test"; // Cfile expects something after the path
ASSERT_FALSE(cfile_init(cfile_dir.c_str()));
-2
View File
@@ -33,8 +33,6 @@ void test::FSTestFixture::SetUp() {
if (_initFlags & INIT_CFILE) {
SCP_string cfile_dir(TEST_DATA_PATH);
cfile_dir += DIR_SEPARATOR_CHAR;
cfile_dir += "test"; // Cfile expects something after the path
if (cfile_init(cfile_dir.c_str())) {
FAIL() << "Cfile init failed!";
-5
View File
@@ -1,5 +0,0 @@
set(FSO_VERSION_MAJOR 19)
set(FSO_VERSION_MINOR 0)
set(FSO_VERSION_BUILD 0)
set(FSO_VERSION_REVISION 0)
set(FSO_VERSION_REVISION_STR RC1)