diff --git a/code/Makefile.am b/code/Makefile.am index 75fa76a822..4ff5cbafb5 100644 --- a/code/Makefile.am +++ b/code/Makefile.am @@ -191,7 +191,7 @@ AM_LDFLAGS = @D_LDFLAGS@ @FS2_LDFLAGS@ noinst_LIBRARIES = libcode.a noinst_PROGRAMS = @FS2_BINARY@ -EXTRA_PROGRAMS = fs2_open_r fs2_open_d wxFRED2_r wxFRED2_d +EXTRA_PROGRAMS = fs2_open_r fs2_open_d wxFRED2_r wxFRED2_d fs2_open_INF_r fs2_open_INF_d wxFRED2_INF_r wxFRED2_INF_d ############################################################################### ## @@ -264,6 +264,9 @@ FS2_SOURCES = \ demo/demo.h \ exceptionhandler/exceptionhandler.cpp \ exceptionhandler/exceptionhandler.h \ + external_dll/externalcode.h \ + external_dll/trackirglobal.cpp \ + external_dll/trackirglobal.h \ fireball/fireballs.cpp \ fireball/fireballs.h \ fireball/warpineffect.cpp \ @@ -315,6 +318,8 @@ FS2_SOURCES = \ graphics/gropenglextension.h \ graphics/gropengllight.cpp \ graphics/gropengllight.h \ + graphics/gropenglpostprocessing.cpp \ + graphics/gropenglpostprocessing.h \ graphics/gropenglshader.cpp \ graphics/gropenglshader.h \ graphics/gropenglstate.cpp \ @@ -379,8 +384,6 @@ FS2_SOURCES = \ io/mouse.h \ io/timer.cpp \ io/timer.h \ - io/trackir.cpp \ - io/trackir.h \ jpgutils/jpgutils.cpp \ jpgutils/jpgutils.h \ jumpnode/jumpnode.cpp \ @@ -395,7 +398,6 @@ FS2_SOURCES = \ localization/fhash.h \ localization/localize.cpp \ localization/localize.h \ - math/bitarray.h \ math/fix.cpp \ math/fix.h \ math/floating.cpp \ @@ -593,6 +595,8 @@ FS2_SOURCES = \ particle/particle.h \ pcxutils/pcxutils.cpp \ pcxutils/pcxutils.h \ + pngutils/pngutils.cpp \ + pngutils/pngutils.h \ physics/physics.cpp \ physics/physics.h \ playerman/managepilot.cpp \ @@ -718,7 +722,6 @@ SOUND_SOURCES = \ sound/audiostr.cpp \ sound/audiostr.h \ sound/acm-openal.cpp \ - sound/acm.cpp \ sound/acm.h \ sound/ds.cpp \ sound/ds.h \ @@ -726,18 +729,12 @@ SOUND_SOURCES = \ sound/ds3d.h \ sound/dscap.cpp \ sound/dscap.h \ - sound/midifile.cpp \ - sound/midifile.h \ - sound/midiseq.h \ sound/rbaudio.cpp \ sound/rbaudio.h \ sound/rtvoice.cpp \ sound/rtvoice.h \ sound/sound.cpp \ sound/sound.h \ - sound/winmidi.cpp \ - sound/winmidi.h \ - sound/winmidi_base.cpp \ vcodec/codec1.cpp \ vcodec/codec1.h \ sound/fsspeech.cpp \ @@ -815,8 +812,16 @@ fs2_open_d_SOURCES = \ fs2_open_r_SOURCES = \ ${FS2OPEN_SOURCES} +fs2_open_INF_d_SOURCES = \ + ${FS2OPEN_SOURCES} + +fs2_open_INF_r_SOURCES = \ + ${FS2OPEN_SOURCES} + fs2_open_d_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a fs2_open_r_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a +fs2_open_INF_d_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a +fs2_open_INF_r_LDADD = libcode.a ../libjpeg/libjpeg.a ../lua/liblua.a ## ## End MAIN binary @@ -842,8 +847,16 @@ wxFRED2_d_SOURCES = \ wxFRED2_r_SOURCES = \ ${wxFRED_SOURCES} +wxFRED2_INF_d_SOURCES = \ + ${wxFRED_SOURCES} + +wxFRED2_INF_r_SOURCES = \ + ${wxFRED_SOURCES} + wxFRED2_d_LDADD = libcode.a ../libjpeg/libjpeg.a wxFRED2_r_LDADD = libcode.a ../libjpeg/libjpeg.a +wxFRED2_INF_d_LDADD = libcode.a ../libjpeg/libjpeg.a +wxFRED2_INF_r_LDADD = libcode.a ../libjpeg/libjpeg.a ## ## End wxFRED2 binary diff --git a/code/ai/ai.h b/code/ai/ai.h index 2100be4d68..5d5cbd0d76 100644 --- a/code/ai/ai.h +++ b/code/ai/ai.h @@ -187,7 +187,7 @@ typedef struct ai_class { float ai_patience[NUM_SKILL_LEVELS]; //SUSHI: These were originally in AI_Profiles, adding the option to override in AI.tbl - //Except for the boolean options at the bottom, these all behave as multipliers + //INT_MIN and FLT_MIN represent the "not set" state for which defaults are used instead. float ai_cmeasure_fire_chance[NUM_SKILL_LEVELS]; float ai_in_range_time[NUM_SKILL_LEVELS]; float ai_link_ammo_levels_maybe[NUM_SKILL_LEVELS]; @@ -195,7 +195,7 @@ typedef struct ai_class { float ai_primary_ammo_burst_mult[NUM_SKILL_LEVELS]; float ai_link_energy_levels_maybe[NUM_SKILL_LEVELS]; float ai_link_energy_levels_always[NUM_SKILL_LEVELS]; - float ai_predict_position_delay[NUM_SKILL_LEVELS]; + fix ai_predict_position_delay[NUM_SKILL_LEVELS]; float ai_shield_manage_delay[NUM_SKILL_LEVELS]; float ai_ship_fire_delay_scale_friendly[NUM_SKILL_LEVELS]; float ai_ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS]; @@ -207,13 +207,12 @@ typedef struct ai_class { float ai_glide_strafe_percent[NUM_SKILL_LEVELS]; float ai_stalemate_time_thresh[NUM_SKILL_LEVELS]; float ai_stalemate_dist_thresh[NUM_SKILL_LEVELS]; - float ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS]; + int ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS]; float ai_max_aim_update_delay[NUM_SKILL_LEVELS]; int ai_profile_flags; //Holds the state of flags that are set int ai_profile_flags_set; //Holds which flags are set and which are just left alone //SUSHI: These are optional overrides to an AI class to prevent the automatic scaling based on AI class index - //INT_MIN and FLT_MIN represent the "not set" state for which defaults are used instead. int ai_aburn_use_factor[NUM_SKILL_LEVELS]; float ai_shockwave_evade_chance[NUM_SKILL_LEVELS]; float ai_get_away_chance[NUM_SKILL_LEVELS]; diff --git a/code/ai/ai_profiles.cpp b/code/ai/ai_profiles.cpp index ef36104ceb..1d5553f5ee 100644 --- a/code/ai/ai_profiles.cpp +++ b/code/ai/ai_profiles.cpp @@ -25,17 +25,24 @@ static char Default_profile_name[NAME_LENGTH]; // utility -void set_flag(ai_profile_t *profile, char *name, int flag) +void set_flag(ai_profile_t *profile, char *name, int flag, int type) { if (optional_string(name)) { bool val; stuff_boolean(&val); - if (val) - profile->flags |= flag; - else - profile->flags &= ~flag; + if (type == AIP_FLAG) { + if (val) + profile->flags |= flag; + else + profile->flags &= ~flag; + } else { + if (val) + profile->flags2 |= flag; + else + profile->flags2 &= ~flag; + } } } @@ -302,69 +309,71 @@ void parse_ai_profiles_tbl(char *filename) if (optional_string("$Max Aim Update Delay:")) parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS); - set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS); + set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG); - set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION); + set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG); - set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION); + set_flag(profile, "$smart secondary weapon selection:", AIPF_SMART_SECONDARY_WEAPON_SELECTION, AIP_FLAG); - set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT); + set_flag(profile, "$smart shield management:", AIPF_SMART_SHIELD_MANAGEMENT, AIP_FLAG); - set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT); + set_flag(profile, "$smart afterburner management:", AIPF_SMART_AFTERBURNER_MANAGEMENT, AIP_FLAG); - set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE); + set_flag(profile, "$allow rapid secondary dumbfire:", AIPF_ALLOW_RAPID_SECONDARY_DUMBFIRE, AIP_FLAG); - set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS); + set_flag(profile, "$huge turret weapons ignore bombs:", AIPF_HUGE_TURRET_WEAPONS_IGNORE_BOMBS, AIP_FLAG); - set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY); + set_flag(profile, "$don't insert random turret fire delay:", AIPF_DONT_INSERT_RANDOM_TURRET_FIRE_DELAY, AIP_FLAG); - set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY); + set_flag(profile, "$hack improve non-homing swarm turret fire accuracy:", AIPF_HACK_IMPROVE_NON_HOMING_SWARM_TURRET_FIRE_ACCURACY, AIP_FLAG); - set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS); + set_flag(profile, "$shockwaves damage small ship subsystems:", AIPF_SHOCKWAVES_DAMAGE_SMALL_SHIP_SUBSYSTEMS, AIP_FLAG); - set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP); + set_flag(profile, "$navigation subsystem governs warpout capability:", AIPF_NAVIGATION_SUBSYS_GOVERNS_WARP, AIP_FLAG); - set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP); + set_flag(profile, "$ignore lower bound for minimum speed of docked ship:", AIPF_NO_MIN_DOCK_SPEED_CAP, AIP_FLAG); - set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY); + set_flag(profile, "$disable linked fire penalty:", AIPF_DISABLE_LINKED_FIRE_PENALTY, AIP_FLAG); - set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING); + set_flag(profile, "$disable weapon damage scaling:", AIPF_DISABLE_WEAPON_DAMAGE_SCALING, AIP_FLAG); - set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY); + set_flag(profile, "$use additive weapon velocity:", AIPF_USE_ADDITIVE_WEAPON_VELOCITY, AIP_FLAG); - set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING); + set_flag(profile, "$use newtonian dampening:", AIPF_USE_NEWTONIAN_DAMPENING, AIP_FLAG); - set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS); + set_flag(profile, "$include beams for kills and assists:", AIPF_INCLUDE_BEAMS_IN_STAT_CALCS, AIP_FLAG); - set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE); + set_flag(profile, "$score kills based on damage caused:", AIPF_KILL_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG); - set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE); + set_flag(profile, "$score assists based on damage caused:", AIPF_ASSIST_SCORING_SCALES_WITH_DAMAGE, AIP_FLAG); - set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING); + set_flag(profile, "$allow event and goal scoring in multiplayer:", AIPF_ALLOW_MULTI_EVENT_SCORING, AIP_FLAG); - set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG); + set_flag(profile, "$fix linked primary weapon decision bug:", AIPF_FIX_LINKED_PRIMARY_BUG, AIP_FLAG); - set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE); + set_flag(profile, "$prevent turrets targeting too distant bombs:", AIPF_PREVENT_TARGETING_BOMBS_BEYOND_RANGE, AIP_FLAG); - set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS); + set_flag(profile, "$smart subsystem targeting for turrets:", AIPF_SMART_SUBSYSTEM_TARGETING_FOR_TURRETS, AIP_FLAG); - set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG); + set_flag(profile, "$fix heat seekers homing on stealth ships bug:", AIPF_FIX_HEAT_SEEKER_STEALTH_BUG, AIP_FLAG); - set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES); + set_flag(profile, "$multi allow empty primaries:", AIPF_MULTI_ALLOW_EMPTY_PRIMARIES, AIP_FLAG); - set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES); + set_flag(profile, "$multi allow empty secondaries:", AIPF_MULTI_ALLOW_EMPTY_SECONDARIES, AIP_FLAG); - set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY); + set_flag(profile, "$allow turrets target weapons freely:", AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY, AIP_FLAG); - set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS); + set_flag(profile, "$use only single fov for turrets:", AIPF_USE_ONLY_SINGLE_FOV_FOR_TURRETS, AIP_FLAG); - set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE); + set_flag(profile, "$allow vertical dodge:", AIPF_ALLOW_VERTICAL_DODGE, AIP_FLAG); - set_flag(profile, "$disarm or disable cause global ai goal effects:", AIPF_GLOBAL_DISARM_DISABLE_EFFECTS); + set_flag(profile, "$disarm or disable cause global ai goal effects:", AIPF_GLOBAL_DISARM_DISABLE_EFFECTS, AIP_FLAG); - set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV); + set_flag(profile, "$force beam turrets to use normal fov:", AIPF_FORCE_BEAM_TURRET_FOV, AIP_FLAG); - set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG); + set_flag(profile, "$fix ai class bug:", AIPF_FIX_AI_CLASS_BUG, AIP_FLAG); + + set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2); // if we've been through once already and are at the same place, force a move if ( saved_Mp && (saved_Mp == Mp) ) diff --git a/code/ai/ai_profiles.h b/code/ai/ai_profiles.h index c3670f085f..d332172190 100644 --- a/code/ai/ai_profiles.h +++ b/code/ai/ai_profiles.h @@ -13,6 +13,9 @@ #include "globalincs/globals.h" #include "globalincs/systemvars.h" +// flag int defines +#define AIP_FLAG 1 +#define AIP_FLAG2 2 // flags #define AIPF_SMART_SHIELD_MANAGEMENT (1 << 0) @@ -48,6 +51,9 @@ #define AIPF_FORCE_BEAM_TURRET_FOV (1 << 30) #define AIPF_FIX_AI_CLASS_BUG (1 << 31) +// flags2 +#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0) + #define MAX_AI_PROFILES 5 typedef struct ai_profile_t { @@ -55,6 +61,7 @@ typedef struct ai_profile_t { char profile_name[NAME_LENGTH]; int flags; + int flags2; // difficulty-related values int max_incoming_asteroids[NUM_SKILL_LEVELS]; // max number of asteroids thrown at friendlies diff --git a/code/ai/aibig.cpp b/code/ai/aibig.cpp index 492529a165..4a17fda252 100644 --- a/code/ai/aibig.cpp +++ b/code/ai/aibig.cpp @@ -132,8 +132,8 @@ void ai_bpap(object *objp, vec3d *attacker_objp_pos, vec3d *attacker_objp_fvec, dist = vm_vec_normalized_dir(&v2p, &result_point, attacker_objp_pos); bool in_fov = false; + dot = vm_vec_dot(&v2p, attacker_objp_fvec); if (tp == NULL) { - dot = vm_vec_dot(&v2p, attacker_objp_fvec); if (dot > fov) in_fov = true; } else { @@ -1417,9 +1417,9 @@ void ai_big_strafe_glide_attack() if (aip->submode_parm1 == 1) { accelerate_ship(aip, 1.0f); //Use afterburners if we have them and are pointed the right way - if (dot_to_goal > 0.99f) { - afterburners_start(Pl_objp); - aip->afterburner_stop_time = Missiontime + 3*F1_0; + if (dot_to_goal > 0.99f && ai_maybe_fire_afterburner(Pl_objp, aip)) { + afterburners_start(Pl_objp); + aip->afterburner_stop_time = Missiontime + 3*F1_0; } turn_towards_point(Pl_objp, &aip->goal_point, NULL, 0.0f); diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index 663ef19d5b..b873bcba53 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -525,33 +525,33 @@ void free_ai_stuff() } //SUSHI: Initialize an AI class's nonrequired values to defaults -//Boolean overrides are unset, multipliers are initialized to 1.0 +//Boolean overrides are unset, others initialized to FLT_MIN or INT_MIN (used as the "not set" state) void init_ai_class(ai_class *aicp) { int i; for (i = 0; i < NUM_SKILL_LEVELS; i++) { - aicp->ai_cmeasure_fire_chance[i] = 1.0f; - aicp->ai_in_range_time[i] = 1.0f; - aicp->ai_link_ammo_levels_maybe[i] = 1.0f; - aicp->ai_link_ammo_levels_always[i] = 1.0f; - aicp->ai_primary_ammo_burst_mult[i] = 1.0f; - aicp->ai_link_energy_levels_maybe[i] = 1.0f; - aicp->ai_link_energy_levels_always[i] = 1.0f; - aicp->ai_predict_position_delay[i] = 1.0f; - aicp->ai_shield_manage_delay[i] = 1.0f; - aicp->ai_ship_fire_delay_scale_friendly[i] = 1.0f; - aicp->ai_ship_fire_delay_scale_hostile[i] = 1.0f; - aicp->ai_ship_fire_secondary_delay_scale_friendly[i] = 1.0f; - aicp->ai_ship_fire_secondary_delay_scale_hostile[i] = 1.0f; - aicp->ai_turn_time_scale[i] = 1.0f; - aicp->ai_glide_attack_percent[i] = 1.0f; - aicp->ai_circle_strafe_percent[i] = 1.0f; - aicp->ai_glide_strafe_percent[i] = 1.0f; - aicp->ai_stalemate_time_thresh[i] = 1.0f; - aicp->ai_stalemate_dist_thresh[i] = 1.0f; - aicp->ai_chance_to_use_missiles_on_plr[i] = 1.0f; - aicp->ai_max_aim_update_delay[i] = 1.0f; + aicp->ai_cmeasure_fire_chance[i] = FLT_MIN; + aicp->ai_in_range_time[i] = FLT_MIN; + aicp->ai_link_ammo_levels_maybe[i] = FLT_MIN; + aicp->ai_link_ammo_levels_always[i] = FLT_MIN; + aicp->ai_primary_ammo_burst_mult[i] = FLT_MIN; + aicp->ai_link_energy_levels_maybe[i] = FLT_MIN; + aicp->ai_link_energy_levels_always[i] = FLT_MIN; + aicp->ai_predict_position_delay[i] = INT_MIN; + aicp->ai_shield_manage_delay[i] = FLT_MIN; + aicp->ai_ship_fire_delay_scale_friendly[i] = FLT_MIN; + aicp->ai_ship_fire_delay_scale_hostile[i] = FLT_MIN; + aicp->ai_ship_fire_secondary_delay_scale_friendly[i] = FLT_MIN; + aicp->ai_ship_fire_secondary_delay_scale_hostile[i] = FLT_MIN; + aicp->ai_turn_time_scale[i] = FLT_MIN; + aicp->ai_glide_attack_percent[i] = FLT_MIN; + aicp->ai_circle_strafe_percent[i] = FLT_MIN; + aicp->ai_glide_strafe_percent[i] = FLT_MIN; + aicp->ai_stalemate_time_thresh[i] = FLT_MIN; + aicp->ai_stalemate_dist_thresh[i] = FLT_MIN; + aicp->ai_chance_to_use_missiles_on_plr[i] = INT_MIN; + aicp->ai_max_aim_update_delay[i] = FLT_MIN; } aicp->ai_profile_flags = 0; aicp->ai_profile_flags_set = 0; @@ -624,7 +624,7 @@ void parse_ai_class() stuff_boolean(&aicp->ai_class_autoscale); - //Parse optional values for stuff imported from ai_profiles (these are multipliers) + //Parse optional values for stuff imported from ai_profiles if (optional_string("$AI Countermeasure Firing Chance:")) parse_float_list(aicp->ai_cmeasure_fire_chance, NUM_SKILL_LEVELS); @@ -646,8 +646,14 @@ void parse_ai_class() if (optional_string("$AI Maybe Links Energy Weapons:")) parse_float_list(aicp->ai_link_energy_levels_maybe, NUM_SKILL_LEVELS); - if (optional_string("$Predict Position Delay:")) - parse_float_list(aicp->ai_predict_position_delay, NUM_SKILL_LEVELS); + // represented in fractions of F1_0 + if (optional_string("$Predict Position Delay:")) { + int iLoop; + float temp_list[NUM_SKILL_LEVELS]; + parse_float_list(temp_list, NUM_SKILL_LEVELS); + for (iLoop = 0; iLoop < NUM_SKILL_LEVELS; iLoop++) + aicp->ai_predict_position_delay[iLoop] = fl2f(temp_list[iLoop]); + } if (optional_string("$AI Shield Manage Delay:") || optional_string("$AI Shield Manage Delays:")) parse_float_list(aicp->ai_shield_manage_delay, NUM_SKILL_LEVELS); @@ -683,7 +689,7 @@ void parse_ai_class() parse_float_list(aicp->ai_stalemate_dist_thresh, NUM_SKILL_LEVELS); if (optional_string("$Chance AI Has to Fire Missiles at Player:")) - parse_float_list(aicp->ai_chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS); + parse_int_list(aicp->ai_chance_to_use_missiles_on_plr, NUM_SKILL_LEVELS); if (optional_string("$Max Aim Update Delay:")) parse_float_list(aicp->ai_max_aim_update_delay, NUM_SKILL_LEVELS); @@ -1643,6 +1649,15 @@ void get_tangent_point(vec3d *goal_point, object *objp, vec3d *point, float radi vm_vec_normalized_dir(&vec_to_point, point, &objp->pos); vm_vec_crossprod(&up_vec, &vec_to_point, &objp->orient.vec.fvec); + + while (IS_VEC_NULL(&up_vec)) { + vec3d rnd_vec; + + vm_vec_rand_vec_quick(&rnd_vec); + vm_vec_add2(&rnd_vec, &objp->orient.vec.fvec); + vm_vec_crossprod(&up_vec, &vec_to_point, &rnd_vec); + } + vm_vec_crossprod(&perp_vec, &vec_to_point, &up_vec); vm_vec_normalize(&perp_vec); @@ -5051,15 +5066,17 @@ void evade_ship() } else accelerate_ship(aip, (float) (Game_skill_level+2) / (NUM_SKILL_LEVELS+1)); - if ((Missiontime - aip->submode_start_time > F1_0/2) && (sip->afterburner_fuel_capacity > 0.0f)) { - float percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity; - if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) { - afterburners_start(Pl_objp); + if (ai_maybe_fire_afterburner(Pl_objp, aip)){ + if ((Missiontime - aip->submode_start_time > F1_0/2) && (sip->afterburner_fuel_capacity > 0.0f)) { + float percent_left = 100.0f * shipp->afterburner_fuel / sip->afterburner_fuel_capacity; + if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) { + afterburners_start(Pl_objp); - if (aip->ai_profile_flags & AIPF_SMART_AFTERBURNER_MANAGEMENT) { - aip->afterburner_stop_time = (fix) (Missiontime + F1_0 + static_randf(Pl_objp-Objects) * F1_0 / 4); - } else { - aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4; + if (aip->ai_profile_flags & AIPF_SMART_AFTERBURNER_MANAGEMENT) { + aip->afterburner_stop_time = (fix) (Missiontime + F1_0 + static_randf(Pl_objp-Objects) * F1_0 / 4); + } else { + aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4; + } } } } @@ -5378,6 +5395,23 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags) // ##UnknownPlayer## - removed. } + if ( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP)) + { + //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] > -1) // Make sure there is a weapon in the bank + { + if (Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) + { + swp->current_primary_bank = i; + nprintf(("AI", "%i: Ship %s selecting weapon %s\n", Framecount, Ships[objp->instance].ship_name, Weapon_info[swp->primary_bank_weapons[i]].name)); + return i; + } + } + } + } + float enemy_remaining_shield = get_shield_pct(other_objp); // Is the target shielded by say only 5%? @@ -5392,7 +5426,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags) { if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank { - 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 (((((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) && (!(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS) && !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) ) { // This weapon is the new candidate 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 ); @@ -5416,7 +5450,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags) bank_index = swp->current_primary_bank; - if (Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_PIERCE_SHIELDS) + if ((Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[bank_index]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) { return swp->current_primary_bank; } @@ -5429,7 +5463,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags) if (weapon_info_index > -1) { - if (Weapon_info[weapon_info_index].wi_flags2 & WIF2_PIERCE_SHIELDS) + if ((Weapon_info[weapon_info_index].wi_flags2 & WIF2_PIERCE_SHIELDS) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) { swp->current_primary_bank = i; return i; @@ -5450,7 +5484,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags) { if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank { - 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 (((((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 ) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) { // This weapon is the new candidate 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)); @@ -5476,7 +5510,7 @@ int ai_select_primary_weapon(object *objp, object *other_objp, int flags) { if (swp->primary_bank_weapons[i] > -1) // Make sure there is a weapon in the bank { - 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 (((((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 ) && !(Weapon_info[swp->primary_bank_weapons[i]].wi_flags2 & WIF2_CAPITAL_PLUS)&& !( Ship_info[Ships[other_objp->instance].ship_info_index].flags & ( SIF_BIG_SHIP | SIF_HUGE_SHIP))) { // This weapon is the new candidate 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 ); @@ -8797,7 +8831,7 @@ void ai_chase() else { float secondary_range_mult = (aip->ai_secondary_range_mult == FLT_MIN) - ? (Game_skill_level + 1 + aip->ai_class/2)/NUM_SKILL_LEVELS + ? (Game_skill_level + 1 + (3 * aip->ai_class/(Num_ai_classes - 1)))/NUM_SKILL_LEVELS : aip->ai_secondary_range_mult; firing_range = MIN((swip->max_speed * swip->lifetime * secondary_range_mult), swip->weapon_range); @@ -13782,7 +13816,7 @@ int ai_avoid_shockwave(object *objp, ai_info *aip) else { accelerate_ship(aip, 1.0f + dot_to_goal); if (dot_to_goal > 0.2f) { - if (!(objp->phys_info.flags & PF_AFTERBURNER_ON )) { + if (ai_maybe_fire_afterburner(Pl_objp, aip) && !(objp->phys_info.flags & PF_AFTERBURNER_ON )) { afterburners_start(objp); aip->afterburner_stop_time = Missiontime + 2*F1_0; } @@ -14569,28 +14603,50 @@ void init_aip_from_class_and_profile(ai_info *aip, ai_class *aicp, ai_profile_t aip->ai_secondary_range_mult = aicp->ai_secondary_range_mult[Game_skill_level]; aip->ai_class_autoscale = aicp->ai_class_autoscale; - //Apply multipliers from ai class to ai profiles values - aip->ai_cmeasure_fire_chance = profile->cmeasure_fire_chance[Game_skill_level] * aicp->ai_cmeasure_fire_chance[Game_skill_level]; - aip->ai_in_range_time = profile->in_range_time[Game_skill_level] * aicp->ai_in_range_time[Game_skill_level]; - aip->ai_link_ammo_levels_maybe = profile->link_ammo_levels_maybe[Game_skill_level] * aicp->ai_link_ammo_levels_maybe[Game_skill_level]; - aip->ai_link_ammo_levels_always = profile->link_ammo_levels_always[Game_skill_level] * aicp->ai_link_ammo_levels_always[Game_skill_level]; - aip->ai_primary_ammo_burst_mult = profile->primary_ammo_burst_mult[Game_skill_level] * aicp->ai_primary_ammo_burst_mult[Game_skill_level]; - aip->ai_link_energy_levels_maybe = profile->link_energy_levels_maybe[Game_skill_level] * aicp->ai_link_energy_levels_maybe[Game_skill_level]; - aip->ai_link_energy_levels_always = profile->link_energy_levels_always[Game_skill_level] * aicp->ai_link_energy_levels_always[Game_skill_level]; - aip->ai_predict_position_delay = (fix)(profile->predict_position_delay[Game_skill_level] * aicp->ai_predict_position_delay[Game_skill_level]); - aip->ai_shield_manage_delay = profile->shield_manage_delay[Game_skill_level] * aicp->ai_shield_manage_delay[Game_skill_level]; - aip->ai_ship_fire_delay_scale_friendly = profile->ship_fire_delay_scale_friendly[Game_skill_level] * aicp->ai_ship_fire_delay_scale_friendly[Game_skill_level]; - aip->ai_ship_fire_delay_scale_hostile = profile->ship_fire_delay_scale_hostile[Game_skill_level] * aicp->ai_ship_fire_delay_scale_hostile[Game_skill_level]; - aip->ai_ship_fire_secondary_delay_scale_friendly = profile->ship_fire_secondary_delay_scale_friendly[Game_skill_level] * aicp->ai_ship_fire_secondary_delay_scale_friendly[Game_skill_level]; - aip->ai_ship_fire_secondary_delay_scale_hostile = profile->ship_fire_secondary_delay_scale_hostile[Game_skill_level] * aicp->ai_ship_fire_secondary_delay_scale_hostile[Game_skill_level]; - aip->ai_turn_time_scale = profile->turn_time_scale[Game_skill_level] * aicp->ai_turn_time_scale[Game_skill_level]; - aip->ai_glide_attack_percent = profile->glide_attack_percent[Game_skill_level] * aicp->ai_glide_attack_percent[Game_skill_level]; - aip->ai_circle_strafe_percent = profile->circle_strafe_percent[Game_skill_level] * aicp->ai_circle_strafe_percent[Game_skill_level]; - aip->ai_glide_strafe_percent = profile->glide_strafe_percent[Game_skill_level] * aicp->ai_glide_strafe_percent[Game_skill_level]; - aip->ai_stalemate_time_thresh = profile->stalemate_time_thresh[Game_skill_level] * aicp->ai_stalemate_time_thresh[Game_skill_level]; - aip->ai_stalemate_dist_thresh = profile->stalemate_dist_thresh[Game_skill_level] * aicp->ai_stalemate_dist_thresh[Game_skill_level]; - aip->ai_chance_to_use_missiles_on_plr = (int)(profile->chance_to_use_missiles_on_plr[Game_skill_level] * aicp->ai_chance_to_use_missiles_on_plr[Game_skill_level]); - aip->ai_max_aim_update_delay = profile->max_aim_update_delay[Game_skill_level] * aicp->ai_max_aim_update_delay[Game_skill_level]; + //Apply overrides from ai class to ai profiles values + //Only override values which were explicitly set in the AI class + aip->ai_cmeasure_fire_chance = (aicp->ai_cmeasure_fire_chance[Game_skill_level] == FLT_MIN) ? + profile->cmeasure_fire_chance[Game_skill_level] : aicp->ai_cmeasure_fire_chance[Game_skill_level]; + aip->ai_in_range_time = (aicp->ai_in_range_time[Game_skill_level] == FLT_MIN) ? + profile->in_range_time[Game_skill_level] : aicp->ai_in_range_time[Game_skill_level]; + aip->ai_link_ammo_levels_maybe = (aicp->ai_link_ammo_levels_maybe[Game_skill_level] == FLT_MIN) ? + profile->link_ammo_levels_maybe[Game_skill_level] : aicp->ai_link_ammo_levels_maybe[Game_skill_level]; + aip->ai_link_ammo_levels_always = (aicp->ai_link_ammo_levels_always[Game_skill_level] == FLT_MIN) ? + profile->link_ammo_levels_always[Game_skill_level] : aicp->ai_link_ammo_levels_always[Game_skill_level]; + aip->ai_primary_ammo_burst_mult = (aicp->ai_primary_ammo_burst_mult[Game_skill_level] == FLT_MIN) ? + profile->primary_ammo_burst_mult[Game_skill_level] : aicp->ai_primary_ammo_burst_mult[Game_skill_level]; + aip->ai_link_energy_levels_maybe = (aicp->ai_link_energy_levels_maybe[Game_skill_level] == FLT_MIN) ? + profile->link_energy_levels_maybe[Game_skill_level] : aicp->ai_link_energy_levels_maybe[Game_skill_level]; + aip->ai_link_energy_levels_always = (aicp->ai_link_energy_levels_always[Game_skill_level] == FLT_MIN) ? + profile->link_energy_levels_always[Game_skill_level] : aicp->ai_link_energy_levels_always[Game_skill_level]; + aip->ai_predict_position_delay = (aicp->ai_predict_position_delay[Game_skill_level] == INT_MIN) ? + profile->predict_position_delay[Game_skill_level] : aicp->ai_predict_position_delay[Game_skill_level]; + aip->ai_shield_manage_delay = (aicp->ai_shield_manage_delay[Game_skill_level] == FLT_MIN) ? + profile->shield_manage_delay[Game_skill_level] : aicp->ai_shield_manage_delay[Game_skill_level]; + aip->ai_ship_fire_delay_scale_friendly = (aicp->ai_ship_fire_delay_scale_friendly[Game_skill_level] == FLT_MIN) ? + profile->ship_fire_delay_scale_friendly[Game_skill_level] : aicp->ai_ship_fire_delay_scale_friendly[Game_skill_level]; + aip->ai_ship_fire_delay_scale_hostile = (aicp->ai_ship_fire_delay_scale_hostile[Game_skill_level] == FLT_MIN) ? + profile->ship_fire_delay_scale_hostile[Game_skill_level] : aicp->ai_ship_fire_delay_scale_hostile[Game_skill_level]; + aip->ai_ship_fire_secondary_delay_scale_friendly = (aicp->ai_ship_fire_secondary_delay_scale_friendly[Game_skill_level] == FLT_MIN) ? + profile->ship_fire_secondary_delay_scale_friendly[Game_skill_level] : aicp->ai_ship_fire_secondary_delay_scale_friendly[Game_skill_level]; + aip->ai_ship_fire_secondary_delay_scale_hostile = (aicp->ai_ship_fire_secondary_delay_scale_hostile[Game_skill_level] == FLT_MIN) ? + profile->ship_fire_secondary_delay_scale_hostile[Game_skill_level] : aicp->ai_ship_fire_secondary_delay_scale_hostile[Game_skill_level]; + aip->ai_turn_time_scale = (aicp->ai_turn_time_scale[Game_skill_level] == FLT_MIN) ? + profile->turn_time_scale[Game_skill_level] : aicp->ai_turn_time_scale[Game_skill_level]; + aip->ai_glide_attack_percent = (aicp->ai_glide_attack_percent[Game_skill_level] == FLT_MIN) ? + profile->glide_attack_percent[Game_skill_level] : aicp->ai_glide_attack_percent[Game_skill_level]; + aip->ai_circle_strafe_percent = (aicp->ai_circle_strafe_percent[Game_skill_level] == FLT_MIN) ? + profile->circle_strafe_percent[Game_skill_level] : aicp->ai_circle_strafe_percent[Game_skill_level]; + aip->ai_glide_strafe_percent = (aicp->ai_glide_strafe_percent[Game_skill_level] == FLT_MIN) ? + profile->glide_strafe_percent[Game_skill_level] : aicp->ai_glide_strafe_percent[Game_skill_level]; + aip->ai_stalemate_time_thresh = (aicp->ai_stalemate_time_thresh[Game_skill_level] == FLT_MIN) ? + profile->stalemate_time_thresh[Game_skill_level] : aicp->ai_stalemate_time_thresh[Game_skill_level]; + aip->ai_stalemate_dist_thresh = (aicp->ai_stalemate_dist_thresh[Game_skill_level] == FLT_MIN) ? + profile->stalemate_dist_thresh[Game_skill_level] : aicp->ai_stalemate_dist_thresh[Game_skill_level]; + aip->ai_chance_to_use_missiles_on_plr = (aicp->ai_chance_to_use_missiles_on_plr[Game_skill_level] == INT_MIN) ? + profile->chance_to_use_missiles_on_plr[Game_skill_level] : aicp->ai_chance_to_use_missiles_on_plr[Game_skill_level]; + aip->ai_max_aim_update_delay = (aicp->ai_max_aim_update_delay[Game_skill_level] == FLT_MIN) ? + profile->max_aim_update_delay[Game_skill_level] : aicp->ai_max_aim_update_delay[Game_skill_level]; //Set flags (these act as overrides if set) aip->ai_profile_flags = 0; @@ -15067,9 +15123,17 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_ if ( hit_objp->parent_sig != Objects[hit_objp->parent].signature ){ return; } + + hitter_objnum = hit_objp->parent; + Assert((hitter_objnum >= 0) && (hitter_objnum < MAX_OBJECTS)); + objp_hitter = &Objects[hitter_objnum]; + // lets not check hits by ghosts any further either + if(objp_hitter->type & OBJ_GHOST) + return; + // Hit by a protected ship, don't attack it. - if (Objects[hit_objp->parent].flags & OF_PROTECTED) { + if (objp_hitter->flags & OF_PROTECTED) { if ((Ship_info[shipp->ship_info_index].flags & (SIF_FIGHTER | SIF_BOMBER)) && (aip->target_objnum == -1)) { if (aip->mode == AIM_CHASE) { if (aip->submode != SM_EVADE_WEAPON) { @@ -15091,9 +15155,6 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_ return; } - hitter_objnum = hit_objp->parent; - Assert((hitter_objnum >= 0) && (hitter_objnum < MAX_OBJECTS)); - objp_hitter = &Objects[hitter_objnum]; maybe_process_friendly_hit(objp_hitter, objp_ship, hit_objp); // Deal with player's friendly fire. ship_maybe_ask_for_help(shipp); diff --git a/code/ai/aigoals.cpp b/code/ai/aigoals.cpp index f06007eb71..d3ed21e893 100644 --- a/code/ai/aigoals.cpp +++ b/code/ai/aigoals.cpp @@ -389,37 +389,6 @@ void ai_mission_goal_complete( ai_info *aip ) } -int ai_get_subsystem_type( char *subsystem ) -{ - if ( strstr(subsystem, "engine") ) { - return SUBSYSTEM_ENGINE; - } else if ( strstr(subsystem, "radar") ) { - return SUBSYSTEM_RADAR; - } else if ( strstr(subsystem, "turret") ) { - return SUBSYSTEM_TURRET; - } else if ( strstr(subsystem, "navigation") ) { - return SUBSYSTEM_NAVIGATION; - } else if ( !strnicmp(subsystem, NOX("communication"), 13) ) { - return SUBSYSTEM_COMMUNICATION; - } else if ( !strnicmp(subsystem, NOX("weapons"), 7) ) { - return SUBSYSTEM_WEAPONS; - } else if ( !strnicmp(subsystem, NOX("sensors"), 7) ) { - return SUBSYSTEM_SENSORS; - } else if ( !strnicmp(subsystem, NOX("solar"), 5) ) { - return SUBSYSTEM_SOLAR; - } else if ( !strnicmp(subsystem, NOX("gas"), 3) ) { - return SUBSYSTEM_GAS_COLLECT; - } else if ( !strnicmp(subsystem, NOX("activator"), 9) ) { - return SUBSYSTEM_ACTIVATION; - } else { // If unrecognized type, set to engine so artist can continue working... - if (!Fred_running) { -// Int3(); // illegal subsystem type -- find allender - } - - return SUBSYSTEM_UNKNOWN; - } -} - // function to prune out goals which are no longer valid, based on a goal pointer passed in. // for instance, if we get passed a goal of "disable X", then any goals in the given goal array // which are destroy, etc, should get removed. goal list is the list of goals to purge. It is diff --git a/code/ai/aigoals.h b/code/ai/aigoals.h index 5994a26daf..4b1a9e5545 100644 --- a/code/ai/aigoals.h +++ b/code/ai/aigoals.h @@ -117,8 +117,6 @@ extern void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip ); extern void ai_mission_goal_complete( ai_info *aip ); extern void ai_mission_wing_goal_complete( int wingnum, ai_goal *remove_goalp ); -extern int ai_get_subsystem_type( char *subsystem ); -extern char *ai_get_subsystem_type_name(int type); extern void ai_update_goal_references(ai_goal *goals, int type, char *old_name, char *new_name); extern int query_referenced_in_ai_goals(ai_goal *goals, int type, char *name); extern char *ai_add_dock_name(char *str); diff --git a/code/ai/aiturret.cpp b/code/ai/aiturret.cpp index df6954415a..fe0e45c7f6 100644 --- a/code/ai/aiturret.cpp +++ b/code/ai/aiturret.cpp @@ -449,7 +449,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo) dist_comp = dist; // if weapon has optimum range set then use it - float optimum_range = ss->system_info->optimum_range; + float optimum_range = ss->optimum_range; if (optimum_range > 0.0f) { if (dist < optimum_range) { dist_comp = (2*optimum_range) - dist; @@ -457,7 +457,7 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo) } // if turret has been told to prefer targets from the current direction then do so - float favor_one_side = ss->system_info->favor_current_facing; + float favor_one_side = ss->favor_current_facing; if (favor_one_side >= 1.0f) { vm_vec_normalize(&vec_to_target); float dot_to_target = vm_vec_dot(&ss->turret_last_fire_direction, &vec_to_target); @@ -643,12 +643,35 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs eeo.nearest_objnum = -1; // here goes the new targeting priority setting - int n_tgt_priorities = turret_subsys->num_target_priorities; + int n_tgt_priorities; + int priority_weapon_idx = -1; + + // check for turret itself first + n_tgt_priorities = turret_subsys->num_target_priorities; + + // turret had no priorities set for it.. try weapons + if (n_tgt_priorities <= 0) { + if (swp->num_primary_banks > 0) + // first try highest primary slot... + priority_weapon_idx = swp->primary_bank_weapons[0]; + else + // ...and then secondary slot + priority_weapon_idx = swp->secondary_bank_weapons[0]; + + if (priority_weapon_idx > -1) + n_tgt_priorities = Weapon_info[priority_weapon_idx].num_targeting_priorities; + } + if (n_tgt_priorities > 0) { for(int i = 0; i < n_tgt_priorities; i++) { // courtesy of WMC... - ai_target_priority *tt = &Ai_tp_list[turret_subsys->target_priority[i]]; + ai_target_priority *tt; + if (priority_weapon_idx == -1) + tt = &Ai_tp_list[turret_subsys->target_priority[i]]; + else + tt = &Ai_tp_list[Weapon_info[priority_weapon_idx].targeting_priorities[i]]; + int n_types = tt->ship_type.size(); int n_s_classes = tt->ship_class.size(); int n_w_classes = tt->weapon_class.size(); @@ -1686,6 +1709,14 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) //aip = &Ai_info[Ships[objp->instance].ai_index]; + // Wanderer - make sure turrets already have all the data + if ( !(tp->flags & MSS_FLAG_TURRET_MATRIX) ) + { + if (!(tp->turret_gun_sobj == tp->subobj_num)) + { + model_make_turret_matrix(Ship_info[shipp->ship_info_index].model_num, tp ); + } + } // Use the turret info for all guns, not one gun in particular. vec3d gvec, gpos; @@ -1715,8 +1746,12 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum) //WMC - build a list of valid weapons. Fire spawns if there are any. float dist_to_enemy = 0.0f; - if(lep != NULL) - dist_to_enemy = MAX(0,vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &gpos) - lep->radius); + if(lep != NULL) { + if (The_mission.ai_profile->flags2 & AIPF2_TURRETS_IGNORE_TARGET_RADIUS) + dist_to_enemy = MAX(0,vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &gpos)); + else + dist_to_enemy = MAX(0,vm_vec_normalized_dir(&v2e, &predicted_enemy_pos, &gpos) - lep->radius); + } int valid_weapons[MAX_SHIP_PRIMARY_BANKS + MAX_SHIP_SECONDARY_BANKS]; int num_valid = 0; diff --git a/code/asteroid/asteroid.h b/code/asteroid/asteroid.h index 3f97d8b6f3..c6ed8e260c 100644 --- a/code/asteroid/asteroid.h +++ b/code/asteroid/asteroid.h @@ -20,7 +20,7 @@ struct object; struct polymodel; struct collision_info_struct; -#define MAX_ASTEROIDS 256 +#define MAX_ASTEROIDS 512 #define NUM_DEBRIS_SIZES 3 #define NUM_DEBRIS_POFS 3 // Number of POFs per debris size diff --git a/code/bmpman/bm_internal.h b/code/bmpman/bm_internal.h index 50f6038f43..3c33a57135 100644 --- a/code/bmpman/bm_internal.h +++ b/code/bmpman/bm_internal.h @@ -30,17 +30,18 @@ #define BM_TYPE_PCX 2 #define BM_TYPE_TGA 3 // 16 or 32 bit targa #define BM_TYPE_DDS 4 // generic identifier for DDS -#define BM_TYPE_JPG 5 // 32 bit jpeg -#define BM_TYPE_ANI 6 // in-house ANI format -#define BM_TYPE_EFF 7 // specifies any type of animated image, the EFF itself is just text +#define BM_TYPE_PNG 5 // PNG +#define BM_TYPE_JPG 6 // 32 bit jpeg +#define BM_TYPE_ANI 7 // in-house ANI format +#define BM_TYPE_EFF 8 // specifies any type of animated image, the EFF itself is just text // c-type types ( used in: bm_bitmaps[i].c_type ) -#define BM_TYPE_DXT1 8 // 24 bit with switchable alpha (compressed) -#define BM_TYPE_DXT3 9 // 32 bit with 4 bit alpha (compressed) -#define BM_TYPE_DXT5 10 // 32 bit with 8 bit alpha (compressed) -#define BM_TYPE_CUBEMAP_DDS 11 // generic DDS cubemap (uncompressed cubemap surface) -#define BM_TYPE_CUBEMAP_DXT1 12 // 24-bit cubemap (compressed cubemap surface) -#define BM_TYPE_CUBEMAP_DXT3 13 // 32-bit cubemap (compressed cubemap surface) -#define BM_TYPE_CUBEMAP_DXT5 14 // 32-bit cubemap (compressed cubemap surface) +#define BM_TYPE_DXT1 9 // 24 bit with switchable alpha (compressed) +#define BM_TYPE_DXT3 10 // 32 bit with 4 bit alpha (compressed) +#define BM_TYPE_DXT5 11 // 32 bit with 8 bit alpha (compressed) +#define BM_TYPE_CUBEMAP_DDS 12 // generic DDS cubemap (uncompressed cubemap surface) +#define BM_TYPE_CUBEMAP_DXT1 13 // 24-bit cubemap (compressed cubemap surface) +#define BM_TYPE_CUBEMAP_DXT3 14 // 32-bit cubemap (compressed cubemap surface) +#define BM_TYPE_CUBEMAP_DXT5 15 // 32-bit cubemap (compressed cubemap surface) // special types ( used in: bm_bitmaps[i].type ) #define BM_TYPE_RENDER_TARGET_STATIC 16 // 24/32 bit setup internally as a static render target #define BM_TYPE_RENDER_TARGET_DYNAMIC 17 // 24/32 bit setup internally as a dynamic render target @@ -118,6 +119,7 @@ extern bitmap_entry bm_bitmaps[MAX_BITMAPS]; // image specific lock functions void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ); void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ); +void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ); void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ); void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ); void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ); diff --git a/code/bmpman/bmpman.cpp b/code/bmpman/bmpman.cpp index 89730e5d20..9c5bdb1b27 100644 --- a/code/bmpman/bmpman.cpp +++ b/code/bmpman/bmpman.cpp @@ -31,6 +31,7 @@ #include "ship/ship.h" #include "ddsutils/ddsutils.h" #include "cfile/cfile.h" +#include "pngutils/pngutils.h" #include "jpgutils/jpgutils.h" #include "parse/parselo.h" @@ -58,8 +59,8 @@ int bm_inited = 0; int Bm_paging = 0; // locals -static uint Bm_next_signature = 0x1234; -static int bm_next_handle = 1; +static unsigned int Bm_next_signature = 0x1234; +static int bm_next_handle = 0; int Bm_low_mem = 0; // Bm_max_ram - How much RAM bmpman can use for textures. // Set to <1 to make it use all it wants. @@ -96,10 +97,10 @@ int bm_get_next_handle() // Returns true if bitmap n can free it's data. static void bm_free_data(int n, bool release = false) { - bitmap_entry *be; - bitmap *bmp; + bitmap_entry *be; + bitmap *bmp; - Assert( n >= 0 && n < MAX_BITMAPS ); + Assert( (n >= 0) && (n < MAX_BITMAPS) ); be = &bm_bitmaps[n]; bmp = &be->bm; @@ -162,10 +163,10 @@ SkipFree: // NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!! static void bm_free_data_fast(int n) { - bitmap_entry *be; - bitmap *bmp; + bitmap_entry *be; + bitmap *bmp; - Assert( n >= 0 && n < MAX_BITMAPS ); + Assert( (n >= 0) && (n < MAX_BITMAPS) ); be = &bm_bitmaps[n]; bmp = &be->bm; @@ -365,7 +366,7 @@ int bm_create( int bpp, int w, int h, void *data, int flags ) bm_bitmaps[n].bm.h = (short) h; bm_bitmaps[n].bm.rowsize = (short) w; bm_bitmaps[n].bm.bpp = (ubyte) bpp; - bm_bitmaps[n].bm.flags = flags; + bm_bitmaps[n].bm.flags = (ubyte) flags; bm_bitmaps[n].bm.data = 0; bm_bitmaps[n].bm.palette = NULL; @@ -504,9 +505,9 @@ int bm_load( char *real_filename ) // Lets find out what type it is { - const int NUM_TYPES = 4; - const ubyte type_list[NUM_TYPES] = { BM_TYPE_DDS, BM_TYPE_TGA, BM_TYPE_JPG, BM_TYPE_PCX }; - const char *ext_list[NUM_TYPES] = { ".dds", ".tga", ".jpg", ".pcx" }; + const int NUM_TYPES = 5; + const ubyte type_list[NUM_TYPES] = { BM_TYPE_DDS, BM_TYPE_TGA, BM_TYPE_PNG, BM_TYPE_JPG, BM_TYPE_PCX }; + const char *ext_list[NUM_TYPES] = { ".dds", ".tga", ".png", ".jpg", ".pcx" }; // see if it's already loaded (checks for any type with filename) if ( bm_load_sub_fast(filename, &handle) ) @@ -557,11 +558,11 @@ int bm_load( char *real_filename ) bm_bitmaps[free_slot].type = type; bm_bitmaps[free_slot].comp_type = c_type; bm_bitmaps[free_slot].signature = Bm_next_signature++; - bm_bitmaps[free_slot].bm.w = short(w); - bm_bitmaps[free_slot].bm.rowsize = short(w); - bm_bitmaps[free_slot].bm.h = short(h); + bm_bitmaps[free_slot].bm.w = (short) w; + bm_bitmaps[free_slot].bm.rowsize = (short) w; + bm_bitmaps[free_slot].bm.h = (short) h; bm_bitmaps[free_slot].bm.bpp = 0; - bm_bitmaps[free_slot].bm.true_bpp = bpp; + bm_bitmaps[free_slot].bm.true_bpp = (ubyte) bpp; bm_bitmaps[free_slot].bm.flags = 0; bm_bitmaps[free_slot].bm.data = 0; bm_bitmaps[free_slot].bm.palette = NULL; @@ -619,6 +620,9 @@ DCF(bm_frag,"Shows BmpMan fragmentation") gr_set_color(255,0,0); break; case BM_TYPE_USER: + case BM_TYPE_TGA: + case BM_TYPE_PNG: + case BM_TYPE_DDS: gr_set_color(0,255,0); break; case BM_TYPE_ANI: @@ -712,6 +716,8 @@ int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps, c_type = BM_TYPE_DDS; } else if (!stricmp(NOX("tga"), ext)) { c_type = BM_TYPE_TGA; + } else if (!stricmp(NOX("png"), ext)) { + c_type = BM_TYPE_PNG; } else if (!stricmp(NOX("jpg"), ext)) { c_type = BM_TYPE_JPG; } else if (!stricmp(NOX("pcx"), ext)) { @@ -954,10 +960,10 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram bm_bitmaps[n+i].info.ani.num_frames = anim_frames; bm_bitmaps[n+i].info.ani.fps = (ubyte)anim_fps; bm_bitmaps[n+i].info.ani.keyframe = key; - bm_bitmaps[n+i].bm.w = short(anim_width); - bm_bitmaps[n+i].bm.rowsize = short(anim_width); - bm_bitmaps[n+i].bm.h = short(anim_height); - if ( reduced ) { + bm_bitmaps[n+i].bm.w = (short) anim_width ; + bm_bitmaps[n+i].bm.rowsize = (short) anim_width; + bm_bitmaps[n+i].bm.h = (short) anim_height; + if ( reduced ) { bm_bitmaps[n+i].bm.w /= 2; bm_bitmaps[n+i].bm.rowsize /= 2; bm_bitmaps[n+i].bm.h /= 2; @@ -1078,7 +1084,7 @@ int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int * } } -uint bm_get_signature( int handle ) +unsigned int bm_get_signature(int handle) { if ( !bm_inited ) bm_init(); @@ -1134,30 +1140,8 @@ static void bm_convert_format( int bitmapnum, bitmap *bmp, ubyte bpp, ubyte flag // basically, map the bitmap into the current palette. used to be done for all pcx's, now just for // Fred, since its the only thing that uses the software tmapper void bm_swizzle_8bit_for_fred(bitmap_entry *be, bitmap *bmp, ubyte *data, ubyte *palette) -{ -/* 2004/10/17 - taylor - no longer needed since FRED is OGL now - int pcx_xparent_index = -1; - int i; - int r, g, b; - ubyte palxlat[256]; - - for (i=0; i<256; i++ ) { - r = palette[i*3]; - g = palette[i*3+1]; - b = palette[i*3+2]; - if ( g == 255 && r == 0 && b == 0 ) { - palxlat[i] = 255; - pcx_xparent_index = i; - } else { - palxlat[i] = (ubyte)(palette_find( r, g, b )); - } - } - for (i=0; iw * bmp->h; i++ ) { - ubyte c = palxlat[data[i]]; - data[i] = c; - } - be->palette_checksum = gr_palette_checksum; -*/ +{ +/* 2004/10/17 - taylor - no longer needed since FRED is OGL now*/ } void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ) @@ -1300,8 +1284,8 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt dv = ( the_anim->height*F1_0 ) / bm->h; for (h = 0; h < bm->h; h++) { - ushort *drow = &((ushort*)dptr)[bm->w * h]; - ushort *srow = &((ushort*)sptr)[f2i(v)*the_anim->width]; + unsigned short *drow = &((unsigned short*)dptr)[bm->w * h]; + unsigned short *srow = &((unsigned short*)sptr)[f2i(v)*the_anim->width]; utmp = u; @@ -1334,9 +1318,6 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ) { - // int idx; - // ushort bit_16; - // Unload any existing data bm_free_data( bitmapnum ); @@ -1363,22 +1344,6 @@ void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, uby break; case 8: // Going from 8 bpp to something (probably only for aabitmaps) - /* - Assert(flags & BMP_AABITMAP); - bmp->bpp = 16; - bmp->data = (uint)vm_malloc(bmp->w * bmp->h * 2); - bmp->flags = be->info.user.flags; - bmp->palette = NULL; - - // go through and map the pixels - for(idx=0; idxw * bmp->h; idx++){ - bit_16 = (ushort)((ubyte*)be->info.user.data)[idx]; - Assert(bit_16 <= 255); - - // stuff the final result - memcpy((char*)bmp->data + (idx * 2), &bit_16, sizeof(ushort)); - } - */ Assert(flags & BMP_AABITMAP); bmp->bpp = bpp; bmp->flags = be->info.user.flags; @@ -1486,20 +1451,20 @@ void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt #if BYTE_ORDER == BIG_ENDIAN // same as with TGA, we need to byte swap 16 & 32-bit, uncompressed, DDS images if ( (be->comp_type == BM_TYPE_DDS) || (be->comp_type == BM_TYPE_CUBEMAP_DDS) ) { - uint i = 0; + unsigned int i = 0; if (dds_bpp == 32) { - uint *swap_tmp; + unsigned int *swap_tmp; - for (i = 0; i < (uint)be->mem_taken; i += 4) { - swap_tmp = (uint *)(data + i); + for (i = 0; i < (unsigned int)be->mem_taken; i += 4) { + swap_tmp = (unsigned int *)(data + i); *swap_tmp = INTEL_INT(*swap_tmp); } } else if (dds_bpp == 16) { - ushort *swap_tmp; + unsigned short *swap_tmp; - for (i = 0; i < (uint)be->mem_taken; i += 2) { - swap_tmp = (ushort *)(data + i); + for (i = 0; i < (unsigned int)be->mem_taken; i += 2) { + swap_tmp = (unsigned short *)(data + i); *swap_tmp = INTEL_SHORT(*swap_tmp); } } @@ -1520,6 +1485,55 @@ void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt #endif } +// lock a PNG file +void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ) +{ + ubyte *data = NULL; + //assume 32 bit - libpng should expand everything + int d_size; + int png_error = PNG_ERROR_INVALID; + char filename[MAX_FILENAME_LEN]; + //int size = bmp->w * bmp->h * d_size; + + // Unload any existing data + bm_free_data( bitmapnum ); + + // should never try to make an aabitmap out of a png + Assert(!(flags & BMP_AABITMAP)); + + // allocate bitmap data + Assert( bmp->w * bmp->h > 0 ); + + //if it's not 32-bit, we expand when we read it + bmp->bpp = 32; + d_size = bmp->bpp >> 3; + //we waste memory if it turns out to be 24-bit, but the way this whole thing works is dodgy anyway + data = (ubyte*)bm_malloc(bitmapnum, bmp->w * bmp->h * d_size); + if (data == NULL) + return; + memset( data, 0, bmp->w * bmp->h * d_size); + bmp->data = (ptr_u)data; + bmp->palette = NULL; + + Assert( &be->bm == bmp ); + + // make sure we are using the correct filename in the case of an EFF. + // this will populate filename[] whether it's EFF or not + EFF_FILENAME_CHECK; + + //bmp->bpp gets set correctly in here after reading into memory + png_error = png_read_bitmap( filename, data, &bmp->bpp, d_size, be->dir_type ); + + if ( png_error != PNG_ERROR_NONE ) { + bm_free_data( bitmapnum ); + return; + } + +#ifdef BMPMAN_NDEBUG + Assert( be->data_size > 0 ); +#endif +} + // lock a JPEG file void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags ) { @@ -1703,7 +1717,7 @@ void bm_unlock( int handle ) Assert( bm_bitmaps[bitmapnum].handle == handle ); // INVALID BITMAP HANDLE - Assert(bitmapnum >= 0 && bitmapnum < MAX_BITMAPS); + Assert( (bitmapnum >= 0) && (bitmapnum < MAX_BITMAPS) ); be = &bm_bitmaps[bitmapnum]; bmp = &be->bm; @@ -1756,7 +1770,7 @@ void bm_get_palette(int handle, ubyte *pal, char *name) int bm_release(int handle, int clear_render_targets) { - bitmap_entry *be; + bitmap_entry *be; int n = handle % MAX_BITMAPS; @@ -1769,7 +1783,7 @@ int bm_release(int handle, int clear_render_targets) Assert( be->handle == handle ); // INVALID BITMAP HANDLE - if ( !clear_render_targets && (be->type == BM_TYPE_RENDER_TARGET_STATIC) || (be->type == BM_TYPE_RENDER_TARGET_DYNAMIC) ) { + if ( !clear_render_targets && ((be->type == BM_TYPE_RENDER_TARGET_STATIC) || (be->type == BM_TYPE_RENDER_TARGET_DYNAMIC)) ) { nprintf(("BmpMan", "Tried to release a render target!\n")); return 0; } @@ -1859,13 +1873,12 @@ int bm_release(int handle, int clear_render_targets) // int bm_unload( int handle, int clear_render_targets ) { - bitmap_entry *be; - bitmap *bmp; + bitmap_entry *be; + bitmap *bmp; int n = handle % MAX_BITMAPS; - - Assert(n >= 0 && n < MAX_BITMAPS); + Assert( (n >= 0) && (n < MAX_BITMAPS) ); be = &bm_bitmaps[n]; bmp = &be->bm; @@ -1924,13 +1937,13 @@ int bm_unload( int handle, int clear_render_targets ) // (NOTE that bm_free_data_fast() is used here and NOT bm_free_data()!) int bm_unload_fast( int handle, int clear_render_targets ) { - bitmap_entry *be; - bitmap *bmp; + bitmap_entry *be; + bitmap *bmp; int n = handle % MAX_BITMAPS; - Assert(n >= 0 && n < MAX_BITMAPS); + Assert( (n >= 0) && (n < MAX_BITMAPS) ); be = &bm_bitmaps[n]; bmp = &be->bm; @@ -2301,51 +2314,51 @@ void (*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte * void bm_set_components_argb_16_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { if ( *av == 0 ) { - *((ushort*)pixel) = (ushort)Gr_current_green->mask; + *((unsigned short*)pixel) = (unsigned short)Gr_current_green->mask; return; } - *((ushort*)pixel) = (ushort)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); - *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); - *((ushort*)pixel) |= (ushort)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); + *((unsigned short*)pixel) = (unsigned short)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); + *((unsigned short*)pixel) |= (unsigned short)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); + *((unsigned short*)pixel) |= (unsigned short)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); } void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { if ( *av == 0 ) { - *((uint*)pixel) = (uint)Gr_current_green->mask; + *((unsigned int*)pixel) = (unsigned int)Gr_current_green->mask; return; } - *((uint*)pixel) = (uint)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); - *((uint*)pixel) |= (uint)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); - *((uint*)pixel) |= (uint)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); + *((unsigned int*)pixel) = (unsigned int)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); + *((unsigned int*)pixel) |= (unsigned int)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); + *((unsigned int*)pixel) |= (unsigned int)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); } void bm_set_components_argb_16_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { if ( *av == 0 ) { - *((ushort*)pixel) = 0; + *((unsigned short*)pixel) = 0; return; } - *((ushort*)pixel) = (ushort)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); - *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); - *((ushort*)pixel) |= (ushort)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); - *((ushort*)pixel) |= (ushort)(Gr_current_alpha->mask); + *((unsigned short*)pixel) = (unsigned short)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); + *((unsigned short*)pixel) |= (unsigned short)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); + *((unsigned short*)pixel) |= (unsigned short)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); + *((unsigned short*)pixel) |= (unsigned short)(Gr_current_alpha->mask); } void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { if ( *av == 0 ) { - *((uint*)pixel) = 0; + *((unsigned int*)pixel) = 0; return; } - *((uint*)pixel) = (uint)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); - *((uint*)pixel) |= (uint)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); - *((uint*)pixel) |= (uint)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); - *((uint*)pixel) |= (uint)(Gr_current_alpha->mask); + *((unsigned int*)pixel) = (unsigned int)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); + *((unsigned int*)pixel) |= (unsigned int)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); + *((unsigned int*)pixel) |= (unsigned int)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); + *((unsigned int*)pixel) |= (unsigned int)(Gr_current_alpha->mask); } // for selecting pixel formats @@ -2400,23 +2413,23 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) if(r != NULL){ if(bit_32){ - *r = ubyte(( (*((uint*)pixel) & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale); + *r = ubyte(( (*((unsigned int*)pixel) & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale); } else { - *r = ubyte(( ( ((ushort*)pixel)[0] & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale); + *r = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale); } } if(g != NULL){ if(bit_32){ - *g = ubyte(( (*((uint*)pixel) & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale); + *g = ubyte(( (*((unsigned int*)pixel) & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale); } else { - *g = ubyte(( ( ((ushort*)pixel)[0] & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale); + *g = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale); } } if(b != NULL){ if(bit_32){ - *b = ubyte(( (*((uint*)pixel) & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale); + *b = ubyte(( (*((unsigned int*)pixel) & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale); } else { - *b = ubyte(( ( ((ushort*)pixel)[0] & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale); + *b = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale); } } @@ -2425,7 +2438,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) *a = 1; Assert(!bit_32); - if(!( ((ushort*)pixel)[0] & 0x8000)){ + if(!( ((unsigned short*)pixel)[0] & 0x8000)){ *a = 0; } } @@ -2456,6 +2469,7 @@ int bm_is_compressed(int num) if (!Use_compressed_textures) return 0; + Assert( (n >= 0) && (n < MAX_BITMAPS) ); Assert(num == bm_bitmaps[n].handle); type = bm_bitmaps[n].comp_type; @@ -2519,6 +2533,7 @@ int bm_get_size(int num) { int n = num % MAX_BITMAPS; + Assert( (n >= 0) && (n < MAX_BITMAPS) ); Assert(num == bm_bitmaps[n].handle); return bm_bitmaps[n].mem_taken; @@ -2528,6 +2543,7 @@ int bm_get_num_mipmaps(int num) { int n = num % MAX_BITMAPS; + Assert( (n >= 0) && (n < MAX_BITMAPS) ); Assert( num == bm_bitmaps[n].handle ); if (bm_bitmaps[n].num_mipmaps == 0) @@ -2547,7 +2563,6 @@ int bm_convert_color_index_to_BGR(int num, ubyte **out_data) int i, j, bpp = 0, size = 0; int index = 0, mult = 3; - Assert( out_data != NULL ); Assert( num == bm_bitmaps[n].handle ); @@ -2640,7 +2655,6 @@ void bm_print_bitmaps() #endif } - // this will create a render target as close to the desiered resolution as posable of the following base types: // - BMP_FLAG_RENDER_TARGET_STATIC // static render targets are ones that you intend to draw to once or not very often in game @@ -2699,12 +2713,12 @@ int bm_make_render_target( int width, int height, int flags ) bm_bitmaps[n].type = (flags & BMP_FLAG_RENDER_TARGET_STATIC) ? BM_TYPE_RENDER_TARGET_STATIC : BM_TYPE_RENDER_TARGET_DYNAMIC; bm_bitmaps[n].signature = Bm_next_signature++; sprintf( bm_bitmaps[n].filename, "RT_%dx%d+%d", w, h, bpp ); - bm_bitmaps[n].bm.w = (short)w; - bm_bitmaps[n].bm.h = (short)h; - bm_bitmaps[n].bm.rowsize = (short)w; - bm_bitmaps[n].bm.bpp = bpp; - bm_bitmaps[n].bm.true_bpp = bpp; - bm_bitmaps[n].bm.flags = (ubyte)flags; + bm_bitmaps[n].bm.w = (short) w; + bm_bitmaps[n].bm.h = (short) h; + bm_bitmaps[n].bm.rowsize = (short) w; + bm_bitmaps[n].bm.bpp = (ubyte) bpp; + bm_bitmaps[n].bm.true_bpp = (ubyte) bpp; + bm_bitmaps[n].bm.flags = (ubyte) flags; bm_bitmaps[n].bm.data = 0; bm_bitmaps[n].bm.palette = NULL; bm_bitmaps[n].num_mipmaps = mm_lvl; @@ -2781,14 +2795,3 @@ int bm_set_render_target(int handle, int face) return 0; } -/*void bm_save_render_target(int handle, int flags) -{ - int n = handle % MAX_BITMAPS; - - Assert( n >= 0 ); - - Assert( flags & BMP_FLAG_RENDER_TARGET_STATIC ); - - gr_bm_save_render_target(slot, flags, data); - -}*/ diff --git a/code/cfile/cfile.cpp b/code/cfile/cfile.cpp index 1d42e3781b..7e9904f44f 100644 --- a/code/cfile/cfile.cpp +++ b/code/cfile/cfile.cpp @@ -50,10 +50,10 @@ char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = ""; cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = { // What type this is Path Extensions Parent type { CF_TYPE_INVALID, NULL, NULL, CF_TYPE_INVALID }, - // Root must be index 1!! + // Root must be index 1!! { CF_TYPE_ROOT, "", ".mve .ogg", CF_TYPE_ROOT }, { CF_TYPE_DATA, "data", ".cfg .log .txt", CF_TYPE_ROOT }, - { CF_TYPE_MAPS, "data" DIR_SEPARATOR_STR "maps", ".pcx .ani .eff .tga .jpg .dds", CF_TYPE_DATA }, + { CF_TYPE_MAPS, "data" DIR_SEPARATOR_STR "maps", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA }, { CF_TYPE_TEXT, "data" DIR_SEPARATOR_STR "text", ".txt .net", CF_TYPE_DATA }, { CF_TYPE_MODELS, "data" DIR_SEPARATOR_STR "models", ".pof", CF_TYPE_DATA }, { CF_TYPE_TABLES, "data" DIR_SEPARATOR_STR "tables", ".tbl .tbm", CF_TYPE_DATA }, @@ -69,22 +69,22 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = { { CF_TYPE_VOICE_TRAINING, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "training", ".wav .ogg", CF_TYPE_VOICE }, { CF_TYPE_MUSIC, "data" DIR_SEPARATOR_STR "music", ".wav .ogg", CF_TYPE_DATA }, { CF_TYPE_MOVIES, "data" DIR_SEPARATOR_STR "movies", ".mve .msb .ogg", CF_TYPE_DATA }, - { CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff .jpg", CF_TYPE_DATA }, + { CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff .png .jpg", CF_TYPE_DATA }, { CF_TYPE_FONT, "data" DIR_SEPARATOR_STR "fonts", ".vf .ttf", CF_TYPE_DATA }, - { CF_TYPE_EFFECTS, "data" DIR_SEPARATOR_STR "effects", ".ani .eff .pcx .neb .tga .jpg .dds .sdr", CF_TYPE_DATA }, - { CF_TYPE_HUD, "data" DIR_SEPARATOR_STR "hud", ".pcx .ani .eff .tga .jpg .dds", CF_TYPE_DATA }, + { CF_TYPE_EFFECTS, "data" DIR_SEPARATOR_STR "effects", ".ani .eff .pcx .neb .tga .jpg .png .dds .sdr", CF_TYPE_DATA }, + { CF_TYPE_HUD, "data" DIR_SEPARATOR_STR "hud", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA }, { CF_TYPE_PLAYERS, "data" DIR_SEPARATOR_STR "players", ".hcf", CF_TYPE_DATA }, - { CF_TYPE_PLAYER_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "images", ".pcx .dds", CF_TYPE_PLAYERS }, - { CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .dds", CF_TYPE_PLAYERS }, + { CF_TYPE_PLAYER_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "images", ".pcx .png .dds", CF_TYPE_PLAYERS }, + { CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS }, { CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css", CF_TYPE_PLAYERS }, - { CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS }, + { CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr", CF_TYPE_PLAYERS }, { CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .ibx .tsb", CF_TYPE_DATA }, //clr=cached color - { CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .dds .fs2 .txt", CF_TYPE_DATA }, + { CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .dds .fs2 .txt", CF_TYPE_DATA }, { CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA }, { CF_TYPE_CONFIG, "data" DIR_SEPARATOR_STR "config", ".cfg", CF_TYPE_DATA }, { CF_TYPE_DEMOS, "data" DIR_SEPARATOR_STR "demos", ".fsd", CF_TYPE_DATA }, - { CF_TYPE_CBANIMS, "data" DIR_SEPARATOR_STR "cbanims", ".pcx .ani .eff .tga .jpg .dds", CF_TYPE_DATA }, - { CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .dds", CF_TYPE_DATA }, + { CF_TYPE_CBANIMS, "data" DIR_SEPARATOR_STR "cbanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA }, + { CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA }, { CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc", CF_TYPE_DATA }, { CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA }, }; diff --git a/code/cfile/cfilesystem.cpp b/code/cfile/cfilesystem.cpp index 2fec28edb2..b97c4ce753 100644 --- a/code/cfile/cfilesystem.cpp +++ b/code/cfile/cfilesystem.cpp @@ -155,7 +155,7 @@ cf_root *cf_create_root() // return the # of packfiles which exist int cf_get_packfile_count(cf_root *root) { - char filespec[MAX_PATH_LEN]; + SCP_string filespec; int i; int packfile_count; @@ -163,34 +163,24 @@ int cf_get_packfile_count(cf_root *root) packfile_count = 0; for (i=CF_TYPE_ROOT; ipath ); + filespec = root->path; if(strlen(Pathtypes[i].path)) { - if(strlen(filespec) + strlen(Pathtypes[i].path) + strlen(DIR_SEPARATOR_STR) - >= sizeof(filespec)) + filespec += Pathtypes[ i ].path; + if ( filespec[ filespec.length( ) - 1 ] != DIR_SEPARATOR_CHAR ) { - Warning(LOCATION, "Path '%s' too long to add '%s' safely.", filespec, Pathtypes[i].path); - continue; - } - strcat_s( filespec, Pathtypes[i].path ); - if ( filespec[strlen(filespec)-1] != DIR_SEPARATOR_CHAR ) - { - strcat_s( filespec, DIR_SEPARATOR_STR ); + filespec += DIR_SEPARATOR_STR; } } #if defined _WIN32 - if(strlen(filespec) + 4 >= sizeof(filespec)) { - Warning(LOCATION, "Could not concatenate '*.vp' to filespec; path too long."); - continue; - } - strcat_s( filespec, "*.vp" ); + filespec += "*.vp"; int find_handle; _finddata_t find; - find_handle = _findfirst( filespec, &find ); + find_handle = _findfirst( filespec.c_str( ), &find ); if (find_handle != -1) { do { @@ -203,15 +193,11 @@ int cf_get_packfile_count(cf_root *root) _findclose( find_handle ); } #elif defined SCP_UNIX - if(strlen(filespec) + 10 >= sizeof(filespec)) { - Warning(LOCATION, "Could not concatenate '*.vp' to filespec; path too long."); - continue; - } - strcat_s( filespec, "*.[vV][pP]" ); + filespec += "*.[vV][pP]"; glob_t globinfo; memset(&globinfo, 0, sizeof(globinfo)); - int status = glob(filespec, 0, NULL, &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 diff --git a/code/cmdline/cmdline.cpp b/code/cmdline/cmdline.cpp index 75e5a7de90..fbc10eb2d0 100644 --- a/code/cmdline/cmdline.cpp +++ b/code/cmdline/cmdline.cpp @@ -117,6 +117,7 @@ Flag exe_params[] = { "-missile_lighting", "Apply Lighting to Missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", }, { "-normal", "Enable normal maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" }, { "-3dshockwave", "Enable 3D shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" }, + { "-post_process", "Enable post processing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" }, { "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", }, { "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", }, @@ -260,6 +261,8 @@ cmdline_parm noemissive_arg("-no_emissive_light", NULL); // Cmdline_no_emissive cmdline_parm normal_arg("-normal", NULL); // Cmdline_normal -- enable normal mapping cmdline_parm height_arg("-height", NULL); // Cmdline_height -- enable support for parallax mapping cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL); +cmdline_parm postprocess_arg("-post_process", NULL); +cmdline_parm bloom_intensity_arg("-bloom_intensity", NULL); float Cmdline_clip_dist = Default_min_draw_distance; float Cmdline_fov = 0.75f; @@ -278,6 +281,8 @@ int Cmdline_no_emissive = 0; int Cmdline_normal = 0; int Cmdline_height = 0; int Cmdline_enable_3d_shockwave = 0; +int Cmdline_postprocess = 0; +int Cmdline_bloom_intensity = 75; // Game Speed related cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL); // Cmdline_cache_bitmaps @@ -491,7 +496,7 @@ char *drop_extra_chars(char *str) void parm_stuff_args(cmdline_parm *parm, char *cmdline) { char buffer[1024]; - memset(buffer, 0, 1024); + memset( buffer, 0, sizeof( buffer ) ); char *dest = buffer; char *saved_args = NULL; @@ -527,13 +532,13 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline) if (saved_args != NULL) { // saved args go first, then new arg - strcpy(parm->args, saved_args); + strcpy_s(parm->args, size, saved_args); // add a separator too, so that we can tell the args apart - strcat(parm->args, ","); + strcat_s(parm->args, size, ","); // now the new arg - strcat(parm->args, buffer); + strcat_s(parm->args, size, buffer); } else { - strcpy(parm->args, buffer); + strcpy_s(parm->args, size, buffer); } } @@ -629,7 +634,11 @@ void os_validate_parms(char *cmdline) #else // if we got a -help, --help, -h, or -? then show the help text, otherwise show unknown option if ( !stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?") ) { - printf("FS2 Open: The Source Code Project, version %i.%i.%i\n", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD); + if (FS_VERSION_REVIS == 0) { + printf("FreeSpace 2 Open, version %i.%i.%i\n", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD); + } else { + printf("FreeSpace 2 Open, version %i.%i.%i.%i\n", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD, FS_VERSION_REVIS); + } printf("Website: http://scp.indiegames.us\n"); printf("Mantis (bug reporting): http://scp.indiegames.us/mantis/\n\n"); printf("Usage: fs2_open [options]\n"); @@ -1072,8 +1081,8 @@ bool SetCmdlineParams() // Ok - mod stacking support int len = strlen(Cmdline_mod); char *modlist = new char[len+2]; - memset(modlist, 0, len+2); - strcpy(modlist, Cmdline_mod); + memset( modlist, 0, len + 2 ); + strcpy_s(modlist, len+2, Cmdline_mod); //modlist[len]= '\0'; // double null termination at the end @@ -1379,6 +1388,16 @@ bool SetCmdlineParams() Cmdline_enable_3d_shockwave = 1; } + if ( postprocess_arg.found() ) + { + Cmdline_postprocess = 1; + } + + if ( bloom_intensity_arg.found() ) + { + Cmdline_bloom_intensity = bloom_intensity_arg.get_int(); + } + return true; } @@ -1397,12 +1416,11 @@ int fred2_parse_cmdline(int argc, char *argv[]) arglen += argc + 2; // leave room for the separators cmdline = new char [arglen+1]; i = 1; - memset(cmdline, 0, arglen+1); // clear it out - strcpy(cmdline, argv[i]); + strcpy_s(cmdline, arglen+1, argv[i]); for (i=2; i < argc; i++) { - strcat(cmdline, " "); - strcat(cmdline, argv[i]); + strcat_s(cmdline, arglen+1, " "); + strcat_s(cmdline, arglen+1, argv[i]); } os_init_cmdline(cmdline); delete [] cmdline; @@ -1425,4 +1443,4 @@ int parse_cmdline(char *cmdline) // 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(); -} +} \ No newline at end of file diff --git a/code/cmdline/cmdline.h b/code/cmdline/cmdline.h index d6817ab12e..52b25eb3a2 100644 --- a/code/cmdline/cmdline.h +++ b/code/cmdline/cmdline.h @@ -74,6 +74,8 @@ extern int Cmdline_spec; extern int Cmdline_normal; extern int Cmdline_height; extern int Cmdline_enable_3d_shockwave; +extern int Cmdline_postprocess; +extern int Cmdline_bloom_intensity; // Game Speed related extern int Cmdline_cache_bitmaps; diff --git a/code/cutscene/cutscenes.cpp b/code/cutscene/cutscenes.cpp index 9a969381f0..996d7246b4 100644 --- a/code/cutscene/cutscenes.cpp +++ b/code/cutscene/cutscenes.cpp @@ -653,8 +653,8 @@ void cutscenes_screen_do_frame() Description_index = Selected_line; Text_size = 0; - if ( Description_index < Cutscene_list.size( ) && - Cutscene_list[ Description_index ] < Cutscenes.size( ) ) { + if ( Description_index < (int)Cutscene_list.size( ) && + (int)Cutscene_list[ Description_index ] < (int)Cutscenes.size( ) ) { src = Cutscenes[Cutscene_list[Description_index]].description; if (src) { Text_size = split_str(src, Cutscene_desc_coords[gr_screen.res][2], Text_line_size, Text_lines, Cutscene_max_text_lines[gr_screen.res]); diff --git a/code/cutscene/oggplayer.cpp b/code/cutscene/oggplayer.cpp index ad58cc56ed..df6cc355b0 100644 --- a/code/cutscene/oggplayer.cpp +++ b/code/cutscene/oggplayer.cpp @@ -724,12 +724,14 @@ THEORAFILE *theora_open(char *filename) movie->vorbis_p = 0; } + int ret; + // we're expecting more header packets. while ( (movie->theora_p < 3) || (movie->vorbis_p && (movie->vorbis_p < 3)) ) { - int ret; + ret = ogg_stream_packetout(&movie->t_osstate, &movie->opacket); // look for further theora headers - while ( (movie->theora_p < 3) && (ret = ogg_stream_packetout(&movie->t_osstate, &movie->opacket)) ){ + while ( (movie->theora_p < 3) && (ret) ){ if ( (ret < 0) || theora_decode_header(&movie->tinfo, &movie->tcomment, &movie->opacket) ) { mprintf(("Theora ERROR: Error parsing Theora stream headers on '%s'! Corrupt stream?\n", lower_name)); goto Error; @@ -737,10 +739,14 @@ THEORAFILE *theora_open(char *filename) if (++movie->theora_p == 3) break; + + ret = ogg_stream_packetout(&movie->t_osstate, &movie->opacket); } + ret = ogg_stream_packetout(&movie->v_osstate, &movie->opacket); + // look for more vorbis header packets - while ( movie->vorbis_p && (movie->vorbis_p < 3) && (ret = ogg_stream_packetout(&movie->v_osstate, &movie->opacket)) ) { + while ( movie->vorbis_p && (movie->vorbis_p < 3) && (ret) ) { if ( (ret < 0) || vorbis_synthesis_headerin(&movie->vinfo, &movie->vcomment, &movie->opacket) ) { mprintf(("Theora ERROR: Error parsing Vorbis stream headers on '%s'! Corrupt stream?\n", lower_name)); goto Error; @@ -748,6 +754,8 @@ THEORAFILE *theora_open(char *filename) if (++movie->vorbis_p == 3) break; + + ret = ogg_stream_packetout(&movie->v_osstate, &movie->opacket); } // The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec @@ -837,15 +845,15 @@ void theora_play(THEORAFILE *movie) for (i = 0; (i < ret) && (i < maxsamples); i++) { for (j = 0; j < movie->vinfo.channels; j++) { - int val = fl2i(pcm[j][i] * 32767.0f + 0.5f); + float val = pcm[j][i] * 32767.0f + 0.5f; - if (val > 32767) - val = 32767; + if (val > 32767.0f) + val = 32767.0f; - if (val < -32768) - val = -32768; + if (val < -32768.0f) + val = -32768.0f; - audiobuf[count++] = val; + audiobuf[count++] = (short)val; } } diff --git a/code/debris/debris.cpp b/code/debris/debris.cpp index 7f52f8db6f..7a47abd9a9 100644 --- a/code/debris/debris.cpp +++ b/code/debris/debris.cpp @@ -584,8 +584,8 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d } if ( db->is_hull ) { - // Only make 1/2 of the pieces have arcs - if ( myrand() < RAND_MAX_2 ) { + // Percent of debris pieces with arcs controlled via table (default 50%) + if (frand() < sip->debris_arc_percent) { db->arc_frequency = 1000; } else { db->arc_frequency = 0; diff --git a/code/fireball/fireballs.cpp b/code/fireball/fireballs.cpp index c06a96eb45..9f07bbc739 100644 --- a/code/fireball/fireballs.cpp +++ b/code/fireball/fireballs.cpp @@ -623,7 +623,7 @@ int fireball_is_warp(object * obj) return 0; } -// mabye play sound effect for warp hole closing +// maybe play sound effect for warp hole closing void fireball_maybe_play_warp_close_sound(fireball *fb) { float life_left; diff --git a/code/fred2/adjustgriddlg.cpp b/code/fred2/adjustgriddlg.cpp index efe4533162..8fedefa379 100644 --- a/code/fred2/adjustgriddlg.cpp +++ b/code/fred2/adjustgriddlg.cpp @@ -79,9 +79,9 @@ BOOL adjust_grid_dlg::OnInitDialog() GetDlgItem(IDC_EDIT_Z)->EnableWindow(FALSE); } - m_spinx.SetRange((short)99999, (short)-99999); - m_spiny.SetRange((short)99999, (short)-99999); - m_spinz.SetRange((short)99999, (short)-99999); + m_spinx.SetRange(SHRT_MIN, SHRT_MAX); + m_spiny.SetRange(SHRT_MIN, SHRT_MAX); + m_spinz.SetRange(SHRT_MIN, SHRT_MAX); return TRUE; } diff --git a/code/fred2/bgbitmapdlg.cpp b/code/fred2/bgbitmapdlg.cpp index b2d2ae204d..ff24a05d2f 100644 --- a/code/fred2/bgbitmapdlg.cpp +++ b/code/fred2/bgbitmapdlg.cpp @@ -71,6 +71,7 @@ bg_bitmap_dlg::bg_bitmap_dlg(CWnd* pParent) : CDialog(bg_bitmap_dlg::IDD, pParen m_sky_flag_3 = The_mission.skybox_flags & MR_NO_ZBUFFER ? 1 : 0; m_sky_flag_4 = The_mission.skybox_flags & MR_NO_CULL ? 1 : 0; m_sky_flag_5 = The_mission.skybox_flags & MR_NO_GLOWMAPS ? 1 : 0; + m_sky_flag_6 = The_mission.skybox_flags & MR_FORCE_CLAMP ? 1 : 0; //}}AFX_DATA_INIT } @@ -128,6 +129,7 @@ void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SKY_FLAG_NO_ZBUFF, m_sky_flag_3); DDX_Check(pDX, IDC_SKY_FLAG_NO_CULL, m_sky_flag_4); DDX_Check(pDX, IDC_SKY_FLAG_NO_GLOW, m_sky_flag_5); + DDX_Check(pDX, IDC_SKY_FLAG_CLAMP, m_sky_flag_6); //}}AFX_DATA_MAP } @@ -415,6 +417,9 @@ void bg_bitmap_dlg::OnClose() if(m_sky_flag_5) { The_mission.skybox_flags |= MR_NO_GLOWMAPS; } + if(m_sky_flag_6) { + The_mission.skybox_flags |= MR_FORCE_CLAMP; + } // close sun data sun_data_close(); diff --git a/code/fred2/bgbitmapdlg.h b/code/fred2/bgbitmapdlg.h index 7dccf5e101..ed0d1b4072 100644 --- a/code/fred2/bgbitmapdlg.h +++ b/code/fred2/bgbitmapdlg.h @@ -82,6 +82,7 @@ public: int m_sky_flag_3; int m_sky_flag_4; int m_sky_flag_5; + int m_sky_flag_6; CString m_skybox_model; CString m_envmap; //}}AFX_DATA diff --git a/code/fred2/createwingdlg.cpp b/code/fred2/createwingdlg.cpp index 36d58242d3..00a89982ad 100644 --- a/code/fred2/createwingdlg.cpp +++ b/code/fred2/createwingdlg.cpp @@ -17,6 +17,7 @@ #include "object/waypoint.h" #include "globalincs/linklist.h" #include "parse/parselo.h" +#include "iff_defs/iff_defs.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -77,7 +78,7 @@ void create_wing_dlg::OnOK() ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { - if (ptr->type == OBJ_SHIP) { + if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)){ i = ptr->instance; if (!strnicmp(m_name, Ships[i].ship_name, strlen(m_name))) { char *namep; @@ -103,11 +104,33 @@ void create_wing_dlg::OnOK() ptr = GET_NEXT(ptr); } - for (i=0; i