Compare commits

...
Author SHA1 Message Date
chief1983 eb46c94d08 Automated 3.7.2 Final versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11329 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-24 12:07:13 +10:00
chief1983 3afde9b623 Automated 3.7.2 RC6 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11313 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-19 00:07:51 +10:00
chief1983 65aceccc13 Project file version catchup to RC5.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11312 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-19 00:07:50 +10:00
chief1983 e37bc109c8 Trunk sync r11307.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11308 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-18 18:09:47 +10:00
chief1983 dafca28717 Trunk sync r11305.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11306 387891d4-d844-0410-90c0-e4c51a9137d3
2015-04-17 18:08:19 +10:00
chief1983 2a9e6719a7 Automated 3.7.2 RC5 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11227 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:21 +10:00
chief1983 aed59d2125 I goofed, let's revert that and try again.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11226 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:20 +10:00
chief1983 c599955813 Automated 3.7.2 RC5 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11225 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:20 +10:00
chief1983 3bcab10109 Trunk sync r11222.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11223 387891d4-d844-0410-90c0-e4c51a9137d3
2015-01-24 09:22:20 +10:00
chief1983 78cf382996 Trunk sync r11173.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@11174 387891d4-d844-0410-90c0-e4c51a9137d3
2014-11-21 18:45:26 +10:00
chief1983 54b2994204 Automated 3.7.2 RC4 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10997 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:09 +10:00
chief1983 3960161427 Trunk sync r10995.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10996 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 0b68d9c09c Automated 3.7.2 RC3 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10783 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 66285e2cab Trunk sync r10774.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10782 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 ff8607d74e Automated 3.7.2 RC2 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10724 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 acf72ef431 Trunk sync r10722.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10723 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 9f61dd5286 Automated 3.7.2 RC1 versioning commit
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10634 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 6e6b4b1620 Trunk sync r10632.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10633 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:08 +10:00
chief1983 3b9869a00a Trunk sync r10572.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10573 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
chief1983 c761256461 Trunk sync r10570.
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_2@10571 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
The_E 5f7b9159b8 Fix for Mantis 3023 by Yarn: Make sure the vasudan mainhall fun cheat works again
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10519 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
The_E 89291af840 Fix for Mantis 3015: Makes sure rotation values are always in the 0-359 degree range
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10518 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 6401a8266d Remove gcc warnings (unused & shadow)
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10517 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 8706f824fa Fix mantis 2921: start mainhall music when leaving the credits state
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10507 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
Goober5000 77a0d6a841 add briefing icons for ship-with-cargo and wing-with-cargo
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10506 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
zookeeper 4e590a6761 Changed the label of the "Broadcast Locally" multiplayer option from "/multidata" to "Broadcast Locally".
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10498 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 953f47560e From Axem: fix newly added hud gauge sexps
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10497 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
karajorma f3d747db32 Yarn's fix for Mantis 3017 (Certain HUD elements don't work after the changes to strings.tbl). Not very happy with the way it fixes thing (it only solves problems for French, German and Polish, which kinda makes the changes to strings.tbl in r9761 somewhat pointless) but it makes sense to wait for SDL and truetype support and then fix everything properly then.
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10496 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:07 +10:00
niffiwan 117dd15bda From Axem & niffiwan: stop briefing/credits/mainhall music with scripting
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10495 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:06 +10:00
m_m 5431beb81d Fix for Mantis 3018: Setting a weapon's Target/HomingObject/HomingPosition etc doesn't work
git-svn-id: svn://svn.icculus.org/fs2open/trunk/fs2_open@10494 387891d4-d844-0410-90c0-e4c51a9137d3
2014-09-11 19:50:06 +10:00
416 changed files with 43235 additions and 23469 deletions

No files matched your search

+9
View File
@@ -1,5 +1,14 @@
*.o
*.a
.dirstamp
libtool
ltmain.sh
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
compile
.deps/
code/.deps/
Makefile
+4
View File
@@ -119,6 +119,10 @@ do
echo "Running autoreconf..."
autoreconf --install
)
# DIE if the subshell failed
if [ $? -ne 0 ]; then
exit 1
fi
fi
done
+4 -1
View File
@@ -263,7 +263,10 @@ FS2_SOURCES = \
debris/debris.cpp \
debris/debris.h \
debugconsole/console.cpp \
debugconsole/dbugfile.h \
debugconsole/console.h \
debugconsole/consolecmds.cpp \
debugconsole/consoleparse.cpp \
debugconsole/consoleparse.h \
debugconsole/timerbar.cpp \
debugconsole/timerbar.h \
exceptionhandler/exceptionhandler.cpp \
+1
View File
@@ -109,6 +109,7 @@ extern ai_flag_name Ai_flag_names[];
#define AIGF_PURGE (1<<5) // purge this goal next time we process
#define AIGF_GOALS_PURGED (1<<6) // this goal has already caused other goals to get purged
#define AIGF_DEPART_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
#define AIGF_TARGET_OWN_TEAM (1<<8) // Goober5000 - removes standard precautions against AI ships taking traitorous actions
#define AIGF_DOCK_INDEXES_VALID (AIGF_DOCKER_INDEX_VALID|AIGF_DOCKEE_INDEX_VALID)
+2 -7
View File
@@ -75,13 +75,9 @@ void parse_ai_profiles_tbl(const char *filename)
char *saved_Mp = NULL;
char buf[NAME_LENGTH];
// open localization
lcl_ext_open();
if ((rval = setjmp(parse_abort)) != 0)
{
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default ai_profiles.tbl>", rval));
lcl_ext_close();
return;
}
@@ -467,6 +463,8 @@ void parse_ai_profiles_tbl(const char *filename)
set_flag(profile, "$fix ai path order bug:", AIPF2_FIX_AI_PATH_ORDER_BUG, AIP_FLAG2);
set_flag(profile, "$strict turret-tagged-only targeting:", AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING, AIP_FLAG2);
// ----------
// compatibility
@@ -514,9 +512,6 @@ void parse_ai_profiles_tbl(const char *filename)
// add tbl/tbm to multiplayer validation list
extern void fs2netd_add_table_validation(const char *tblname);
fs2netd_add_table_validation(filename);
// close localization
lcl_ext_close();
}
void ai_profiles_init()
+1
View File
@@ -65,6 +65,7 @@
#define AIPF2_ASPECT_LOCK_COUNTERMEASURE (1 << 11)
#define AIPF2_AI_GUARDS_SPECIFIC_SHIP_IN_WING (1 << 12)
#define AIPF2_FIX_AI_PATH_ORDER_BUG (1 << 13)
#define AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING (1 << 14)
// AI Path types
#define AI_PATH_MODE_NORMAL 0
+58 -67
View File
@@ -369,9 +369,13 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
object *target_objp;
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
if ( aip->target_objnum < 0 )
return 0;
target_objp = &Objects[aip->target_objnum];
if ( (aip->targeted_subsys != NULL) && (aip->target_objnum >= 0) && (aip->targeted_subsys->system_info->path_num >= 0) ) {
if ( (aip->targeted_subsys != NULL) && (aip->targeted_subsys->system_info->path_num >= 0) ) {
int subsys_path_num, subsys_in_sight, checked_sight;
float dist;
@@ -605,8 +609,9 @@ void ai_big_chase_attack(ai_info *aip, ship_info *sip, vec3d *enemy_pos, float d
return;
}
vec3d *rel_pos, vec_to_enemy;
float weapon_travel_dist;
vec3d *rel_pos;
vec3d vec_to_enemy;
float weapon_travel_dist;
start_bank = Ships[aip->shipnum].weapons.current_primary_bank;
@@ -742,89 +747,75 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
}
if (tswp->num_secondary_banks > 0) {
int priority1, priority2;
priority1 = -1;
priority2 = -1;
// Maybe favor selecting a bomb.
// Note, if you're firing a bomb, if it's aspect seeking, the firing conditions can be looser.
if (Ship_info[Ships[En_objp->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))
if (En_objp->phys_info.speed * dist_to_enemy < 5000.0f) // Don't select a bomb if enemy moving fast relative to distance
priority1 = WIF_BOMB;
if (!(En_objp->flags & OF_PROTECTED) || (aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP))) {
//ai_select_secondary_weapon(Pl_objp, tswp, priority1, priority2); // Note, need to select to get weapon speed and lifetime
if(aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP)) {
priority1 = WIF_PUNCTURE;
}
ai_choose_secondary_weapon(Pl_objp, aip, En_objp);
int current_bank = tswp->current_secondary_bank;
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
if (current_bank > -1) {
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
if(!(En_objp->flags & OF_PROTECTED) || ((aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP)) && swip->wi_flags & WIF_PUNCTURE )) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
// If ship is protected and very low on hits, don't fire missiles.
if ((current_bank > -1) && (!(En_objp->flags & OF_PROTECTED) || (En_objp->hull_strength > 10*swip->damage))) {
if (aip->ai_flags & AIF_UNLOAD_SECONDARIES) {
if (timestamp_until(swp->next_secondary_fire_stamp[current_bank]) > swip->fire_wait*1000.0f) {
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (swip->fire_wait*1000.0f));
}
}
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank])) {
float firing_range;
if (swip->wi_flags2 & WIF2_LOCAL_SSM)
firing_range=swip->lssm_lock_range;
else
firing_range = MIN((swip->max_speed * swip->lifetime), swip->weapon_range);
// reduce firing range of secondaries in nebula
extern int Nebula_sec_range;
if ((The_mission.flags & MISSION_FLAG_FULLNEB) && Nebula_sec_range) {
firing_range *= 0.8f;
if(!(En_objp->flags & OF_PROTECTED) || ((aip->goals[0].ai_mode & (AI_GOAL_DISABLE_SHIP | AI_GOAL_DISARM_SHIP)) && swip->wi_flags & WIF_PUNCTURE )) { //override lockdown on protected ships when using anti subsystem weapons - Valathil
// If ship is protected and very low on hits, don't fire missiles.
if (!(En_objp->flags & OF_PROTECTED) || (En_objp->hull_strength > 10*swip->damage)) {
if (aip->ai_flags & AIF_UNLOAD_SECONDARIES) {
if (timestamp_until(swp->next_secondary_fire_stamp[current_bank]) > swip->fire_wait*1000.0f) {
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (swip->fire_wait*1000.0f));
}
}
float t = 0.25f; // default delay in seconds until next fire.
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank])) {
float firing_range;
if (swip->wi_flags2 & WIF2_LOCAL_SSM)
firing_range=swip->lssm_lock_range;
else
firing_range = MIN((swip->max_speed * swip->lifetime), swip->weapon_range);
// reduce firing range of secondaries in nebula
extern int Nebula_sec_range;
if ((The_mission.flags & MISSION_FLAG_FULLNEB) && Nebula_sec_range) {
firing_range *= 0.8f;
}
if (dist_to_enemy < firing_range*1.0f) {
float t = 0.25f; // default delay in seconds until next fire.
if (dist_to_enemy < firing_range*1.0f) {
//vm_vec_scale_add(&future_enemy_pos, enemy_pos, enemy_vel, dist_to_enemy/swip->max_speed);
//if (vm_vec_dist_quick(&future_enemy_pos, firing_pos) < firing_range * 0.8f) {
if (ai_fire_secondary_weapon(Pl_objp)) {
//vm_vec_scale_add(&future_enemy_pos, enemy_pos, enemy_vel, dist_to_enemy/swip->max_speed);
//if (vm_vec_dist_quick(&future_enemy_pos, firing_pos) < firing_range * 0.8f) {
if (ai_fire_secondary_weapon(Pl_objp)) {
int current_bank_adjusted = MAX_SHIP_PRIMARY_BANKS + current_bank;
int current_bank_adjusted = MAX_SHIP_PRIMARY_BANKS + current_bank;
if ((aip->ai_flags & AIF_UNLOAD_SECONDARIES) || (swip->burst_flags & WBF_FAST_FIRING)) {
if (swip->burst_shots > swp->burst_counter[current_bank_adjusted]) {
t = swip->burst_delay;
swp->burst_counter[current_bank_adjusted]++;
} else {
t = swip->fire_wait;
if ((swip->burst_shots > 0) && (swip->burst_flags & WBF_RANDOM_LENGTH)) {
swp->burst_counter[current_bank_adjusted] = myrand() % swip->burst_shots;
if ((aip->ai_flags & AIF_UNLOAD_SECONDARIES) || (swip->burst_flags & WBF_FAST_FIRING)) {
if (swip->burst_shots > swp->burst_counter[current_bank_adjusted]) {
t = swip->burst_delay;
swp->burst_counter[current_bank_adjusted]++;
} else {
swp->burst_counter[current_bank_adjusted] = 0;
t = swip->fire_wait;
if ((swip->burst_shots > 0) && (swip->burst_flags & WBF_RANDOM_LENGTH)) {
swp->burst_counter[current_bank_adjusted] = myrand() % swip->burst_shots;
} else {
swp->burst_counter[current_bank_adjusted] = 0;
}
}
}
} else {
if (swip->burst_shots > swp->burst_counter[current_bank_adjusted]) {
t = set_secondary_fire_delay(aip, temp_shipp, swip, true);
swp->burst_counter[current_bank_adjusted]++;
} else {
t = set_secondary_fire_delay(aip, temp_shipp, swip, false);
if ((swip->burst_shots > 0) && (swip->burst_flags & WBF_RANDOM_LENGTH)) {
swp->burst_counter[current_bank_adjusted] = myrand() % swip->burst_shots;
if (swip->burst_shots > swp->burst_counter[current_bank_adjusted]) {
t = set_secondary_fire_delay(aip, temp_shipp, swip, true);
swp->burst_counter[current_bank_adjusted]++;
} else {
swp->burst_counter[current_bank_adjusted] = 0;
t = set_secondary_fire_delay(aip, temp_shipp, swip, false);
if ((swip->burst_shots > 0) && (swip->burst_flags & WBF_RANDOM_LENGTH)) {
swp->burst_counter[current_bank_adjusted] = myrand() % swip->burst_shots;
} else {
swp->burst_counter[current_bank_adjusted] = 0;
}
}
}
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
}
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
}
//}
//}
}
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
}
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (t*1000.0f));
}
}
}
+110 -78
View File
@@ -18,6 +18,7 @@
#include "ai/ai.h"
#include "debugconsole/console.h"
#include "globalincs/linklist.h"
#include "object/object.h"
#include "physics/physics.h"
@@ -780,9 +781,6 @@ void reset_ai_class_names()
#define AI_CLASS_INCREMENT 10
void parse_aitbl()
{
// open localization
lcl_ext_open();
read_file_text("ai.tbl", CF_TYPE_TABLES);
reset_parse();
@@ -814,9 +812,6 @@ void parse_aitbl()
reset_ai_class_names();
}
}
// close localization
lcl_ext_close();
atexit(free_ai_stuff);
}
@@ -836,7 +831,6 @@ void ai_init()
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "ai.tbl", rval));
lcl_ext_close();
} else {
parse_aitbl();
}
@@ -1997,7 +1991,7 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
dist = dist * 0.5f;
}
num_attacking = num_enemies_attacking(eno->trial_objp-Objects);
num_attacking = num_enemies_attacking(OBJ_INDEX(eno->trial_objp));
if ((sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) || (num_attacking < eno->max_attackers)) {
if (!(sip->flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))){
dist *= (float) (num_attacking+2)/2.0f; // prevents lots of ships from attacking same target
@@ -2014,7 +2008,7 @@ void evaluate_object_as_nearest_objnum(eval_nearest_objnum *eno)
if (dist < eno->nearest_dist) {
eno->nearest_dist = dist;
eno->nearest_objnum = eno->trial_objp-Objects;
eno->nearest_objnum = OBJ_INDEX(eno->trial_objp);
}
}
}
@@ -2129,7 +2123,7 @@ int find_nearby_threat(int objnum, int enemy_team_mask, float range, int *count)
if (dist < nearest_dist) {
nearest_dist = dist;
nearest_objnum = objp-Objects;
nearest_objnum = OBJ_INDEX(objp);
}
}
}
@@ -2290,20 +2284,21 @@ void ai_attack_object(object *attacker, object *attacked, ship_subsys *ssp)
if (attacked == NULL) {
aip->choose_enemy_timestamp = timestamp(0);
// nebula safe
set_target_objnum(aip, find_enemy(attacker-Objects, 99999.9f, 4));
set_target_objnum(aip, find_enemy(OBJ_INDEX(attacker), 99999.9f, 4));
} else {
// check if we can see atacked in nebula
if (aip->target_objnum != attacked - Objects) {
if (aip->target_objnum != OBJ_INDEX(attacked)) {
aip->aspect_locked_time = 0.0f;
}
set_target_objnum(aip, attacked - Objects);
set_target_objnum(aip, OBJ_INDEX(attacked));
}
ai_set_goal_maybe_abort_dock(attacker, aip);
aip->ok_to_target_timestamp = timestamp(DELAY_TARGET_TIME); // No dynamic targeting for 7 seconds.
// Goober5000
if ((temp = find_ignore_new_object_index(aip, aip->target_objnum)) >= 0)
temp = find_ignore_new_object_index(aip, aip->target_objnum);
if (temp >= 0)
{
aip->ignore_new_objnums[temp] = UNUSED_OBJNUM;
}
@@ -2382,7 +2377,7 @@ void ai_evade_object(object *evader, object *evaded)
aip = &Ai_info[Ships[evader->instance].ai_index];
set_target_objnum(aip, evaded - Objects);
set_target_objnum(aip, OBJ_INDEX(evaded));
aip->mode = AIM_EVADE;
}
@@ -2781,7 +2776,7 @@ void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_
aip->path_cur = aip->path_start;
aip->path_dir = PD_FORWARD;
aip->path_objnum = mobjp-Objects;
aip->path_objnum = OBJ_INDEX(mobjp);
aip->mp_index = path_num;
aip->path_length = Ppfp - ppfp_start;
aip->path_next_check_time = timestamp(1);
@@ -2842,7 +2837,7 @@ void create_model_exit_path(object *pl_objp, object *mobjp, int path_num, int co
aip->path_cur = aip->path_start;
aip->path_dir = PD_FORWARD;
aip->path_objnum = mobjp-Objects;
aip->path_objnum = OBJ_INDEX(mobjp);
aip->mp_index = path_num;
aip->path_length = Ppfp - ppfp_start;
aip->path_next_check_time = timestamp(1);
@@ -3280,7 +3275,7 @@ void ai_do_stay_near(object *objp, object *other_objp, float dist)
aip->submode = -1;
aip->submode_start_time = Missiontime;
aip->stay_near_distance = dist;
aip->goal_objnum = other_objp-Objects;
aip->goal_objnum = OBJ_INDEX(other_objp);
aip->goal_signature = other_objp->signature;
}
@@ -3333,7 +3328,7 @@ void ai_form_on_wing(object *objp, object *goal_objp)
aip->ai_flags &= ~AIF_FORMATION_WING;
aip->ai_flags |= AIF_FORMATION_OBJECT;
aip->goal_objnum = goal_objp-Objects;
aip->goal_objnum = OBJ_INDEX(goal_objp);
ai_set_goal_maybe_abort_dock(objp, aip);
aip->ok_to_target_timestamp = timestamp(DELAY_TARGET_TIME*4); // Super extra long time until can target another ship.
@@ -4839,9 +4834,9 @@ int ai_maybe_fire_afterburner(object *objp, ai_info *aip)
else {
//If ai_aburn_use_factor is not specified, calculate a number based on the AI class. Otherwise, use that value.
if (aip->ai_aburn_use_factor == INT_MIN)
return static_rand_timed(objp-Objects, Num_ai_classes - aip->ai_class);
return static_rand_timed(OBJ_INDEX(objp), Num_ai_classes - aip->ai_class);
else
return static_rand_timed(objp-Objects, aip->ai_aburn_use_factor);
return static_rand_timed(OBJ_INDEX(objp), aip->ai_aburn_use_factor);
}
}
}
@@ -5082,7 +5077,7 @@ void evade_ship()
int rand_int;
float accel_val;
rand_int = static_rand(Pl_objp-Objects);
rand_int = static_rand(OBJ_INDEX(Pl_objp));
accel_val = (float) (((Missiontime^rand_int) >> 14) & 0x0f)/32.0f + 0.5f;
accelerate_ship(aip, accel_val);
} else
@@ -5090,13 +5085,13 @@ void evade_ship()
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)) {
if (percent_left > 30.0f + ((OBJ_INDEX(Pl_objp)) & 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);
aip->afterburner_stop_time = (fix) (Missiontime + F1_0 + static_randf(OBJ_INDEX(Pl_objp)) * F1_0 / 4);
} else {
aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(OBJ_INDEX(Pl_objp))/4;
}
}
}
@@ -5649,7 +5644,7 @@ int ai_fire_primary_weapon(object *objp)
float dot;
vec3d v2t;
if (!( vm_vec_mag_quick(&G_predicted_pos) < AICODE_SMALL_MAGNITUDE )) {
if ( !(vm_vec_mag_quick(&G_predicted_pos) < AICODE_SMALL_MAGNITUDE ) && !(aip->submode == SM_AVOID) ) {
if ( vm_vec_cmp(&G_predicted_pos, &G_fire_pos) ) {
vm_vec_normalized_dir(&v2t, &G_predicted_pos, &G_fire_pos);
dot = vm_vec_dot(&v2t, &objp->orient.vec.fvec);
@@ -6135,7 +6130,9 @@ void render_all_ship_bay_paths(object *objp)
if ( pm->ship_bay == NULL )
return;
for ( i = 0; i < pm->ship_bay->num_paths; i++ ) {
memset(&v, 0, sizeof(v));
for ( i = 0; i < pm->ship_bay->num_paths; i++ ) {
mp = &pm->paths[pm->ship_bay->path_indexes[i]];
for ( j = 0; j < mp->nverts; j++ ) {
@@ -6177,6 +6174,8 @@ void render_all_subsys_paths(object *objp)
if ( pm->ship_bay == NULL )
return;
memset(&v, 0, sizeof(v));
for ( i = 0; i < pm->n_paths; i++ ) {
mp = &pm->paths[i];
@@ -6238,6 +6237,8 @@ void render_path_points(object *objp)
for (i=0; i<num_points; i++) {
vertex v0;
memset(&v0, 0, sizeof(v0));
g3_rotate_vertex( &v0, &pp->pos );
@@ -6355,7 +6356,7 @@ void set_predicted_enemy_pos_turret(vec3d *predicted_enemy_pos, vec3d *gun_pos,
scale = (1.0f - aip->ai_accuracy) * 4.0f * (1.0f + 4.0f * (1.0f - time_enemy_in_range/(2*range_time)));
}
static_randvec(((pobjp-Objects) ^ (Missiontime >> 16)) & 7, &rand_vec);
static_randvec(((OBJ_INDEX(pobjp)) ^ (Missiontime >> 16)) & 7, &rand_vec);
vm_vec_scale_add2(predicted_enemy_pos, &rand_vec, scale);
G_collision_time = collision_time;
@@ -6468,7 +6469,7 @@ void set_predicted_enemy_pos(vec3d *predicted_enemy_pos, object *pobjp, vec3d *e
}
// get a random vector that changes slowly over time (1x / sec)
static_randvec(((pobjp-Objects) ^ (Missiontime >> 16)) & 7, &rand_vec);
static_randvec(((OBJ_INDEX(pobjp)) ^ (Missiontime >> 16)) & 7, &rand_vec);
vm_vec_scale_add2(predicted_enemy_pos, &rand_vec, scale);
@@ -6672,7 +6673,7 @@ void attack_set_accel(ai_info *aip, ship_info *sip, float dist_to_enemy, float d
if (sip_local->afterburner_fuel_capacity > 0.0f) {
percent_left = 100.0f * shipp->afterburner_fuel / sip_local->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
if (percent_left > 30.0f + ((OBJ_INDEX(Pl_objp)) & 0x0f)) {
afterburners_start(Pl_objp);
if (aip->ai_profile_flags & AIPF_SMART_AFTERBURNER_MANAGEMENT) {
float max_ab_vel;
@@ -6695,7 +6696,7 @@ void attack_set_accel(ai_info *aip, ship_info *sip, float dist_to_enemy, float d
aip->afterburner_stop_time = (fix) (Missiontime + F1_0 * ab_time);
} else {
aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(Pl_objp-Objects)/4;
aip->afterburner_stop_time = Missiontime + F1_0 + static_rand(OBJ_INDEX(Pl_objp))/4;
}
}
}
@@ -7229,7 +7230,7 @@ void ai_chase_attack(ai_info *aip, ship_info *sip, vec3d *predicted_enemy_pos, f
// If ship moving slowly relative to its size, then don't attack its center point.
// How far from center we attack is based on speed, size and distance to enemy
if (En_objp->radius > En_objp->phys_info.speed) {
static_randvec(Pl_objp-Objects, &randvec);
static_randvec(OBJ_INDEX(Pl_objp), &randvec);
scale = dist_to_enemy/(dist_to_enemy + En_objp->radius) * En_objp->radius;
scale *= 0.5f * En_objp->radius/(En_objp->phys_info.speed + En_objp->radius); // scale downward by 1/2 to 1/4
vm_vec_scale_add(&new_pos, predicted_enemy_pos, &randvec, scale);
@@ -7320,7 +7321,7 @@ void ai_chase_ga(ai_info *aip, ship_info *sip)
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
if (!(Pl_objp->phys_info.flags & PF_AFTERBURNER_ON )) {
float percent_left = 100.0f * Ships[Pl_objp->instance].afterburner_fuel / sip->afterburner_fuel_capacity;
if (percent_left > 30.0f + ((Pl_objp-Objects) & 0x0f)) {
if (percent_left > 30.0f + ((OBJ_INDEX(Pl_objp)) & 0x0f)) {
afterburners_start(Pl_objp);
aip->afterburner_stop_time = Missiontime + 3*F1_0/2;
}
@@ -7368,7 +7369,8 @@ int ai_set_attack_subsystem(object *objp, int subnum)
aip->ignore_objnum = UNUSED_OBJNUM;
// Goober5000
if ((temp = find_ignore_new_object_index(aip, aip->target_objnum)) >= 0)
temp = find_ignore_new_object_index(aip, aip->target_objnum);
if (temp >= 0)
{
aip->ignore_new_objnums[temp] = UNUSED_OBJNUM;
}
@@ -7529,7 +7531,7 @@ void ai_set_guard_object(object *objp, object *other_objp)
ai_set_guard_wing(objp, Ai_info[Ships[other_objp->instance].ai_index].wing);
} else {
other_objnum = other_objp-Objects;
other_objnum = OBJ_INDEX(other_objp);
aip->guard_objnum = other_objnum;
aip->guard_signature = other_objp->signature;
@@ -8236,8 +8238,12 @@ void ai_chase()
// If seeking lock, try to point directly at ship, else predict position so lasers can hit it.
// If just acquired target, or target is not in reasonable cone, don't refine believed enemy position.
if ((real_dot_to_enemy < 0.25f) || (aip->target_time < 1.0f) || (aip->ai_flags & AIF_SEEK_LOCK)) {
if ((real_dot_to_enemy < 0.25f) || (aip->target_time < 1.0f)) {
predicted_enemy_pos = enemy_pos;
} else if (aip->ai_flags & AIF_SEEK_LOCK) {
set_predicted_enemy_pos(&predicted_enemy_pos, Pl_objp, &aip->last_aim_enemy_pos, &aip->last_aim_enemy_vel, aip); // Set G_fire_pos
predicted_enemy_pos = enemy_pos;
G_predicted_pos = predicted_enemy_pos;
} else {
// Set predicted_enemy_pos.
// See if attacking a subsystem.
@@ -8761,9 +8767,9 @@ void ai_chase()
if (!(En_objp->flags & OF_PROTECTED)) {
ai_choose_secondary_weapon(Pl_objp, aip, En_objp);
int current_bank = tswp->current_secondary_bank;
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[tswp->current_secondary_bank]];
if (current_bank > -1) {
weapon_info *swip = &Weapon_info[tswp->secondary_bank_weapons[current_bank]];
if (aip->ai_flags & AIF_UNLOAD_SECONDARIES) {
if (timestamp_until(swp->next_secondary_fire_stamp[current_bank]) > swip->fire_wait*1000.0f) {
swp->next_secondary_fire_stamp[current_bank] = timestamp((int) (swip->fire_wait*1000.0f));
@@ -8771,7 +8777,7 @@ void ai_chase()
}
if (timestamp_elapsed(swp->next_secondary_fire_stamp[current_bank])) {
if (tswp->current_secondary_bank >= 0) {
if (current_bank >= 0) {
float firing_range;
if (swip->wi_flags2 & WIF2_LOCAL_SSM)
@@ -9555,7 +9561,7 @@ void guard_object_was_hit(object *guard_objp, object *hitter_objp)
return;
}
}
set_target_objnum(aip, hitter_objp-Objects);
set_target_objnum(aip, OBJ_INDEX(hitter_objp));
aip->mode = AIM_CHASE;
aip->submode = SM_ATTACK;
aip->submode_start_time = Missiontime;
@@ -9580,7 +9586,7 @@ void maybe_update_guard_object(object *hit_objp, object *hitter_objp)
aip = &Ai_info[Ships[objp->instance].ai_index];
if ((aip->mode == AIM_GUARD) || (aip->active_goal == AI_ACTIVE_GOAL_DYNAMIC)) {
if (aip->guard_objnum == hit_objp-Objects) {
if (aip->guard_objnum == OBJ_INDEX(hit_objp)) {
guard_object_was_hit(objp, hitter_objp);
} else if ((aip->guard_wingnum != -1) && (aip->guard_wingnum == Ai_info[Ships[hit_objp->instance].ai_index].wing)) {
guard_object_was_hit(objp, hitter_objp);
@@ -9607,7 +9613,7 @@ int ai_guard_find_nearby_bomb(object *guarding_objp, object *guarded_objp)
wp = &Weapons[bomb_objp->instance];
wip = &Weapon_info[wp->weapon_info_index];
if ( !(wip->wi_flags & WIF_BOMB) ) {
if ( !((wip->wi_flags & WIF_BOMB) || (wip->wi_flags3 & WIF3_FIGHTER_INTERCEPTABLE)) ) {
continue;
}
@@ -9800,7 +9806,7 @@ void ai_big_guard()
float radius, extended_z;
// get random [0 to 1] based on OBJNUM
float objval = static_randf(Pl_objp-Objects);
float objval = static_randf(OBJ_INDEX(Pl_objp));
// get position relative to cylinder of guard_objp
extended_z = get_cylinder_points(Pl_objp, guard_objp, &axis_pt, &r_vec, &radius);
@@ -9826,7 +9832,7 @@ void ai_big_guard()
// how often to choose new desired_z
// 1*(64) sec < 2000, 2*(64) < 2-4000 3*(64) > 4-8000, etc (Missiontime >> 22 is 64 sec intervals)
int time_choose = int(floor(log(length * 0.001f) / log(2.0f)));
float desired_z = min_z + length * static_randf( (Pl_objp-Objects) ^ (Missiontime >> (22 + time_choose)) );
float desired_z = min_z + length * static_randf( (OBJ_INDEX(Pl_objp)) ^ (Missiontime >> (22 + time_choose)) );
// get r from guard_ship
float cur_guard_rad = vm_vec_dist(&Pl_objp->pos, &axis_pt);
@@ -9938,7 +9944,7 @@ void ai_big_guard()
}
// Periodically, scan for a nearby ship to attack.
if (((AI_FrameCount ^ (Pl_objp-Objects)) & 0x07) == 0) {
if (((AI_FrameCount ^ (OBJ_INDEX(Pl_objp))) & 0x07) == 0) {
ai_guard_find_nearby_object();
}
}
@@ -10009,7 +10015,7 @@ void ai_guard()
vec3d v2g, rvec;
// get random [0 to 1] based on OBJNUM
objval = static_randf(Pl_objp-Objects);
objval = static_randf(OBJ_INDEX(Pl_objp));
switch (aip->submode) {
case AIS_GUARD_STATIC:
@@ -10141,7 +10147,7 @@ void ai_guard()
}
// Periodically, scan for a nearby ship to attack.
if (((AI_FrameCount ^ (Pl_objp-Objects)) & 0x07) == 0) {
if (((AI_FrameCount ^ (OBJ_INDEX(Pl_objp))) & 0x07) == 0) {
ai_guard_find_nearby_object();
}
break;
@@ -10532,7 +10538,7 @@ void ai_stay_near()
goal_objp = &Objects[goal_objnum];
// Make not all ships pursue same point.
static_randvec(Pl_objp-Objects, &rand_vec);
static_randvec(OBJ_INDEX(Pl_objp), &rand_vec);
// Make sure point is in front hemisphere (relative to Pl_objp's position.
vm_vec_sub(&vec_to_goal, &goal_objp->pos, &Pl_objp->pos);
@@ -10843,12 +10849,17 @@ void ai_dock()
{
// call the ai_abort rearm request code
ai_abort_rearm_request( Pl_objp );
// Goober5000 - add missionlog for support ships, per Mantis #2999
mission_log_add_entry(LOG_SHIP_UNDOCKED, shipp->ship_name, goal_shipp->ship_name);
}
// Make sure repair has not broken off.
else if (dist > 5.0f) // Oops, too far away!
{
if ( goal_aip->ai_flags & AIF_BEING_REPAIRED )
if ( goal_aip->ai_flags & AIF_BEING_REPAIRED ) {
ai_do_objects_repairing_stuff( goal_objp, Pl_objp, REPAIR_INFO_BROKEN);
// Goober5000 - add missionlog for support ships, per Mantis #2999
mission_log_add_entry(LOG_SHIP_UNDOCKED, shipp->ship_name, goal_shipp->ship_name);
}
if (dist > Pl_objp->radius*2 + goal_objp->radius*2) {
// Got real far away from goal, so move back a couple modes and try again.
@@ -10862,8 +10873,11 @@ void ai_dock()
}
else
{
if ( goal_aip->ai_flags & AIF_AWAITING_REPAIR )
if ( goal_aip->ai_flags & AIF_AWAITING_REPAIR ) {
ai_do_objects_repairing_stuff( goal_objp, Pl_objp, REPAIR_INFO_BEGIN );
// Goober5000 - add missionlog for support ships, per Mantis #2999
mission_log_add_entry(LOG_SHIP_DOCKED, shipp->ship_name, goal_shipp->ship_name);
}
}
break;
@@ -10980,9 +10994,8 @@ void ai_dock()
model_anim_start_type(goal_shipp, TRIGGER_TYPE_DOCKING_STAGE_2, dockee_index, -1);
// don't add undock log entries for support ships.
if ( !(sip->flags & SIF_SUPPORT) ) {
mission_log_add_entry(LOG_SHIP_UNDOCKED, shipp->ship_name, goal_shipp->ship_name);
}
// Goober5000 - deliberately contravening Volition's above comment - add missionlog for support ships, per Mantis #2999
mission_log_add_entry(LOG_SHIP_UNDOCKED, shipp->ship_name, goal_shipp->ship_name);
}
break;
}
@@ -11367,16 +11380,14 @@ float get_wing_largest_radius(object *objp, int formation_object_flag)
float Wing_y_scale = 2.0f;
float Wing_scale = 1.0f;
DCF(wing_y_scale, "")
DCF(wing_y_scale, "Adjusts the wing formation scale along the Y axis (Default is 2.0)")
{
dc_get_arg(ARG_FLOAT);
Wing_y_scale = Dc_arg_float;
dc_stuff_float(&Wing_y_scale);
}
DCF(wing_scale, "")
DCF(wing_scale, "Adjusts the wing formation scale. (Default is 1.0f)")
{
dc_get_arg(ARG_FLOAT);
Wing_scale = Dc_arg_float;
dc_stuff_float(&Wing_scale);
}
/**
@@ -12092,10 +12103,8 @@ void ai_maybe_launch_cmeasure(object *objp, ai_info *aip)
if ((aip->nearest_locked_object != -1) && (Objects[aip->nearest_locked_object].type == OBJ_WEAPON)) {
object *weapon_objp;
weapon *weaponp;
weapon_objp = &Objects[aip->nearest_locked_object];
weaponp = &Weapons[weapon_objp->instance];
if ((dist = vm_vec_dist_quick(&objp->pos, &weapon_objp->pos)) < weapon_objp->phys_info.speed*2.0f) {
@@ -12451,6 +12460,7 @@ void maybe_evade_dumbfire_weapon(ai_info *aip)
if (aip->submode == SM_ATTACK_FOREVER) {
return;
}
break;
case AIM_GUARD:
// If in guard mode and far away from guard object, don't pursue guy that hit me.
if ((aip->guard_objnum != -1) && (aip->guard_signature == Objects[aip->guard_objnum].signature)) {
@@ -12644,6 +12654,8 @@ int ai_acquire_emerge_path(object *pl_objp, int parent_objnum, int allowed_path_
{
int i, num_allowed_paths = 0, allowed_bay_paths[MAX_SHIP_BAY_PATHS];
memset(allowed_bay_paths, 0, sizeof(allowed_bay_paths));
for (i = 0; i < bay->num_paths; i++)
{
if (allowed_path_mask & (1 << i))
@@ -12892,6 +12904,10 @@ int ai_acquire_depart_path(object *pl_objp, int parent_objnum, int allowed_path_
// take the closest path we can find
ship_bay_path = ai_find_closest_depart_path(aip, pm, allowed_path_mask);
if ( ship_bay_path < 0 )
return -1;
path_index = bay->path_indexes[ship_bay_path];
aip->submode_parm0 = ship_bay_path;
bay->depart_flags |= (1<<ship_bay_path);
@@ -13833,8 +13849,17 @@ int ai_need_new_target(object *pl_objp, int target_objnum)
if ( objp->type == OBJ_SHIP ) {
if ( Ships[objp->instance].flags & SF_DYING ) {
return 1;
} else if (Ships[objp->instance].team == Ships[pl_objp->instance].team)
} else if (Ships[objp->instance].team == Ships[pl_objp->instance].team) {
// Goober5000 - targeting the same team is allowed if pl_objp is going bonkers
ai_info *pl_aip = &Ai_info[Ships[pl_objp->instance].ai_index];
if (pl_aip->active_goal != AI_GOAL_NONE && pl_aip->active_goal != AI_ACTIVE_GOAL_DYNAMIC) {
if (pl_aip->goals[pl_aip->active_goal].flags & AIGF_TARGET_OWN_TEAM) {
return 0;
}
}
return 1;
}
}
return 0;
@@ -14014,8 +14039,12 @@ void ai_frame(int objnum)
if (target_objnum != -1) {
if (aip->target_objnum != target_objnum)
aip->aspect_locked_time = 0.0f;
set_target_objnum(aip, target_objnum);
En_objp = &Objects[target_objnum];
target_objnum = set_target_objnum(aip, target_objnum);
if (target_objnum >= 0)
{
En_objp = &Objects[target_objnum];
}
}
}
}
@@ -14055,7 +14084,7 @@ void ai_frame(int objnum)
}
if ((En_objp != NULL) && (En_objp->pos.xyz.x == Pl_objp->pos.xyz.x) && (En_objp->pos.xyz.y == Pl_objp->pos.xyz.y) && (En_objp->pos.xyz.z == Pl_objp->pos.xyz.z)) {
mprintf(("Warning: Object and its enemy have same position. Object #%i\n", Pl_objp-Objects));
mprintf(("Warning: Object and its enemy have same position. Object #%i\n", OBJ_INDEX(Pl_objp)));
En_objp = NULL;
}
@@ -14201,7 +14230,7 @@ void ai_process( object * obj, int ai_index, float frametime )
Assert( ai_index >= 0 );
AI_frametime = frametime;
if (obj-Objects <= Last_ai_obj) {
if (OBJ_INDEX(obj) <= Last_ai_obj) {
AI_FrameCount++;
}
@@ -14247,7 +14276,7 @@ void ai_process( object * obj, int ai_index, float frametime )
}
}
Last_ai_obj = obj-Objects;
Last_ai_obj = OBJ_INDEX(obj);
}
/**
@@ -14778,14 +14807,17 @@ int firing_aspect_seeking_bomb(object *objp)
bank_index = swp->current_secondary_bank;
if (bank_index != -1)
if (swp->secondary_bank_ammo[bank_index] > 0) {
if (Weapon_info[swp->secondary_bank_weapons[bank_index]].wi_flags & WIF_BOMB) {
if (Weapon_info[swp->secondary_bank_weapons[bank_index]].wi_flags & WIF_HOMING_ASPECT) {
return 1;
if (bank_index != -1) {
if (swp->secondary_bank_weapons[bank_index] > 0) {
if (swp->secondary_bank_ammo[bank_index] > 0) {
if (Weapon_info[swp->secondary_bank_weapons[bank_index]].wi_flags & WIF_BOMB) {
if (Weapon_info[swp->secondary_bank_weapons[bank_index]].wi_flags & WIF_HOMING_ASPECT) {
return 1;
}
}
}
}
}
return 0;
}
@@ -14979,7 +15011,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_
if (shipp->team == Ships[hit_objp->instance].team) // Don't have AI react to collisions between teammates.
return;
objp_hitter = hit_objp;
hitter_objnum = hit_objp-Objects;
hitter_objnum = OBJ_INDEX(hit_objp);
} else {
Int3(); // Hmm, what kind of object hit this if not weapon or ship? Get MikeK.
return;
@@ -15045,7 +15077,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_
// If the hitter object is the ignore object, don't attack it.
ship_info *sip = &Ship_info[shipp->ship_info_index];
if ((is_ignore_object(aip, objp_hitter-Objects)) && (sip->flags & (SIF_BOMBER | SIF_FIGHTER))) {
if ((is_ignore_object(aip, OBJ_INDEX(objp_hitter))) && (sip->flags & (SIF_BOMBER | SIF_FIGHTER))) {
if (!object_is_docked(objp_ship)) {
if (aip->mode == AIM_NONE) {
aip->mode = AIM_CHASE; // This will cause the ship to move, if not attack.
@@ -15066,14 +15098,14 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hitpos, int shield_
if ( ai_big_maybe_enter_strafe_mode(objp_ship, OBJ_INDEX(hit_objp), 1) )
return;
}
break;
case AIM_GUARD:
// If in guard mode and far away from guard object, don't pursue guy that hit me.
if ((aip->guard_objnum != -1) && (aip->guard_signature == Objects[aip->guard_objnum].signature)) {
if (vm_vec_dist_quick(&objp_ship->pos, &Objects[aip->guard_objnum].pos) > 500.0f) {
return;
}
if ((aip->guard_objnum != -1) && (aip->guard_signature == Objects[aip->guard_objnum].signature)) {
if (vm_vec_dist_quick(&objp_ship->pos, &Objects[aip->guard_objnum].pos) > 500.0f) {
return;
}
}
case AIM_STILL:
case AIM_STAY_NEAR:
// Note: Dealt with above, at very top. case AIM_PLAY_DEAD:
+10
View File
@@ -979,6 +979,16 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
aigp->priority = MAX_GOAL_PRIORITY;
}
// Goober5000 - we now have an extra optional chase argument to allow chasing our own team
if ( op == OP_AI_CHASE || op == OP_AI_CHASE_WING || op == OP_AI_DISABLE_SHIP || op == OP_AI_DISARM_SHIP ) {
if ((CDDDR(node) != -1) && is_sexp_true(CDDDR(node)))
aigp->flags |= AIGF_TARGET_OWN_TEAM;
}
if ( op == OP_AI_DESTROY_SUBSYS ) {
if ((CDDDDR(node) != -1) && is_sexp_true(CDDDDR(node)))
aigp->flags |= AIGF_TARGET_OWN_TEAM;
}
// Goober5000 - since none of the goals act on the actor,
// don't assign the goal if the actor's goal target is itself
if (aigp->target_name != NULL && !strcmp(aigp->target_name, actor_name))
+99 -26
View File
@@ -22,6 +22,7 @@
#include "iff_defs/iff_defs.h"
#include "weapon/muzzleflash.h"
#include "parse/scripting.h"
#include "debugconsole/console.h"
#include <limits.h>
@@ -38,8 +39,7 @@
float Lethality_range_const = 2.0f;
DCF(lethality_range, "N for modifying range: 1 / (1+N) at 100")
{
dc_get_arg(ARG_FLOAT);
Lethality_range_const = Dc_arg_float;
dc_stuff_float(&Lethality_range_const);
}
float Player_lethality_bump[NUM_SKILL_LEVELS] = {
@@ -354,6 +354,54 @@ bool turret_weapon_has_flags2(ship_weapon *swp, int flags)
return false;
}
/**
* Just gloms all the flags from all the weapons into one variable. More efficient if all you need to do is test for the existence of a flag.
*/
int turret_weapon_aggregate_flags(ship_weapon *swp)
{
Assert(swp != NULL);
int i = 0, flags = 0;
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) {
flags |= Weapon_info[swp->primary_bank_weapons[i]].wi_flags;
}
}
for (i = 0; i < swp->num_secondary_banks; i++)
{
if (swp->secondary_bank_weapons[i] >= 0) {
flags |= Weapon_info[swp->secondary_bank_weapons[i]].wi_flags;
}
}
return flags;
}
/**
* Just gloms all the flags from all the weapons into one variable. More efficient if all you need to do is test for the existence of a flag.
*/
int turret_weapon_aggregate_flags2(ship_weapon *swp)
{
Assert(swp != NULL);
int i = 0, flags2 = 0;
for (i = 0; i < swp->num_primary_banks; i++)
{
if (swp->primary_bank_weapons[i] >= 0) {
flags2 |= Weapon_info[swp->primary_bank_weapons[i]].wi_flags2;
}
}
for (i = 0; i < swp->num_secondary_banks; i++)
{
if (swp->secondary_bank_weapons[i] >= 0) {
flags2 |= Weapon_info[swp->secondary_bank_weapons[i]].wi_flags2;
}
}
return flags2;
}
/**
* Returns true if any of the weapons in swp have the subtype specified
*
@@ -479,7 +527,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
}
// don't shoot at ships without collision check
if (sip->flags & SIF_NO_COLLIDE) {
if (!(objp->flags & OF_COLLIDES)) {
return 0;
}
@@ -501,7 +549,11 @@ int valid_turret_enemy(object *objp, object *turret_parent)
weapon *wp = &Weapons[objp->instance];
weapon_info *wip = &Weapon_info[wp->weapon_info_index];
if ( (!(wip->wi_flags & WIF_BOMB) && !(Ai_info[Ships[turret_parent->instance].ai_index].ai_profile_flags & AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY) ) ) {
if (wip->subtype == WP_LASER && !(wip->wi_flags3 & WIF3_TURRET_INTERCEPTABLE)) { // If the thing can't be shot down, don't try. -MageKing17
return 0;
}
if ( (!((wip->wi_flags & WIF_BOMB) || (wip->wi_flags3 & WIF3_TURRET_INTERCEPTABLE)) && !(Ai_info[Ships[turret_parent->instance].ai_index].ai_profile_flags & AIPF_ALLOW_TURRETS_TARGET_WEAPONS_FREELY) ) ) {
return 0;
}
@@ -598,9 +650,15 @@ void evaluate_obj_as_target(object *objp, eval_enemy_obj_struct *eeo)
}
}
// check if turret flagged to only target tagged ships
// check if turret flagged to only target tagged ships
// Note: retail behaviour was turrets with tagged-only could fire at bombs
// and could fire their spawn weapons
// this check is almost redundant; see the almost identical check in ai_fire_from_turret
// however if this is removed turrets still track targets but don't fire at them (which looks silly)
if (eeo->eeo_flags & EEOF_TAGGED_ONLY) {
if (!ship_is_tagged(objp)) {
if (!ship_is_tagged(objp) &&
( (The_mission.ai_profile->flags2 & AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING) ||
( !(objp->type == OBJ_WEAPON) && !(turret_weapon_has_flags(&eeo->turret_subsys->weapons, WIF_SPAWN))) )) {
return;
}
}
@@ -1049,7 +1107,7 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
objp = &Objects[mo->objnum];
Assert(objp->type == OBJ_WEAPON);
if (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_BOMB)
if ((Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_BOMB) || (Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags3 & WIF3_TURRET_INTERCEPTABLE))
{
evaluate_obj_as_target(objp, &eeo);
}
@@ -1466,10 +1524,16 @@ ship_subsys *aifft_list[MAX_AIFFT_TURRETS];
float aifft_rank[MAX_AIFFT_TURRETS];
int aifft_list_size = 0;
int aifft_max_checks = 5;
DCF(mf, "")
DCF(mf, "Adjusts the maximum number of tries an AI may do when trying to pick a subsystem to attack (Default is 5)")
{
dc_get_arg(ARG_INT);
aifft_max_checks = Dc_arg_int;
dc_stuff_int(&aifft_max_checks);
if (aifft_max_checks <= 0) {
dc_printf("Value must be a non-negative, non-zero integer\n");
dc_printf("aifft_max_checks set to default value of 5\n");
aifft_max_checks = 5;
}
}
@@ -1820,8 +1884,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
}
// now do anything else
else {
for (int i=0; i < wip->shots; i++)
{
for (int i = 0; i < wip->shots; i++) {
// zookeeper - Firepoints should cycle normally between shots,
// so we need to get the position info separately for each shot
ship_get_global_turret_gun_info(&Objects[parent_objnum], turret, turret_pos, turret_fvec, 1, NULL);
@@ -1831,9 +1894,9 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
//nprintf(("AI", "Turret_time_enemy_in_range = %7.3f\n", ss->turret_time_enemy_in_range));
if (weapon_objnum != -1) {
objp=&Objects[weapon_objnum];
wp=&Weapons[objp->instance];
wip=&Weapon_info[wp->weapon_info_index];
objp = &Objects[weapon_objnum];
wp = &Weapons[objp->instance];
wip = &Weapon_info[wp->weapon_info_index];
parent_ship->last_fired_turret = turret;
turret->last_fired_weapon_info_index = wp->weapon_info_index;
@@ -1846,7 +1909,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
Script_system.RunCondition(CHA_ONTURRETFIRED, 0, NULL, &Objects[parent_objnum]);
// if the gun is a flak gun
if(wip->wi_flags & WIF_FLAK){
if (wip->wi_flags & WIF_FLAK) {
// show a muzzle flash
flak_muzzle_flash(turret_pos, turret_fvec, &Objects[parent_ship->objnum].phys_info, turret_weapon_class);
@@ -1862,8 +1925,10 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
{
flak_set_range(objp, flak_range_override);
}
} else if(wip->muzzle_flash > -1) {
mflash_create(turret_pos, turret_fvec, &Objects[parent_ship->objnum].phys_info, Weapon_info[turret_weapon_class].muzzle_flash);
}
// otherwise just do mflash if the weapon has it
else if (wip->muzzle_flash >= 0) {
mflash_create(turret_pos, turret_fvec, &Objects[parent_ship->objnum].phys_info, wip->muzzle_flash);
}
// in multiplayer (and the master), then send a turret fired packet.
@@ -1953,6 +2018,11 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
Weapons[Objects[weapon_objnum].instance].turret_subsys = tsi->turret;
Weapons[Objects[weapon_objnum].instance].target_num = tsi->turret->turret_enemy_objnum;
// muzzle flash?
if (Weapon_info[tsi->weapon_class].muzzle_flash >= 0) {
mflash_create(&turret_pos, &turret_fvec, &Objects[tsi->parent_objnum].phys_info, Weapon_info[tsi->weapon_class].muzzle_flash);
}
// maybe sound
if ( Weapon_info[tsi->weapon_class].launch_snd != -1 ) {
// Don't play turret firing sound if turret sits on player ship... it gets annoying.
@@ -1960,8 +2030,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
snd_play_3d( &Snds[Weapon_info[tsi->weapon_class].launch_snd], &turret_pos, &View_position );
}
}
if(Weapon_info[tsi->weapon_class].muzzle_flash > -1)
mflash_create(&turret_pos, &turret_fvec, &Objects[tsi->parent_objnum].phys_info, Weapon_info[tsi->weapon_class].muzzle_flash);
// in multiplayer (and the master), then send a turret fired packet.
if ( MULTIPLAYER_MASTER && (weapon_objnum != -1) ) {
int subsys_index;
@@ -2048,7 +2117,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
// (NOTE: this will probably get changed by other parts of the code (swarming, beams, etc) to be
// a more accurate time, but we need to give it a long enough time for the other parts of the code
// to change the timestamp before it gets acted upon - taylor)
ss->turret_animation_done_time = timestamp(1000);
ss->turret_animation_done_time = timestamp(200);
} else {
return;
}
@@ -2218,6 +2287,8 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
}
}
bool tagged_only = ((wip->wi_flags2 & WIF2_TAGGED_ONLY) || (ss->weapons.flags & SW_FLAG_TAGGED_ONLY));
if (lep->type == OBJ_SHIP) {
// Check if we're targeting a protected ship
if (lep->flags & OF_PROTECTED) {
@@ -2250,14 +2321,16 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
ss->turret_time_enemy_in_range = 0.0f;
continue;
}
// Check if weapon or turret is set to tagged-only
// must check here in case turret has multiple weapons and not all are tagged-only
else if (!ship_is_tagged(lep) && tagged_only) {
continue;
}
}
else
{
//can't tag anything else, other than asteroids
//but we don't want to waste this type of
//weaponary on asteroids now do we?
if ((wip->wi_flags2 & WIF2_TAGGED_ONLY) || (ss->weapons.flags & SW_FLAG_TAGGED_ONLY))
{
// check tagged-only for non-ship targets
if (tagged_only && (!(lep->type == OBJ_WEAPON) || (The_mission.ai_profile->flags2 & AIPF2_STRICT_TURRET_TAGGED_ONLY_TARGETING))) {
continue;
}
}
+10 -6
View File
@@ -196,8 +196,8 @@ anim_instance *anim_play(anim_play_struct *aps)
}
if(aps->base_w < 0 || aps->base_h < 0) {
instance->base_w = gr_screen.max_w_unscaled;
instance->base_h = gr_screen.max_h_unscaled;
instance->base_w = gr_screen.max_w_unscaled_zoomed;
instance->base_h = gr_screen.max_h_unscaled_zoomed;
} else {
instance->base_w = aps->base_w;
instance->base_h = aps->base_h;
@@ -488,16 +488,20 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
// determine x,y to display the bitmap at
if ( instance->world_pos == NULL ) {
int old_max_w_unscaled = gr_screen.max_w_unscaled;
int old_max_h_unscaled = gr_screen.max_h_unscaled;
int old_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
int old_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;
gr_set_screen_scale(instance->base_w, instance->base_h);
gr_set_clip(0, 0, instance->base_w, instance->base_h, false);
gr_set_clip(0, 0, instance->base_w, instance->base_h, GR_RESIZE_MENU);
if ( instance->aa_color == NULL ) {
gr_bitmap(instance->x, instance->y);
gr_bitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET);
}
else {
gr_set_color_fast( (color*)instance->aa_color );
gr_aabitmap(instance->x, instance->y);
gr_aabitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET);
}
gr_reset_screen_scale();
gr_set_screen_scale(old_max_w_unscaled, old_max_h_unscaled, old_max_w_unscaled_zoomed, old_max_h_unscaled_zoomed);
gr_reset_clip();
}
else {
-2
View File
@@ -301,7 +301,6 @@ int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_
Assert(packed_size == (save-dest_start) );
return packed_size;
break;
}
default:
@@ -467,7 +466,6 @@ int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, in
Assert(packed_size == (save-dest_start) );
return packed_size;
break;
}
default:
+8 -29
View File
@@ -39,6 +39,8 @@
#include "network/multimsgs.h"
#include "network/multi.h"
#include "parse/scripting.h"
#include "debugconsole/console.h"
#include <algorithm>
#include "globalincs/compatibility.h"
@@ -859,7 +861,7 @@ void asteroid_maybe_reposition(object *objp, asteroid_field *asfieldp)
dist = vm_vec_normalized_dir(&vec_to_asteroid, &objp->pos, &Eye_position);
dot = vm_vec_dot(&Eye_matrix.vec.fvec, &vec_to_asteroid);
if ((dot < 0.7f) || (dist > 3000.0f)) {
if ( (dot < 0.7f) || (dist > asfieldp->bound_rad) ) {
if (Num_asteroids > MAX_ASTEROIDS-10) {
objp->flags |= OF_SHOULD_BE_DEAD;
} else {
@@ -867,12 +869,11 @@ void asteroid_maybe_reposition(object *objp, asteroid_field *asfieldp)
asteroid_wrap_pos(objp, asfieldp);
Asteroids[objp->instance].target_objnum = -1;
vm_vec_normalized_dir(&vec_to_asteroid, &objp->pos, &Eye_position);
dist = vm_vec_normalized_dir(&vec_to_asteroid, &objp->pos, &Eye_position);
dot = vm_vec_dot(&Eye_matrix.vec.fvec, &vec_to_asteroid);
dist = vm_vec_dist_quick(&objp->pos, &Eye_position);
if (( dot > 0.7f) && (dist < 3000.0f)) {
// player would see asteroid pop out other side, so reverse velocity instead of wrapping
if ( (dot > 0.7f) && (dist < (asfieldp->bound_rad * 1.3f)) ) {
// player would see asteroid pop out other side, so reverse velocity instead of wrapping
objp->pos = old_asteroid_pos;
vm_vec_copy_scale(&objp->phys_info.vel, &old_vel, -1.0f);
objp->phys_info.desired_vel = objp->phys_info.vel;
@@ -1404,23 +1405,8 @@ void asteroid_level_close()
Asteroid_field.num_initial_asteroids=0;
}
DCF(asteroids,"Turns asteroids on/off")
{
if ( Dc_command ) {
dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);
if ( Dc_arg_type & ARG_TRUE )
Asteroids_enabled = 1;
else if ( Dc_arg_type & ARG_FALSE )
Asteroids_enabled = 0;
else if ( Dc_arg_type & ARG_NONE )
Asteroids_enabled ^= 1;
}
if ( Dc_help )
dc_printf( "Usage: asteroids [bool]\nTurns asteroid system on/off. If nothing passed, then toggles it.\n" );
if ( Dc_status )
dc_printf( "asteroids are %s\n", (Asteroids_enabled?"ON":"OFF") );
}
DCF_BOOL2(asteroids, Asteroids_enabled, "enables or disables asteroids", "Usage: asteroids [bool]\nTurns asteroid system on/off. If nothing passed, then toggles it.\n");
void hud_target_asteroid()
{
@@ -1909,12 +1895,8 @@ void asteroid_parse_tbl()
"are no species for them to belong to."
);
// open localization
lcl_ext_open();
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "asteroid.tbl", rval));
lcl_ext_close();
return;
}
@@ -2043,9 +2025,6 @@ void asteroid_parse_tbl()
} else {
Asteroid_icon_closeup_zoom = 0.5f; // magic number from retail
}
// close localization
lcl_ext_close();
}
/**
+1
View File
@@ -124,6 +124,7 @@ typedef enum {
typedef struct asteroid_field {
vec3d min_bound; // Minimum range of field.
vec3d max_bound; // Maximum range of field.
float bound_rad;
int has_inner_bound;
vec3d inner_min_bound;
vec3d inner_max_bound;
-7
View File
@@ -1274,13 +1274,9 @@ void parse_autopilot_table(char *filename)
int rval;
SCP_vector<SCP_string> lines;
// open localization
lcl_ext_open();
if ((rval = setjmp(parse_abort)) != 0)
{
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", (filename) ? filename : "<default autopilot.tbl>", rval));
lcl_ext_close();
return;
}
@@ -1337,9 +1333,6 @@ void parse_autopilot_table(char *filename)
required_string("#END");
// close localization
lcl_ext_close();
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
/**
* @file bm_examples.cpp
* This file contains example code for using bmpman.
*/
#include "bmpman/bmpman.h"
#include "graphics/2d.h"
void bm_create_example() {
static int test_inited = 0;
static int test_bmp;
static uint test_bmp_data[128 * 64];
if (!test_inited) {
test_inited = 1;
// Create the new bitmap and fill in its data.
// When you're done with it completely, call
// bm_release to free up the bitmap handle
test_bmp = bm_create(32, 128, 64, test_bmp_data);
int i, j;
for (i = 0; i < 64; i++) {
for (j = 0; j < 64; j++) {
uint r = i * 4;
test_bmp_data[j + i * 128] = r;
}
}
}
// page out the data, so that the next bm_lock will convert the new data to
// the correct bpp
bm_unload(test_bmp);
// put in new data
int x, y;
gr_reset_clip();
for (y = 0; y < 64; y++) {
for (x = 0; x < 128; x++) {
test_bmp_data[y * 128 + x] = 15;
}
}
// Draw the bitmap, the upper left corner is the origin (0, 0)
gr_set_bitmap(test_bmp);
gr_bitmap(0, 0);
}
+77 -81
View File
@@ -1,121 +1,119 @@
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#ifndef __BM_INTERNAL_H__
#define __BM_INTERNAL_H__
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
/**
* @file bm_internal.h
* These are functions and types used by bmpman and a few others.
*
* @details It is a "protected" header that requires BMPMAN_INTERNAL to be defined before it can be included. This is to
* provide a small measure of safety since this functions can cause problems if not used correctly
*/
// extra check to make sure this stuff doesn't end up in normal files
// don't use any of this unless BMPMAN_INTERNAL is defined
#ifdef BMPMAN_INTERNAL
#ifndef BMPMAN_INTERNAL
#error The file header "bmpman/bm_internal.h" is protected. Make sure you know what you are doing!
#endif
#include "globalincs/pstypes.h"
#include "bmpman/bmpman.h"
#include "globalincs/pstypes.h"
// Bitmap types
enum BM_TYPE
{
BM_TYPE_NONE = 0, //!< No type
BM_TYPE_USER, //!< in-memory
BM_TYPE_PCX, //!< PCX
BM_TYPE_TGA, //!< 16 or 32 bit targa
BM_TYPE_DDS, //!< generic identifier for DDS
BM_TYPE_PNG, //!< PNG
BM_TYPE_JPG, //!< 32 bit jpeg
BM_TYPE_ANI, //!< in-house ANI format
BM_TYPE_EFF, //!< specifies any type of animated image, the EFF itself is just text
// no-type ( used in: bm_bitmaps[i].type )
#define BM_TYPE_NONE 0
// in-memory type ( used in: bm_bitmaps[i].type )
#define BM_TYPE_USER 1
// file-type types ( used in: bm_bitmaps[i].type )
#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_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 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
// special types
BM_TYPE_RENDER_TARGET_STATIC, //!< 24/32 bit setup internally as a static render target
BM_TYPE_RENDER_TARGET_DYNAMIC, //!< 24/32 bit setup internally as a dynamic render target
// Compressed types (bitmap.c_type)
BM_TYPE_DXT1, //!< 24 bit with switchable alpha
BM_TYPE_DXT3, //!< 32 bit with 4 bit alpha
BM_TYPE_DXT5, //!< 32 bit with 8 bit alpha
BM_TYPE_CUBEMAP_DDS, //!< generic DDS cubemap (uncompressed cubemap surface)
BM_TYPE_CUBEMAP_DXT1, //!< 24-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
BM_TYPE_CUBEMAP_DXT5 //!< 32-bit cubemap (compressed cubemap surface)
};
/// Moved from cpp file ///////////////////
// Consider these 'protected' structures and functions that should only be used by special bitmap functions
typedef union bm_extra_info {
union bm_extra_info {
struct {
// Stuff needed for animations
int first_frame; // used for animations -- points to index of first frame
int num_frames; // used for animation -- number of frames in the animation
int keyframe; // used for animation -- keyframe info
ubyte fps; // used for animation -- frames per second
int first_frame; //!< used for animations -- points to index of first frame
int num_frames; //!< used for animations -- number of frames in the animation
int keyframe; //!< used for animations -- keyframe info
ubyte fps; //!< used for animations -- frames per second
struct {
// stuff for static animations
ubyte type; // type for individual images
char filename[MAX_FILENAME_LEN]; // filename for individual images
ubyte type; //!< type for individual images
char filename[MAX_FILENAME_LEN]; //!< filename for individual images
} eff;
} ani;
struct {
// Stuff needed for user bitmaps
void *data; // For user bitmaps, this is where the data comes from
ubyte bpp; // For user bitmaps, this is what format the data is
ubyte flags; // Flags passed to bm_create
void* data; //!< For user bitmaps, this is where the data comes from
ubyte bpp; //!< For user bitmaps, this is what format the data is
ubyte flags; //!< For user bitmaps, Flags passed to bm_create
} user;
} bm_extra_info;
};
typedef struct bitmap_entry {
struct bitmap_entry {
// identification
char filename[MAX_FILENAME_LEN]; // filename for this bitmap
char filename[MAX_FILENAME_LEN]; //!< filename for this bitmap
uint signature; // a unique signature identifying the data
uint palette_checksum; // checksum used to be sure bitmap is in current palette
int handle; // Handle = id*MAX_BITMAPS + bitmapnum
int last_used; // When this bitmap was last used
uint signature; //!< a unique signature identifying the data
uint palette_checksum; //!< checksum used to be sure bitmap is in current palette
int handle; //!< Handle = id*MAX_BITMAPS + bitmapnum
int last_used; //!< When this bitmap was last used
ubyte type; // PCX, USER, ANI, etc
ubyte comp_type; // What sort of compressed type, BM_TYPE_NONE if not compressed
signed char ref_count; // Number of locks on bitmap. Can't unload unless ref_count is 0.
ubyte type; //!< PCX, USER, ANI, etc
ubyte comp_type; //!< What sort of compressed type, BM_TYPE_NONE if not compressed
signed char ref_count; //!< Number of locks on bitmap. Can't unload unless ref_count is 0.
int dir_type; // which directory this was loaded from (to skip other locations with same name)
int dir_type; //!< which directory this was loaded from (to skip other locations with same name)
// compressed bitmap stuff (.dds) - RT please take a look at this and tell me if we really need it
int mem_taken; // How much memory does this bitmap use? - UnknownPlayer
int num_mipmaps; // number of mipmap levels, we need to read all of them
int mem_taken; //!< How much memory does this bitmap use? - UnknownPlayer
int num_mipmaps; //!< number of mipmap levels, we need to read all of them
// Stuff to keep track of usage
ubyte preloaded; // If set, then this was loaded from the lst file
int preload_count; // how many times this gets used in game, for unlocking
ubyte used_flags; // What flags it was accessed thru
int load_count;
ubyte preloaded; //!< If set, then this was loaded from the lst file
int preload_count; //!< how many times this gets used in game, for unlocking
ubyte used_flags; //!< What flags it was accessed thru
int load_count;
// Bitmap info
bitmap bm;
bitmap bm; //!< Bitmap info
// Data for animations and user bitmaps
bm_extra_info info;
bm_extra_info info; //!< Data for animations and user bitmaps
#ifdef BMPMAN_NDEBUG
// bookeeping
ubyte used_last_frame; // If set, then it was used last frame
ubyte used_this_frame; // If set, then it was used this frame
int data_size; // How much data this bitmap uses
int used_count; // How many times it was accessed
ubyte used_last_frame; // If set, then it was used last frame
ubyte used_this_frame; // If set, then it was used this frame
int data_size; // How much data this bitmap uses
int used_count; // How many times it was accessed
#endif
} bitmap_entry;
};
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 );
@@ -126,6 +124,4 @@ void bm_lock_tga( 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 );
#endif // BMPMAN_INTERNAL
#endif // __BM_INTERNAL_H__
+1740 -1919
View File
File diff suppressed because it is too large. Load diff
+543 -201
View File
@@ -1,288 +1,630 @@
#ifndef _BMPMAN_H
#define _BMPMAN_H
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
*/
/**
* @file bmpman.h
* Header file for the bitmap manager (bmpman)
*/
/**
* @example bm_examples.cpp
* @brief This containes examples of bmpman usage
*/
#ifndef _BMPMAN_H
#define _BMPMAN_H
#include "globalincs/pstypes.h"
#include "cfile/cfile.h"
#include "globalincs/pstypes.h"
#ifndef NDEBUG
#define BMPMAN_NDEBUG
#define BMPMAN_NDEBUG //!< Enables BMPMAN debugging code
#endif
#define MAX_BITMAPS 4750 // How many bitmaps the game can handle
// NOTE: MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's
// proper use even the largest missions should stay under this number. With the largest retail
// missions and wasteful content we should still have about 20% of the slots free. If it still
// goes over then it's something the artists need to fix. For instance the Terran Mara fighter,
// with -spec and -glow and using the Shinepack, needs 117 bitmap slots alone. 111 of those is
// just for the glowmaps. This number can be greatly reduced if the number of ani frames for
// another LOD than LOD0 has fewer or no ani frames. A 37 frame glow ani for LOD2 is little
// more than a waste of resources. Future reports of texture corruption should be initially
// approached with content as the cause and not code. If anything we could/should reduce
// MAX_BITMAPS in the future. Where it's at now should accomidate even the largest mods.
// -- Taylor
/**
* @defgroup BMPMAN_CONSTANTS Macro constants used in/with bmpman.h
*
* @{
*/
/**
* @brief How many bitmaps the game can handle
*
* @attention MAX_BITMAPS shouldn't need to be bumped again. With the fixed bm_release() and it's proper use even the
* largest missions should stay under this number. With the largest retail missions and wasteful content we should
* still have about 20% of the slots free. If it still goes over then it's something the artists need to fix.
* For instance the Terran Mara fighter, with -spec and -glow and using the Shinepack, needs 117 bitmap slots alone.
* 111 of those is just for the glowmaps. This number can be greatly reduced if the number of ani frames for another
* LOD than LOD0 has fewer or no ani frames. A 37 frame glow ani for LOD2 is little more than a waste of resources.
* Future reports of texture corruption should be initially approached with content as the cause and not code.
* If anything we could/should reduce MAX_BITMAPS in the future. Where it's at now should accomidate even the
* largest mods. -- Taylor
*/
#define MAX_BITMAPS 4750
#define BMP_AABITMAP (1<<0) // antialiased bitmap
#define BMP_TEX_XPARENT (1<<1) // transparent texture
#define BMP_TEX_OTHER (1<<2) // so we can identify all "normal" textures
#define BMP_TEX_DXT1 (1<<3) // dxt1 compressed 8r8g8b1a (24bit)
#define BMP_TEX_DXT3 (1<<4) // dxt3 compressed 8r8g8b4a (32bit)
#define BMP_TEX_DXT5 (1<<5) // dxt5 compressed 8r8g8b8a (32bit)
#define BMP_TEX_CUBEMAP (1<<6) // a texture made for cubic environment map
// Flag positions for bitmap.flags
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
#define BMP_AABITMAP (1<<0) //!< antialiased bitmap
#define BMP_TEX_XPARENT (1<<1) //!< transparent texture
#define BMP_TEX_OTHER (1<<2) //!< so we can identify all "normal" textures
#define BMP_TEX_DXT1 (1<<3) //!< dxt1 compressed 8r8g8b1a (24bit)
#define BMP_TEX_DXT3 (1<<4) //!< dxt3 compressed 8r8g8b4a (32bit)
#define BMP_TEX_DXT5 (1<<5) //!< dxt5 compressed 8r8g8b8a (32bit)
#define BMP_TEX_CUBEMAP (1<<6) //!< a texture made for cubic environment map
//compressed texture types
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 )
// Combined flags
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 ) //!< Compressed textures
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER ) //!< Non-compressed textures
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP ) //!< Any texture
//non compressed textures
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER )
// Flag positions for bitmap.type
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0) //!< Texture is a static type
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1) //!< Texture is a dynamic type (animation)
#define BMP_FLAG_CUBEMAP (1<<2) //!< Texture is a cubemap
// any texture type
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP )
/**
* @}
*/
#define BMP_FLAG_RENDER_TARGET_STATIC (1<<0)
#define BMP_FLAG_RENDER_TARGET_DYNAMIC (1<<1)
#define BMP_FLAG_CUBEMAP (1<<2)
struct bitmap
{
short w; //!< Width, in number of pixels
short h; //!< Height, in number of pixels
short rowsize; //!< What you need to add to go to next row
ubyte bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
ubyte true_bpp; //!< The image's actual bitdepth
ubyte flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
ptr_u data; //!< Pointer to data, or maybe offset into VRAM.
ubyte *palette; /**< @brief Pointer to this bitmap's palette (if it has one).
* @details If BMP_NO_PALETTE_MAP flag is cleared, this palette just points to the screen palette. (gr_palette)
*/
};
typedef struct bitmap {
short w, h; // Width and height
short rowsize; // What you need to add to go to next row
ubyte bpp; // How many bits per pixel it is. (7,8,15,16,24,32) (what is requested)
ubyte true_bpp; // How many bits per pixel the image actually is.
ubyte flags; // See the BMP_???? defines for values (this isn't for the BMP_FLAG_* stuff)
ptr_u data; // Pointer to data, or maybe offset into VRAM.
ubyte *palette; // If bpp==8, this is pointer to palette. If the BMP_NO_PALETTE_MAP flag
// is not set, this palette just points to the screen palette. (gr_palette)
} bitmap;
extern int bm_texture_ram; //!< how many bytes of textures are used.
extern int Bm_paging; //!< Bool type that indicates if BMPMAN is currently paging.
extern int Bm_paging;
extern int GLOWMAP; //!< References a map that is a fully lit version of its index -Bobboau
extern int SPECMAP; //!< References a map that is for specular mapping -Bobboau
extern int ENVMAP; //!< References a map that is for environment mapping -Bobboau
extern int NORMMAP; //!< Normal mapping
extern int HEIGHTMAP; //!< Height map for normal mapping
extern int MISCMAP; //!< Utility map, to be utilized for various things shader authors can come up with
/**
* @brief Initilizes the bitmap manager
*/
void bm_init();
/**
* @brief Closes the bitmap manager, freeing any allocated memory used by bitmaps. Is called at program close.
*/
void bm_close();
int bm_get_cache_slot( int bitmap_id, int separate_ani_frames );
/**
* Gets the cache slot of the bitmap indexed by handle.
*
* @details if the bitmap is an ani, gets the first frame
*
* @returns The cache slot index of the bitmap if handle is valid
*
* @note If the handle is invalid, an Assert() fails
*/
int bm_get_cache_slot(int bitmap_id, int separate_ani_frames);
/**
* @brief Gets the next available bitmap slot.
*/
int bm_get_next_handle();
void *bm_malloc(int n, int size);
/**
* @brief Allocates memory for the given handle.
*
* @returns A pointer to the allocated vm if successful,
* @returns Null, if unsuccessful
*
* @note z64 - This function looks fishy. Not only is handle not used in release builds, but bm_bitmaps[handle].size
* and bm_texture_size aren't modified unless this is a debug build
*/
void *bm_malloc(int handle, int size);
/**
* @brief (DEBUG) Similar to bm_malloc, but only updates how much memory is used
*
* @note z64 - Also fishy (see bm_malloc)
*/
void bm_update_memory_used(int n, int size);
// how many bytes of textures are used.
extern int bm_texture_ram;
// This loads a bitmap so we can draw with it later.
// It returns a negative number if it couldn't load
// the bitmap. On success, it returns the bitmap
// number.
/**
* @brief Loads a bitmap so we can draw with it later.
*
* @param filename
*
* @returns The bitmap number if successful, else
* @returns a negative value if not
*/
int bm_load(const char* filename);
/**
* @brief Loads a bitmap so we can draw with it later. (Preferred version)
*
* @param filename
*
* @returns The bitmap number if successful, else
* @returns a negative value if not
*/
int bm_load(const SCP_string& filename);
// special load function. basically allows you to load a bitmap which already exists (by filename).
// this is useful because in some cases we need to have a bitmap which is locked in screen format
// _and_ texture format, such as pilot pics and squad logos
/**
* @brief Reloads a bitmap as a duplicate.
*
* @details This function basically allows you to load a bitmap which already exists (by filename). This is useful
* because in some cases we need to have a bitmap which is locked in screen format _and_ texture format, such as
* the pilot pics and squad logos
*
* @param filename
*
* @returns The bitmap number if successful, else
* @returns a negative value if not
*/
int bm_load_duplicate(const char *filename);
// Creates a bitmap that exists in RAM somewhere, instead
// of coming from a disk file. You pass in a pointer to a
// block of data. The data can be in the following formats:
// 8 bpp (mapped into game palette)
// 32 bpp
// On success, it returns the bitmap number. You cannot
// free that RAM until bm_release is called on that bitmap.
// See example at bottom of this file
int bm_create( int bpp, int w, int h, void *data = NULL, int flags = 0);
/**
* Loads a bitmap which exists somewhere in the RAM.
*
* @param bpp The bitdepth of the bitmap
* @param w The width of the bitmap
* @param h The height of the bitmap
* @param[in] data The bitmap's data glob
* @param flags
*
* @note The used RAM cannot be freed until bm_release is called on the created bitmap
*/
int bm_create(int bpp, int w, int h, void *data = NULL, int flags = 0);
// Frees up a bitmap's data, but bitmap number 'n' can
// still be used, it will just have to be paged in next
// time it is locked.
int bm_unload( int n, int clear_render_targets = 0, bool nodebug = false);
/**
* @brief Unloads a bitmap's data, but not the bitmap info
*
* @details The bm number (n) may be reused once this function has been called on it. However, it will have to be paged
* in the next time it is locked.
// like bm_unload() except that it's safe to use to free data without worrying about
// load_count so it's safe to use in relation to bm_release() and in gr_*_texture functions
int bm_unload_fast( int n, int clear_render_targets = 0 );
* @param handle The index number of the bitmap to free
* @param clear_render_targets If true, release a render target
* @param nodebug If true, exclude certain debug messages
*
* @returns 0 if not successful,
* @returns 1 if successful
*/
int bm_unload(int handle, int clear_render_targets = 0, bool nodebug = false);
// Frees up a bitmap's data, and it's slot, so bitmap
// number 'n' cannot be used anymore, and bm_load or
// bm_create might reuse the slot.
int bm_release( int n, int clear_render_targets = 0 );
/**
* @brief Quickly unloads a bitmap's data, ignoring the load_count
*
* @details Similar to bm_unload(), except that it can be safely used to free data without worrying about load_count.
* It's safe to use in relation to bm_release() and in gr_*_texture functions
*
* @param handle The bm number of the bitmap to free
* @param clear_render_targets If true, release a render target
*
* @note bm_free_data_fast() is used here and NOT bm_free_data()
*/
int bm_unload_fast(int handle, int clear_render_targets = 0);
// This loads a bitmap sequence so we can draw with it later.
// It returns a negative number if it couldn't load
// the bitmap. On success, it returns the bitmap
// number of the first frame and nframes is set.
extern int bm_load_animation( const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY );
/**
* @brief Frees both a bitmap's data and it's associated slot.
*
* @details Once called, the bm number 'n' cannot be used until bm_load or bm_create is re-inits the slot.
*
* @param handle The index number of the bitmap to release
* @param clear_render_targets If nonzero, also release render targets
*
* @returns 1 on success,
* @returns 0 otherwise
*
* @note If the passed handle is that of an ANI, it frees EVERY frame. Be sure to only pass the handle of the first frame!
*
* @todo upgrade return type and clear_render_targets type to bools
*/
int bm_release(int handle, int clear_render_targets = 0);
//Loads either animation (bm_load_animation) or still image (bm_load)
extern int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
/**
* @brief Loads a bitmap sequance so we can draw with it.
*
* @param[in] filename
* @param[out] nframes If non-null, set to the number of frames the animation has
* @param[out] fps If non-null, set to the fps of this animation
* @param[out] keyframe if non null, set to the keyframe index of this animation
* @param[in] can_drop_frames If set, allows dropped frames
* @param[in] dir_type Directory type
*
* @returns The bm number of the first bitmap in the sequence if successful, or
* @returns A negative value if unsuccessful
*/
int bm_load_animation(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
// This locks down a bitmap and returns a pointer to a bitmap
// that can be accessed until you call bm_unlock. Only lock
// a bitmap when you need it! This will convert it into the
// appropriate format also.
extern bitmap * bm_lock( int bitmapnum, ubyte bpp, ubyte flags, bool nodebug = false);
/**
* @brief Loads either animation (bm_load_animation) or still image (bm_load)
*
* @param[in] filename
* @param[out] nframes If non-null and loading was successful, set to the number of frames the animation has
* @param[out] fps If non-null and loading was successful, set to the fps of this animation
* @param[out] keyframe if non null and loading was successful, set to the keyframe index of this animation
* @param[in] can_drop_frames
* @param[in] dir_type
*
* @returns The bm number of the first bitmap in the sequence if successful, or
* @returns A negative value if unsuccessful
*/
int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, int *keyframe = NULL, int can_drop_frames = 0, int dir_type = CF_TYPE_ANY);
// The signature is a field that gets filled in with
// a unique signature for each bitmap. The signature for each bitmap
// will also change when the bitmap's data changes.
extern uint bm_get_signature( int bitmapnum);
/**
* @brief Locks down the bitmap indexed by bitmapnum.
*
* @details Also converts the bitmap to the appropriate format specified by bpp and flags. Only lock a bitmap when you
* need it!
*
* @param bitmapnum The number indexing the desired bitmap
* @param bpp The desired bpp of the bitmep
* @param flags The desired bitmap format
* @param nodebug
//gets the image type
* @returns A pointer to the bitmap that's valid until bm_unlock is called if successful, or
* @returns NULL if unsuccessful
*/
bitmap* bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug = false);
/**
* @brief Returns a unique signiature for the bitmap indexed by handle
*
* @details A signature will change when the bitmap's data changes
*/
uint bm_get_signature(int handle);
/**
* @brief Returns the image type of the given bitmap handle
*/
ubyte bm_get_type(int handle);
// Unlocks a bitmap
extern void bm_unlock( int bitmapnum );
/**
* @brief Unlocks a bitmap
*
* @details Decrements the ref_count member of the bitmap_entry struct, A bitmap can only be unloaded when the
* ref_count is 0
*/
void bm_unlock(int handle);
//WMC - Returns 0 if invalid, nonzero if valid
extern int bm_is_valid(int handle);
/**
* @brief Checks if the bitmap indexed by handle is valid
*
* @details Some early known false or out of range handles (such as negative) are checked within
* an initial routine pass, followed by a more thorough check routine to ensure the
* series of bitmaps within the bm_bitmaps[] structure have not become invalid.
*
* @returns Nonzero if valid, else
* @returns Zero otherwise
*
* @todo z64 - Returned value is essentially a bool type, need to check all caller functions to see if it can safely
* be updated to reflect this
*/
int bm_is_valid(int handle);
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
//WMC - Returns -1 on failure, handle or first frame handle on success.
int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, int *nframes=NULL, int *fps=NULL );
/**
* @brief Gets info on the bitmap indexed by handle.
*
* @param[out] w If non-null, gets the width
* @param[out] h If non-null, gets the heigth
* @param[out] flags If non-null, gets the flags
* @param[out] nframs If non-null, gets the nframes
* @param[out] fps If non-null, gets the fps
*
* @returns The handle on success, or
* @returns The handle to the first frame on success, or
* @returns -1 on failure
*/
int bm_get_info(int handle, int *w = NULL, int * h = NULL, ubyte * flags = NULL, int *nframes = NULL, int *fps = NULL);
// get filename
extern void bm_get_filename(int bitmapnum, char *filename);
/**
* @brief Gets the filename of the bitmap indexed by handle
*
* @param[out] filename The filename of the bitmap, if successful. Is set to an empty string if unseccessful
*
* @todo z64 - maybe deprecate this in favor of an SCP_string version
*/
void bm_get_filename(int bitmapnum, char *filename);
// call to load all data for all bitmaps that have been requested to be loaded
extern void bm_gfx_load_all();
extern void bm_unload_all();
/**
* @brief Gets the filename of the bitmap indexed by handle, which must exist.
*
* @details If the bitmap does not exist (i.e. the handle is invalid), then an Assertion halts program execution.
*
* @returns A const char* to the filename of the bitmap
*
* @todo z64 - maybe deprecate this in favor of an SCP_string version.
* @todo z64 - maybe combine this with the other bm_get_filename function like so:
* void bm_get_filename(int handle, SCP_string *filename, bool must_exist = false);
*/
const char *bm_get_filename(int handle);
// call to get the palette for a bitmap
void bm_get_palette(int n, ubyte *pal, char *name);
/**
* @brief Loads all data for all bitmaps that have been requested to be loaded
*
* @note This function is not defined.
*/
void bm_gfx_load_all();
// Hacked function to get a pixel from a bitmap.
// Only works good in 8bpp mode.
void bm_gfx_get_pixel( int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *b );
/**
* @brief Unloads all used bitmaps, should only ever be called by game_shutdown()
*
* @todo Maybe move this declaration into bmpman.cpp and then extern this function within game_shutdown() to
* ensure it only ever gets called there.
*/
void bm_unload_all();
// Returns number of bytes of bitmaps locked this frame
// ntotal = number of bytes of bitmaps locked this frame
// nnew = number of bytes of bitmaps locked this frame that weren't locked last frame
/**
* @brief Gets the palette for a given bitmap indexed by handle, and optionally the filename
*
* @param[out] pal Is set to reference the bitmap's palette
* @param[out] name (optional) Is set to the bitmap's filename
*
* @todo Maybe get rid of the optional filename and have the callers call bm_get_filename. Less efficient, however.
*/
void bm_get_palette(int handle, ubyte *pal, char *name);
/**
* @brief Hack to get a pixel from a bitmap
*
* @details only works good in 8bpp mode
*
* @note This function is not defined.
*/
void bm_gfx_get_pixel(int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *b);
/**
* @brief (DEBUG) Gets memory size, in bytes, of the locked bitmaps
*
* @details Both params are non-optional, and must be non-null. There's currently no safety checks on either.
*
* @param ntotal[out] Memory size, in bytes, of the locked bitmaps
* @param nnew[out] Memory size, in bytes, of the bitmaps that were locked since the last frame
*
* @note This is a debug function, and is undefined within release builds
*/
void bm_get_frame_usage(int *ntotal, int *nnew);
// Reload a different image into an existing bmpman slot
/**
* @brief Reloads an existing bmpman slot with different bitmap
*
* @param[in] filename The filename of the image to load
*
* @returns The bitmap handle on success, or
* @returns A negative value on failure
*
* @note This should only be used if you are certain the new picture is the same type, has same dimensions, etc.
*/
int bm_reload(int bitmap_handle, const char* filename);
/*
* Example on using bm_create
*
{
static int test_inited = 0;
static int test_bmp;
static uint test_bmp_data[128*64];
if ( !test_inited ) {
test_inited = 1;
// Create the new bitmap and fill in its data.
// When you're done with it completely, call
// bm_release to free up the bitmap handle
test_bmp = bm_create( 32, 128, 64, test_bmp_data );
int i,j;
for (i=0; i<64; i++ ) {
for (j=0; j<64; j++ ) {
uint r=i*4;
test_bmp_data[j+i*128] = r;
}
}
}
bm_unload(test_bmp); // this pages out the data, so that the
// next bm_lock will convert the new data to the
// correct bpp
// put in new data
int x,y;
gr_reset_clip();
for (y=0; y<64; y++)
for (x=0; x<128; x++ )
test_bmp_data[y*128+x] = 15;
// Draw the bitmap to upper left corner
gr_set_bitmap(test_bmp);
gr_bitmap( 0,0 );
}
*/
//============================================================================
// Paging stuff
//============================================================================
/**
* @brief Tells bmpman to start keeping track of what bitmaps are used where
*/
void bm_page_in_start();
/**
* @brief Tells bmpman to stop paging (?)
*/
void bm_page_in_stop();
// Paging code in a library should call these functions
// in its page in function.
// Marks a texture as being used for this level
// If num_frames is passed, assume this is an animation
void bm_page_in_texture( int bitmapnum, int num_frames = 0 );
/**
* @brief Marks a texture as being used for this level
*
* @param[in] num_frames If specified, assumes this is an animated texture
*/
void bm_page_in_texture(int bitmapnum, int num_frames = 0);
// marks a texture as being a transparent textyre used for this level
// Marks a texture as being used for this level
// If num_frames is passed, assume this is an animation
void bm_page_in_xparent_texture( int bitmapnum, int num_frames=1 );
/**
* @brief Marks a textures as being used for level and is transparant
*
* @param[in] num_frames If specified, assumes this is an animated texture
*/
void bm_page_in_xparent_texture(int bitmapnum, int num_frames = 1);
// Marks an aabitmap as being used for this level
// If num_frames is passed, assume this is an animation
void bm_page_in_aabitmap( int bitmapnum, int num_frames=1 );
/**
* @brief Marks a texture as being used for this level, and is anti-aliased
*
* @param[in] num_frames If specified, assumes this is an animated texture
*/
void bm_page_in_aabitmap(int bitmapnum, int num_frames = 1);
// unload a texture that was paged in
int bm_page_out( int handle );
/**
* @brief Unloads the bitmap indexed by handle that was previously paged-in
*
* @returns 0 If the bitmap had already been released, or
* @returns 0 If the handle is invalid, or
* @returns 1 If successful
*
* @todo The return type should be a bool
*/
int bm_page_out(int handle);
//
// Mode: 0 = High memory
// 1 = Low memory ( every other frame of ani's)
// 2 = Debug low memory ( only use first frame of each ani )
void bm_set_low_mem( int mode );
const char *bm_get_filename(int handle);
/**
* @brief Sets BMPMAN's memory mode
*
* @details 0 = High memory;
* 1 = Low memory (loads every other frame of ani's);
* 2 = Debug low memory (only use first frame of each ani)
*
* @todo This should use an enum, or instead allow an arbitrary number to drop frames (like 1/2, 1/3, etc.)
*/
void bm_set_low_mem(int mode);
/**
* @brief Sets bm_set_components and bm_get_components to reference screen format functions
*/
void BM_SELECT_SCREEN_FORMAT();
/**
* @brief Sets bm_set_components and bm_get_components to reference texture format functions
*/
void BM_SELECT_TEX_FORMAT();
/**
* @brief Sets bm_set_components and bm_get_components to reference texture format functions (with alpha)
*/
void BM_SELECT_ALPHA_TEX_FORMAT();
// set the rgba components of a pixel, any of the parameters can be NULL
extern void (*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
extern void (*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
void bm_set_components_argb_d3d_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Functional pointer that references any of the bm_set_components functions.
*
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
*
* @param[out] pixel The pixel to set
* @param[in] r Red value (may not be NULL)
* @param[in] g Green value (may not be NULL)
* @param[in] b Blue value (may not be NULL)
* @param[in] a Alpha value (currently ignored)
*
* @note z64 - These functions were made predating the introduction of C++ classes, and are basically the equivalent
* of Pixel::set(ubyte *r, ubyte *b, ubyte *g). The original comment mentions that any of the rgba params may be
* NULL, but this is by far _NOT_ the case, as a NULL value will cause undefined behavior (really really bad chroma
* corruption)
*
* @note These functions assume the incoming bitdepth will always be >= to the outgoing bitdepth of the pixel. Should
* the incoming bitdepth be lower, the outgoing values will appear darker than they should be
*/
extern void(*bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
// get the rgba components of a pixel, any of the parameters can be NULL
/**
* @brief Functional pointer that references any of the bm_set_components_32 functions.
*
* @details The bm_set_components functions packs the RGBA values into the ubyte array referenced by pixel, whose
* format differs according to its bpp value and presence of an alpha channel. The RGBA values are scaled accordingly.
*
* @see bm_set_components
*/
extern void(*bm_set_components_32)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 16bpp screen pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_16_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 32bpp screen pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 16bpp texture pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_16_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Sets the 32bpp texture pixel to the specified RGBA value
*
* @see bm_set_components
*/
void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
/**
* @brief Gets the RGBA components of a pixel according to the selected mode
*
* @see BM_SELECT_SCREEN_FORMAT() BM_SELECT_TEX_FORMAT() BM_SELECT_ALPHA_TEX_FORMAT()
*/
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
extern int GLOWMAP; //this holds a reference to a map that is a fully lit version of its index -Bobboau
extern int SPECMAP; //this holds a reference to a map that is for specular mapping -Bobboau
extern int ENVMAP; //this holds a reference to a map that is for environment mapping -Bobboau
extern int NORMMAP; // normal mapping
extern int HEIGHTMAP; // height map for normal mapping
extern int MISCMAP; // Utility map, to be utilized for various things shader authors can come up with
/**
* @brief Returns the compression type of the bitmap indexed by handle
*/
int bm_is_compressed(int handle);
int bm_is_compressed(int num);
int bm_get_tcache_type(int num);
int bm_get_size(int num);
int bm_get_num_mipmaps(int num);
/**
* @brief Gets the correct TCACHE_TYPE for compressed graphics (uncompressed are assumed TCACHE_TYPE_NORMAL)
*/
int bm_get_tcache_type(int handle);
/**
* @brief Gets the size, in bytes, taken up by the bitmap indexed by handle
*
* @todo retval should be a size_t
*/
int bm_get_size(int handle);
/**
* @brief Gets the number of mipmaps of the indexed texture
*/
int bm_get_num_mipmaps(int handle);
/**
* @brief Checks to see if the indexed bitmap has an alpha channel
*
* @note Currently just checks if the bitmap is 32bpp and is not a .PCX
*
* @todo retval should be a bool
*/
int bm_has_alpha_channel(int handle);
/**
* @brief (DEBUG) Prints all loaded bitmaps to an outwindow
*/
void bm_print_bitmaps();
int bm_make_render_target( int width, int height, int flags );
int bm_is_render_target(int bitmap_id);
/**
* @brief Creates a render target as close to the desired resolution as possible.
*
* @returns the handle of an avilable render target if successful, or
* @returns -1 if not successful
*
* @note BM_FLAG_RENDER_TARGET_STATIC are drawn once/infrequently, while BM_FLAG_RENDER_TARGET_DYNAMIC are drawn roughly once every frame
*/
int bm_make_render_target(int width, int height, int flags);
/**
* @brief Checks to see if the given bitmap indexed by handle is a render target
*
* @returns The render type (BM_TYPE) if it is a render target, or
* @returns 0 if it is not
*/
int bm_is_render_target(int handle);
/**
* @brief (GR function) Calls gr_bm_set_render target for the given bitmap indexed by handle
*
* @returns 1 if successful, or
* @returns 0 if unsuccessful
*
* @todo retval should be a bool
*/
int bm_set_render_target(int handle, int face = -1);
/**
* @brief Loads and parses an .EFF
*
* @param[in] filename The filename of the .EFF
* @param[in] dir_type
* @param[out] nframes (optional) If given, is set to the number of frames this .EFF has
* @param[out] nfps (optional) If given, is set to the fps of this .EFF
* @param[out] key (optional) If given, is set to the keyframe index of this .EFF
* @param[out] type (optional) If given, is set to the BM_TYPE of the .EFF
*
* @returns 0 If successful,
* @returns -1 if not successful
*
* @todo retval should be a bool
*/
int bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type);
#endif
+13 -13
View File
@@ -540,8 +540,10 @@ void warp_camera::get_info(vec3d *position, matrix *orientation)
//*************************subtitle*************************
#define MAX_SUBTITLE_LINES 64
subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim, float in_display_time, float in_fade_time, color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width, int in_height, bool in_post_shaded)
subtitle::subtitle(int in_x_pos, int in_y_pos, const char* in_text, const char* in_imageanim, float in_display_time, float in_fade_time, const color *in_text_color, int in_text_fontnum, bool center_x, bool center_y, int in_width, int in_height, bool in_post_shaded)
{
SCP_string text_buf;
// basic init, this always has to be done
memset( imageanim, 0, sizeof(imageanim) );
memset( &text_pos, 0, 2*sizeof(int) );
@@ -551,12 +553,11 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
if ( ((in_text != NULL) && (strlen(in_text) <= 0)) && ((in_imageanim != NULL) && (strlen(in_imageanim) <= 0)) )
return;
char text_buf[256];
if (in_text != NULL && in_text[0] != '\0')
{
strcpy_s(text_buf, in_text);
sexp_replace_variable_names_with_values(text_buf, 256);
in_text = text_buf;
text_buf = in_text;
sexp_replace_variable_names_with_values(text_buf);
in_text = text_buf.c_str();
}
@@ -569,11 +570,10 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim
int split_width = (in_width > 0) ? in_width : 200;
num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
SCP_string temp_str;
for(int i = 0; i < num_text_lines; i++)
{
temp_str.assign(text_line_ptrs[i], text_line_lens[i]);
text_lines.push_back(temp_str);
text_buf.assign(text_line_ptrs[i], text_line_lens[i]);
text_lines.push_back(text_buf);
}
}
@@ -718,7 +718,7 @@ void subtitle::do_frame(float frametime)
for(SCP_vector<SCP_string>::iterator line = text_lines.begin(); line != text_lines.end(); ++line)
{
gr_string(x, y, (char*)line->c_str(), false);
gr_string(x, y, (char*)line->c_str(), GR_RESIZE_NONE);
y += font_height;
}
@@ -739,18 +739,18 @@ void subtitle::do_frame(float frametime)
vec3d scale;
bm_get_info(image_id, &orig_w, &orig_h);
scale.xyz.x = image_pos.w / (float) orig_w;
scale.xyz.y = image_pos.h / (float) orig_h;
scale.xyz.x = (image_pos.w > 0) ? (image_pos.w / (float) orig_w) : 1.0f;
scale.xyz.y = (image_pos.h > 0) ? (image_pos.h / (float) orig_h) : 1.0f;
scale.xyz.z = 1.0f;
gr_push_scale_matrix(&scale);
gr_bitmap(image_pos.x, image_pos.y, false);
gr_bitmap(fl2i(image_pos.x / scale.xyz.x), fl2i(image_pos.y / scale.xyz.y), GR_RESIZE_NONE);
gr_pop_scale_matrix();
}
// no scaling
else
{
gr_bitmap(image_pos.x, image_pos.y, false);
gr_bitmap(image_pos.x, image_pos.y, GR_RESIZE_NONE);
}
}
+2 -2
View File
@@ -137,8 +137,8 @@ private:
bool post_shaded;
public:
subtitle(int in_x_pos, int in_y_pos, char* in_text = NULL, char* in_imageanim = NULL,
float in_display_time = 0, float in_fade_time = 0.0f, color *in_text_color = NULL, int in_text_fontnum = -1,
subtitle(int in_x_pos, int in_y_pos, const char* in_text = NULL, const char* in_imageanim = NULL,
float in_display_time = 0, float in_fade_time = 0.0f, const color *in_text_color = NULL, int in_text_fontnum = -1,
bool center_x = false, bool center_y = false, int in_width = 0, int in_height = 0, bool post_shaded=false);
~subtitle();
+8 -14
View File
@@ -35,7 +35,6 @@
#include "osapi/osapi.h"
char Cfile_root_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
#ifdef SCP_UNIX
char Cfile_user_dir[CFILE_ROOT_DIRECTORY_LEN] = "";
@@ -492,23 +491,17 @@ int cf_access(const char *filename, int dir_type, int mode)
// Returns 1 if the file exists, 0 if not.
// Checks only the file system.
// cf_find_file_location checks the filesystem before VPs
// If offset is 0, it was found in the filesystem, so offset is boolean false
// If offset equates to boolean true, it was found in a VP and the logic will negate the function return
int cf_exists(const char *filename, int dir_type)
{
char longname[MAX_PATH_LEN];
int offset = 1;
Assert(CF_TYPE_SPECIFIED(dir_type));
if ( (filename == NULL) || !strlen(filename) )
return 0;
cf_create_default_path_string(longname, sizeof(longname) - 1, dir_type, filename);
FILE *fp = fopen(longname, "rb");
if (fp)
{
// Goober5000 - these were switched, causing the fclose to be unreachable
fclose(fp);
return 1;
}
return 0;
return (cf_find_file_location(filename, dir_type, 0, NULL, &offset, NULL) && !offset);
}
// Goober5000
@@ -736,6 +729,7 @@ CFILE *cfopen(const char *file_path, const char *mode, int type, int dir_type, b
if ( cf_find_file_location( copy_file_path, dir_type, sizeof(longname) - 1, longname, &size, &offset, localize ) ) {
// Fount it, now create a cfile out of it
nprintf(("CFileDebug", "Requested file %s found at: %s\n", file_path, longname));
if ( type & CFILE_MEMORY_MAPPED ) {
+1 -1
View File
@@ -387,6 +387,6 @@ namespace cfile
}
};
};
}
#endif /* __CFILE_H__ */
+4 -3
View File
@@ -388,7 +388,7 @@ void cf_build_root_list(const char *cdrom_dir)
// truncated string check
if ( (strlen(Cfile_user_dir) + strlen(str_temp) + 1) >= CF_MAX_PATHNAME_LENGTH ) {
Int3();
Error(LOCATION, "Home directory plus mod directory exceeds CF_MAX_PATHNAME_LENGTH\n");
}
root = cf_create_root();
@@ -444,7 +444,7 @@ void cf_build_root_list(const char *cdrom_dir)
// truncated string check
if ( (strlen(root->path) + strlen(str_temp) + 1) >= CF_MAX_PATHNAME_LENGTH ) {
Int3();
Error(LOCATION, "Installed path plus mod directory exceeds CF_MAX_PATHNAME_LENGTH\n");
}
path_len = strlen(root->path);
@@ -507,7 +507,7 @@ int is_ext_in_list( const char *ext_list, const char *ext )
{
char tmp_ext[128];
strncpy( tmp_ext, ext, 127 );
strcpy_s( tmp_ext, ext);
strlwr(tmp_ext);
if ( strstr(ext_list, tmp_ext )) {
return 1;
@@ -695,6 +695,7 @@ void cf_search_root_pack(int root_index)
find.offset = INTEL_INT( find.offset ); //-V570
find.size = INTEL_INT( find.size ); //-V570
find.write_time = INTEL_INT( find.write_time ); //-V570
find.filename[sizeof(find.filename)-1] = '\0';
if ( find.size == 0 ) {
int search_path_len = strlen(search_path);
+335 -224
View File
@@ -29,22 +29,40 @@
#ifdef SCP_UNIX
#include "osapi/osapi.h"
#include <dirent.h>
#endif
#include <string.h>
#include <stdlib.h>
enum cmdline_arg_type
{
AT_NONE =0,
AT_INT,
AT_FLOAT,
AT_STRING
};
// values and order MUST match cmdline_arg_type
const char *cmdline_arg_types[] =
{
"NONE",
"INT",
"FLOAT",
"STRING",
};
// variables
class cmdline_parm {
public:
cmdline_parm *next, *prev;
char *name; // name of parameter, must start with '-' char
char *help; // help text for this parameter
bool stacks; // whether this arg stacks with each use or is replaced by newest use (should only be used for strings!!)
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(char *name, char *help, bool stacks = false);
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false);
~cmdline_parm();
int found();
int get_int();
@@ -53,12 +71,11 @@ public:
bool check_if_args_is_valid();
};
static cmdline_parm Parm_list(NULL, NULL);
static cmdline_parm Parm_list(NULL, NULL, AT_NONE);
static int Parm_list_inited = 0;
extern int Show_framerate; // from freespace.cpp
enum
{
// DO NOT CHANGE ANYTHING ABOUT THESE FIRST TWO OR WILL MESS UP THE LAUNCHER
@@ -83,7 +100,7 @@ enum
typedef struct
{
// DO NOT CHANGE THE SIZE OF THIS STRING!
// DO NOT CHANGE THE SIZE OF THIS AT_STRING!
char name[32];
} EasyFlag;
@@ -113,21 +130,24 @@ typedef struct
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
Flag exe_params[] =
{
{ "-nospec", "Disable specular", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-noglow", "Disable glow maps", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-noenv", "Disable environment maps", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-nospec", "Disable specular", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-nomotiondebris", "Disable motion debris", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
{ "-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", },
{ "-nonormal", "Disable normal maps", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-nonormal", "Disable normal maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-noheight", "Disable height/parallax maps", true, EASY_DEFAULT_MEM, EASY_MEM_ALL_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-height" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-soft_particles", "Enable soft particles", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
{ "-fxaa", "Enable FXAA anti-aliasing", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-nolightshafts", "Disable lightshafts", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-flightshaftsoff"},
{ "-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_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fxaa" },
{ "-nolightshafts", "Disable lightshafts", true, EASY_DEFAULT, EASY_ALL_ON, "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", },
{ "-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", },
{ "-no_fps_capping", "Don't limit frames-per-second", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_fps_capping", },
{ "-cache_bitmaps", "Cache bitmaps between missions", true, 0, EASY_DEFAULT_MEM, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-cache_bitmaps", },
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
@@ -141,6 +161,7 @@ Flag exe_params[] =
{ "-3dwarp", "Enable 3D warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-stretch_menu", "Stretch interface to fill screen", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stretch_menu", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
@@ -165,19 +186,20 @@ Flag exe_params[] =
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
{ "-disable_pbo", "Disable OpenGL Pixel Buffer Objects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_pbo", },
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_glsl", },
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ati_swap", },
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
{ "-disable_glsl_model","Don't use shaders for model rendering", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_glsl_model", },
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
#ifndef SCP_UNIX
{ "-disable_di_mouse", "Don't use DirectInput for mouse control", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-disable_di_mouse", "Don't use DirectInput for mouse control", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_di_mouse", },
#endif
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-old_collision", "Use old collision detection system", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
{ "-old_collision", "Use old collision detection system", true, EASY_DEFAULT, EASY_ALL_ON, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-old_collision", },
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
{ "-ingame_join", "Allow in-game joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, 0, EASY_DEFAULT, "Experimental", "", },
{ "-brief_lighting", "Enable lighting on briefing models", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-brief_lighting", },
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
@@ -188,9 +210,9 @@ Flag exe_params[] =
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
{ "-pofspew", "", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
{ "-pofspew", "Generate all ibx files immediately", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "Dump table CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "Dump mission CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
@@ -207,27 +229,30 @@ Flag exe_params[] =
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
};
// forward declaration
const char * get_param_desc(const char *flag_name);
// here are the command line parameters that we will be using for FreeSpace
// RETAIL options ----------------------------------------------
cmdline_parm connect_arg("-connect", NULL); // Cmdline_connect_addr
cmdline_parm gamename_arg("-gamename", NULL); // Cmdline_game_name
cmdline_parm gamepassword_arg("-password", NULL); // Cmdline_game_password
cmdline_parm allowabove_arg("-allowabove", NULL); // Cmdline_rank_above
cmdline_parm allowbelow_arg("-allowbelow", NULL); // Cmdline_rank_below
cmdline_parm standalone_arg("-standalone", NULL);
cmdline_parm nosound_arg("-nosound", NULL); // Cmdline_freespace_no_sound
cmdline_parm nomusic_arg("-nomusic", NULL); // Cmdline_freespace_no_music
cmdline_parm startgame_arg("-startgame", NULL); // Cmdline_start_netgame
cmdline_parm gameclosed_arg("-closed", NULL); // Cmdline_closed_game
cmdline_parm gamerestricted_arg("-restricted", NULL); // Cmdline_restricted_game
cmdline_parm port_arg("-port", NULL);
cmdline_parm multilog_arg("-multilog", NULL); // Cmdline_multi_log
cmdline_parm client_dodamage("-clientdamage", NULL); // Cmdline_client_dodamage
cmdline_parm pof_spew("-pofspew", NULL); // Cmdline_spew_pof_info
cmdline_parm mouse_coords("-coords", NULL); // Cmdline_mouse_coords
cmdline_parm timeout("-timeout", NULL); // Cmdline_timeout
cmdline_parm bit32_arg("-32bit", NULL); // (only here for retail compatibility reasons, doesn't actually do anything)
cmdline_parm connect_arg("-connect", "Automatically connect to multiplayer IP:PORT", AT_STRING); // Cmdline_connect_addr
cmdline_parm gamename_arg("-gamename", "Set multiplayer game name", AT_STRING); // Cmdline_game_name
cmdline_parm gamepassword_arg("-password", "Set multiplayer game password", AT_STRING); // Cmdline_game_password
cmdline_parm allowabove_arg("-allowabove", "Ranks above this can join multi", AT_STRING); // Cmdline_rank_above
cmdline_parm allowbelow_arg("-allowbelow", "Ranks below this can join multi", AT_STRING); // Cmdline_rank_below
cmdline_parm standalone_arg("-standalone", NULL, AT_NONE);
cmdline_parm nosound_arg("-nosound", NULL, AT_NONE); // Cmdline_freespace_no_sound
cmdline_parm nomusic_arg("-nomusic", NULL, AT_NONE); // Cmdline_freespace_no_music
cmdline_parm startgame_arg("-startgame", NULL, AT_NONE); // Cmdline_start_netgame
cmdline_parm gameclosed_arg("-closed", NULL, AT_NONE); // Cmdline_closed_game
cmdline_parm gamerestricted_arg("-restricted", NULL, AT_NONE); // Cmdline_restricted_game
cmdline_parm port_arg("-port", "Multiplayer network port", AT_INT);
cmdline_parm multilog_arg("-multilog", NULL, AT_NONE); // Cmdline_multi_log
cmdline_parm client_dodamage("-clientdamage", NULL, AT_NONE); // Cmdline_client_dodamage
cmdline_parm pof_spew("-pofspew", NULL, AT_NONE); // Cmdline_spew_pof_info
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;
@@ -254,31 +279,32 @@ int Cmdline_use_last_pilot = 0;
// FSO options -------------------------------------------------
// Graphics related
cmdline_parm spec_exp_arg("-spec_exp", NULL); // comand line FOV -Bobboau
cmdline_parm clip_dist_arg("-clipdist", NULL); // Cmdline_clip_dist
cmdline_parm fov_arg("-fov", NULL); // Cmdline_fov -- comand line FOV -Bobboau
cmdline_parm ogl_spec_arg("-ogl_spec", NULL); // Cmdline_ogl_spec
cmdline_parm spec_static_arg("-spec_static", NULL);
cmdline_parm spec_point_arg("-spec_point", NULL);
cmdline_parm spec_tube_arg("-spec_tube", NULL);
cmdline_parm ambient_factor_arg("-ambient_factor", NULL); // Cmdline_ambient_factor
cmdline_parm env("-noenv", NULL); // Cmdline_env
cmdline_parm missile_lighting_arg("-missile_lighting", NULL); // Cmdline_missile_lighting
cmdline_parm glow_arg("-noglow", NULL); // Cmdline_glow -- use Bobs glow code
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
cmdline_parm noscalevid_arg("-noscalevid", NULL); // Cmdline_noscalevid -- disable video scaling that fits to window
cmdline_parm spec_arg("-nospec", NULL); // Cmdline_spec --
cmdline_parm noemissive_arg("-no_emissive_light", NULL); // Cmdline_no_emissive -- don't use emissive light in OGL
cmdline_parm normal_arg("-nonormal", NULL); // Cmdline_normal -- disable normal mapping
cmdline_parm height_arg("-noheight", NULL); // Cmdline_height -- enable support for parallax mapping
cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL);
cmdline_parm softparticles_arg("-soft_particles", NULL);
cmdline_parm postprocess_arg("-post_process", NULL);
cmdline_parm bloom_intensity_arg("-bloom_intensity", NULL);
cmdline_parm fxaa_arg("-fxaa", NULL);
cmdline_parm fxaa_preset_arg("-fxaa_preset", NULL);
cmdline_parm fb_explosions_arg("-fb_explosions", NULL);
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL);
cmdline_parm fov_arg("-fov", "Vertical field-of-view factor", AT_FLOAT); // Cmdline_fov -- comand line FOV -Bobboau
cmdline_parm clip_dist_arg("-clipdist", "Changes the distance from the viewpoint for the near-clipping plane", AT_FLOAT); // Cmdline_clip_dist
cmdline_parm spec_exp_arg("-spec_exp", "Adjusts the size of shiny spots on ships", AT_FLOAT);
cmdline_parm ogl_spec_arg("-ogl_spec", "Shininess of specular light", AT_FLOAT); // Cmdline_ogl_spec
cmdline_parm spec_static_arg("-spec_static", "Adjusts suns contribution to specular highlights", AT_FLOAT);
cmdline_parm spec_point_arg("-spec_point", "Adjusts laser weapons contribution to specular highlights", AT_FLOAT);
cmdline_parm spec_tube_arg("-spec_tube", "Adjusts beam weapons contribution to specular highlights", AT_FLOAT);
cmdline_parm ambient_factor_arg("-ambient_factor", "Adjusts ambient light applied to all parts of a ship", AT_INT); // Cmdline_ambient_factor
cmdline_parm missile_lighting_arg("-missile_lighting", NULL, AT_NONE); // Cmdline_missile_lighting
cmdline_parm env("-noenv", NULL, AT_NONE); // Cmdline_env
cmdline_parm glow_arg("-noglow", NULL, AT_NONE); // Cmdline_glow -- use Bobs glow code
cmdline_parm nomotiondebris_arg("-nomotiondebris", NULL, AT_NONE); // Cmdline_nomotiondebris -- Removes those ugly floating rocks -C
cmdline_parm noscalevid_arg("-noscalevid", NULL, AT_NONE); // Cmdline_noscalevid -- disable video scaling that fits to window
cmdline_parm spec_arg("-nospec", NULL, AT_NONE); // Cmdline_spec --
cmdline_parm noemissive_arg("-no_emissive_light", "Disable emissive light from ships", AT_NONE); // Cmdline_no_emissive -- don't use emissive light in OGL
cmdline_parm normal_arg("-nonormal", NULL, AT_NONE); // Cmdline_normal -- disable normal mapping
cmdline_parm height_arg("-noheight", NULL, AT_NONE); // Cmdline_height -- enable support for parallax mapping
cmdline_parm enable_3d_shockwave_arg("-3dshockwave", NULL, AT_NONE);
cmdline_parm softparticles_arg("-soft_particles", NULL, AT_NONE);
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 fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
cmdline_parm flightshaftsoff_arg("-nolightshafts", NULL, AT_NONE);
cmdline_parm brieflighting_arg("-brief_lighting", NULL, AT_NONE);
float Cmdline_clip_dist = Default_min_draw_distance;
float Cmdline_fov = 0.75f;
@@ -303,12 +329,13 @@ int Cmdline_fxaa_preset = 6;
extern int Fxaa_preset_last_frame;
bool Cmdline_fb_explosions = 0;
extern bool ls_force_off;
bool Cmdline_brief_lighting = 0;
// Game Speed related
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL); // Cmdline_cache_bitmaps
cmdline_parm img2dds_arg("-img2dds", NULL); // Cmdline_img2dds
cmdline_parm no_fpscap("-no_fps_capping", NULL); // Cmdline_NoFPSCap
cmdline_parm no_vsync_arg("-no_vsync", NULL); // Cmdline_no_vsync
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL, AT_NONE); // Cmdline_cache_bitmaps
cmdline_parm img2dds_arg("-img2dds", NULL, AT_NONE); // Cmdline_img2dds
cmdline_parm no_fpscap("-no_fps_capping", "Don't limit frames-per-second", AT_NONE); // Cmdline_NoFPSCap
cmdline_parm no_vsync_arg("-no_vsync", NULL, AT_NONE); // Cmdline_no_vsync
int Cmdline_cache_bitmaps = 0; // caching of bitmaps between missions (faster loads, can hit swap on reload with <512 Meg RAM though) - taylor
int Cmdline_img2dds = 0;
@@ -316,11 +343,11 @@ int Cmdline_NoFPSCap = 0; // Disable FPS capping - kazan
int Cmdline_no_vsync = 0;
// HUD related
cmdline_parm ballistic_gauge("-ballistic_gauge", NULL); // Cmdline_ballistic_gauge
cmdline_parm dualscanlines_arg("-dualscanlines", NULL); // Cmdline_dualscanlines -- Change to phreaks options including new targeting code
cmdline_parm orb_radar("-orbradar", NULL); // Cmdline_orb_radar
cmdline_parm rearm_timer_arg("-rearm_timer", NULL); // Cmdline_rearm_timer
cmdline_parm targetinfo_arg("-targetinfo", NULL); // Cmdline_targetinfo -- Adds ship name/class to right of target box -C
cmdline_parm ballistic_gauge("-ballistic_gauge", NULL, AT_NONE); // Cmdline_ballistic_gauge
cmdline_parm dualscanlines_arg("-dualscanlines", NULL, AT_NONE); // Cmdline_dualscanlines -- Change to phreaks options including new targeting code
cmdline_parm orb_radar("-orbradar", NULL, AT_NONE); // Cmdline_orb_radar
cmdline_parm rearm_timer_arg("-rearm_timer", NULL, AT_NONE); // Cmdline_rearm_timer
cmdline_parm targetinfo_arg("-targetinfo", NULL, AT_NONE); // Cmdline_targetinfo -- Adds ship name/class to right of target box -C
int Cmdline_ballistic_gauge = 0; // WMCoolmon's gauge thingy
int Cmdline_dualscanlines = 0;
@@ -329,39 +356,41 @@ int Cmdline_rearm_timer = 0;
int Cmdline_targetinfo = 0;
// Gameplay related
cmdline_parm use_3dwarp("-3dwarp", NULL); // Cmdline_3dwarp
cmdline_parm ship_choice_3d_arg("-ship_choice_3d", NULL); // Cmdline_ship_choice_3d
cmdline_parm weapon_choice_3d_arg("-weapon_choice_3d", NULL); // Cmdline_weapon_choice_3d
cmdline_parm use_warp_flash("-warp_flash", NULL); // Cmdline_warp_flash
cmdline_parm allow_autpilot_interrupt("-no_ap_interrupt", NULL); // Cmdline_warp_flash
cmdline_parm use_3dwarp("-3dwarp", NULL, AT_NONE); // Cmdline_3dwarp
cmdline_parm ship_choice_3d_arg("-ship_choice_3d", NULL, AT_NONE); // Cmdline_ship_choice_3d
cmdline_parm weapon_choice_3d_arg("-weapon_choice_3d", NULL, AT_NONE); // Cmdline_weapon_choice_3d
cmdline_parm use_warp_flash("-warp_flash", NULL, AT_NONE); // Cmdline_warp_flash
cmdline_parm allow_autpilot_interrupt("-no_ap_interrupt", NULL, AT_NONE);
cmdline_parm stretch_menu("-stretch_menu", NULL, AT_NONE); // Cmdline_stretch_menu
int Cmdline_3dwarp = 0;
int Cmdline_ship_choice_3d = 0;
int Cmdline_weapon_choice_3d = 0;
int Cmdline_warp_flash = 0;
int Cmdline_autopilot_interruptable = 1;
int Cmdline_stretch_menu = 0;
// Audio related
cmdline_parm query_speech_arg("-query_speech", NULL); // Cmdline_query_speech
cmdline_parm snd_preload_arg("-snd_preload", NULL); // Cmdline_snd_preload
cmdline_parm voice_recognition_arg("-voicer", NULL); // Cmdline_voice_recognition
cmdline_parm query_speech_arg("-query_speech", NULL, AT_NONE); // Cmdline_query_speech
cmdline_parm snd_preload_arg("-snd_preload", NULL, AT_NONE); // Cmdline_snd_preload
cmdline_parm voice_recognition_arg("-voicer", NULL, AT_NONE); // Cmdline_voice_recognition
int Cmdline_query_speech = 0;
int Cmdline_snd_preload = 0; // preload game sounds during mission load
int Cmdline_voice_recognition = 0;
// MOD related
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
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
// Multiplayer/Network related
cmdline_parm almission_arg("-almission", NULL); // Cmdline_almission -- DTP for autoload Multi mission
cmdline_parm ingamejoin_arg("-ingame_join", NULL); // Cmdline_ingamejoin
cmdline_parm mpnoreturn_arg("-mpnoreturn", NULL); // Cmdline_mpnoreturn -- Removes 'Return to Flight Deck' in respawn dialog -C
cmdline_parm missioncrcspew_arg("-missioncrcs", NULL); // Cmdline_spew_mission_crcs
cmdline_parm tablecrcspew_arg("-tablecrcs", NULL); // Cmdline_spew_table_crcs
cmdline_parm objupd_arg("-cap_object_update", NULL);
cmdline_parm almission_arg("-almission", "Autoload multiplayer mission", AT_STRING); // Cmdline_almission -- DTP for autoload Multi mission
cmdline_parm ingamejoin_arg("-ingame_join", NULL, AT_NONE); // Cmdline_ingamejoin
cmdline_parm mpnoreturn_arg("-mpnoreturn", NULL, AT_NONE); // Cmdline_mpnoreturn -- Removes 'Return to Flight Deck' in respawn dialog -C
cmdline_parm missioncrcspew_arg("-missioncrcs", NULL, AT_STRING); // Cmdline_spew_mission_crcs
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.
int Cmdline_ingamejoin = 0;
@@ -371,22 +400,24 @@ char *Cmdline_spew_table_crcs = NULL;
int Cmdline_objupd = 3; // client object updates on LAN by default
// Troubleshooting
cmdline_parm loadallweapons_arg("-loadallweps", NULL); // Cmdline_load_all_weapons
cmdline_parm htl_arg("-nohtl", NULL); // Cmdline_nohtl -- don't use HT&L
cmdline_parm noibx_arg("-noibx", NULL); // Cmdline_noibx
cmdline_parm nomovies_arg("-nomovies", NULL); // Cmdline_nomovies -- Allows video streaming
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL); // Cmdline_no_set_gamma
cmdline_parm no_vbo_arg("-novbo", NULL); // Cmdline_novbo
cmdline_parm no_fbo_arg("-disable_fbo", NULL); // Cmdline_no_fbo
cmdline_parm no_pbo_arg("-disable_pbo", NULL); // Cmdline_no_pbo
cmdline_parm noglsl_arg("-no_glsl", NULL); // Cmdline_noglsl -- disable GLSL support in OpenGL
cmdline_parm mipmap_arg("-mipmap", NULL); // Cmdline_mipmap
cmdline_parm atiswap_arg("-ati_swap", NULL); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
cmdline_parm no3dsound_arg("-no_3d_sound", NULL); // Cmdline_no_3d_sound - Disable use of full 3D sounds
cmdline_parm no_glsl_models_arg("-disable_glsl_model", NULL); // Cmdline_no_glsl_model_rendering -- switches model rendering to fixed pipeline
cmdline_parm no_di_mouse_arg("-disable_di_mouse", NULL); // Cmdline_no_di_mouse -- Disables directinput use for mouse control
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
cmdline_parm keyboard_layout("-keyboard_layout", NULL);
cmdline_parm loadallweapons_arg("-loadallweps", NULL, AT_NONE); // Cmdline_load_all_weapons
cmdline_parm htl_arg("-nohtl", NULL, AT_NONE); // Cmdline_nohtl -- don't use HT&L
cmdline_parm noibx_arg("-noibx", NULL, AT_NONE); // Cmdline_noibx
cmdline_parm nomovies_arg("-nomovies", NULL, AT_NONE); // Cmdline_nomovies -- Allows video streaming
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL, AT_NONE); // Cmdline_no_set_gamma
cmdline_parm no_vbo_arg("-novbo", NULL, AT_NONE); // Cmdline_novbo
cmdline_parm no_fbo_arg("-disable_fbo", NULL, AT_NONE); // Cmdline_no_fbo
cmdline_parm no_pbo_arg("-disable_pbo", NULL, AT_NONE); // Cmdline_no_pbo
cmdline_parm noglsl_arg("-no_glsl", NULL, AT_NONE); // Cmdline_noglsl -- disable GLSL support in OpenGL
cmdline_parm mipmap_arg("-mipmap", NULL, AT_NONE); // Cmdline_mipmap
cmdline_parm atiswap_arg("-ati_swap", NULL, AT_NONE); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
cmdline_parm no3dsound_arg("-no_3d_sound", NULL, AT_NONE); // Cmdline_no_3d_sound - Disable use of full 3D sounds
cmdline_parm no_glsl_models_arg("-disable_glsl_model", NULL, AT_NONE); // Cmdline_no_glsl_model_rendering -- switches model rendering to fixed pipeline
cmdline_parm no_di_mouse_arg("-disable_di_mouse", "Disable DirectInput mouse code (Windows only)", AT_NONE); // Cmdline_no_di_mouse -- Disables directinput use for mouse control
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL, AT_NONE); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
cmdline_parm keyboard_layout("-keyboard_layout", "Specify keyboard layout (qwertz or azerty)", AT_STRING);
cmdline_parm old_collision_system("-old_collision", NULL, AT_NONE); // Cmdline_old_collision_sys
cmdline_parm gl_finish ("-gl_finish", NULL, AT_NONE);
int Cmdline_load_all_weapons = 0;
int Cmdline_nohtl = 0;
@@ -403,35 +434,35 @@ int Cmdline_no_glsl_model_rendering = 0;
int Cmdline_no_di_mouse = 0;
int Cmdline_drawelements = 0;
char* Cmdline_keyboard_layout = NULL;
bool Cmdline_gl_finish = false;
// Developer/Testing related
cmdline_parm start_mission_arg("-start_mission", NULL); // Cmdline_start_mission
cmdline_parm old_collision_system("-old_collision", NULL); // Cmdline_new_collision
cmdline_parm dis_collisions("-dis_collisions", NULL); // Cmdline_dis_collisions
cmdline_parm dis_weapons("-dis_weapons", NULL); // Cmdline_dis_weapons
cmdline_parm noparseerrors_arg("-noparseerrors", NULL); // Cmdline_noparseerrors -- turns off parsing errors -C
cmdline_parm start_mission_arg("-start_mission", "Skip mainhall and run this mission", AT_STRING); // Cmdline_start_mission
cmdline_parm dis_collisions("-dis_collisions", NULL, AT_NONE); // Cmdline_dis_collisions
cmdline_parm dis_weapons("-dis_weapons", NULL, AT_NONE); // Cmdline_dis_weapons
cmdline_parm noparseerrors_arg("-noparseerrors", NULL, AT_NONE); // Cmdline_noparseerrors -- turns off parsing errors -C
#ifdef Allow_NoWarn
cmdline_parm nowarn_arg("-no_warn", NULL); // Cmdline_nowarn
cmdline_parm nowarn_arg("-no_warn", "Disable warnings (not recommended)", AT_NONE); // Cmdline_nowarn
#endif
cmdline_parm extra_warn_arg("-extra_warn", NULL); // Cmdline_extra_warn
cmdline_parm fps_arg("-fps", NULL); // Cmdline_show_fps
cmdline_parm show_mem_usage_arg("-show_mem_usage", NULL); // Cmdline_show_mem_usage
cmdline_parm pos_arg("-pos", NULL); // Cmdline_show_pos
cmdline_parm stats_arg("-stats", NULL); // Cmdline_show_stats
cmdline_parm save_render_targets_arg("-save_render_target", NULL); // Cmdline_save_render_targets
cmdline_parm debug_window_arg("-debug_window", NULL); // Cmdline_debug_window
cmdline_parm window_arg("-window", NULL); // Cmdline_window
cmdline_parm fullscreen_window_arg("-fullscreen_window",NULL);
cmdline_parm res_arg("-res", NULL); // Cmdline_lores
cmdline_parm verify_vps_arg("-verify_vps", NULL); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, NULL);
cmdline_parm extra_warn_arg("-extra_warn", "Enable 'extra' warnings", AT_NONE); // Cmdline_extra_warn
cmdline_parm fps_arg("-fps", NULL, AT_NONE); // Cmdline_show_fps
cmdline_parm show_mem_usage_arg("-show_mem_usage", NULL, AT_NONE); // Cmdline_show_mem_usage
cmdline_parm pos_arg("-pos", NULL, AT_NONE); // Cmdline_show_pos
cmdline_parm stats_arg("-stats", NULL, AT_NONE); // Cmdline_show_stats
cmdline_parm save_render_targets_arg("-save_render_target", NULL, AT_NONE); // Cmdline_save_render_targets
cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_window
cmdline_parm window_arg("-window", NULL, AT_NONE); // Cmdline_window
cmdline_parm fullscreen_window_arg("-fullscreen_window", "Fullscreen/borderless window (Windows only)", AT_NONE);
cmdline_parm res_arg("-res", "Resolution, formatted like 1600x900", AT_STRING);
cmdline_parm verify_vps_arg("-verify_vps", NULL, AT_NONE); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, "Ignore any cmdline_fso.cfg files", AT_NONE);
#ifdef SCP_UNIX
cmdline_parm no_grab("-nograb", NULL); // Cmdline_no_grab
cmdline_parm no_grab("-nograb", NULL, AT_NONE); // Cmdline_no_grab
#endif
cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL); //Cmdline_reparse_mainhall
cmdline_parm frame_profile_arg("-profile_frame_time", NULL); //Cmdline_frame_profile
cmdline_parm frame_profile_write_file("-profile_write_file", NULL); // Cmdline_profile_write_file
cmdline_parm no_unfocused_pause_arg("-no_unfocused_pause", NULL); //Cmdline_no_unfocus_pause
cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL, AT_NONE); //Cmdline_reparse_mainhall
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
cmdline_parm frame_profile_write_file("-profile_write_file", NULL, AT_NONE); // Cmdline_profile_write_file
cmdline_parm no_unfocused_pause_arg("-no_unfocused_pause", NULL, AT_NONE); //Cmdline_no_unfocus_pause
char *Cmdline_start_mission = NULL;
int Cmdline_old_collision_sys = 0;
@@ -460,17 +491,17 @@ bool Cmdline_profile_write_file = false;
bool Cmdline_no_unfocus_pause = false;
// Other
cmdline_parm get_flags_arg("-get_flags", NULL);
cmdline_parm output_sexp_arg("-output_sexps", NULL); //WMC - outputs all SEXPs to sexps.html
cmdline_parm output_scripting_arg("-output_scripting", NULL); //WMC
cmdline_parm get_flags_arg("-get_flags", "Output the launcher flags file", AT_NONE);
cmdline_parm output_sexp_arg("-output_sexps", NULL, AT_NONE); //WMC - outputs all SEXPs to sexps.html
cmdline_parm output_scripting_arg("-output_scripting", NULL, AT_NONE); //WMC
// Deprecated flags - CommanderDJ
cmdline_parm deprecated_spec_arg("-spec", NULL);
cmdline_parm deprecated_glow_arg("-glow", NULL);
cmdline_parm deprecated_normal_arg("-normal", NULL);
cmdline_parm deprecated_env_arg("-env", NULL);
cmdline_parm deprecated_tbp_arg("-tbp", NULL);
cmdline_parm deprecated_jpgtga_arg("-jpgtga", NULL);
cmdline_parm deprecated_spec_arg("-spec", "Deprecated", AT_NONE);
cmdline_parm deprecated_glow_arg("-glow", "Deprecated", AT_NONE);
cmdline_parm deprecated_normal_arg("-normal", "Deprecated", AT_NONE);
cmdline_parm deprecated_env_arg("-env", "Deprecated", AT_NONE);
cmdline_parm deprecated_tbp_arg("-tbp", "Deprecated", AT_NONE);
cmdline_parm deprecated_jpgtga_arg("-jpgtga", "Deprecated", AT_NONE);
int Cmdline_deprecated_spec = 0;
int Cmdline_deprecated_glow = 0;
@@ -740,11 +771,19 @@ void os_validate_parms(char *cmdline)
// not the prettiest thing but the job gets done
static const int STR_SIZE = 25; // max len of exe_params.name + 5 spaces
int p=0, sp=0;
while (exe_params[p].name[0] == '-') {
sp = strlen(exe_params[p].name);
printf(" [ %s ]%*s- %s\n", exe_params[p].name, (STR_SIZE - sp - 1), NOX(" "), exe_params[p].desc);
p++;
const int AT_SIZE = 8; // max len of cmdline_arg_types[] + 2 spaces
int sp=0, atp=0;
for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
// don't output deprecated flags
if (stricmp("deprecated", parmp->help)) {
sp = strlen(parmp->name);
if (parmp->arg_type != AT_NONE) {
atp = strlen(cmdline_arg_types[parmp->arg_type]);
printf(" [ %s ]%*s[ %s ]%*s- %s\n", parmp->name, (STR_SIZE - sp -1), NOX(" "), cmdline_arg_types[parmp->arg_type], AT_SIZE-atp, NOX(" "), parmp->help);
} else {
printf(" [ %s ]%*s- %s\n", parmp->name, (STR_SIZE - sp -1 +AT_SIZE+4), NOX(" "), parmp->help);
}
}
}
printf("\n");
@@ -767,113 +806,119 @@ void os_validate_parms(char *cmdline)
void os_init_cmdline(char *cmdline)
{
FILE *fp;
bool parse_config = true;
if (strstr(cmdline, PARSE_COMMAND_LINE_STRING) != NULL) {
parse_config = false;
}
if (strstr(cmdline, PARSE_COMMAND_LINE_STRING) == NULL) {
// read the cmdline.cfg file from the data folder, and pass the command line arguments to
// the the parse_parms and validate_parms line. Read these first so anything actually on
// the command line will take precedence
// read the cmdline_fso.cfg file from the data folder, and pass the command line arguments to
// the the parse_parms and validate_parms line. Read these first so anything actually on
// the command line will take precedence
#ifdef _WIN32
fp = fopen("data\\cmdline_fso.cfg", "rt");
fp = fopen("data\\cmdline_fso.cfg", "rt");
#elif defined(APPLE_APP)
char resolved_path[MAX_PATH], data_path[MAX_PATH_LEN];
char resolved_path[MAX_PATH], data_path[MAX_PATH_LEN];
GetCurrentDirectory(MAX_PATH_LEN-1, data_path);
snprintf(resolved_path, MAX_PATH, "%s/data/cmdline_fso.cfg", data_path);
GetCurrentDirectory(MAX_PATH_LEN-1, data_path);
snprintf(resolved_path, MAX_PATH, "%s/data/cmdline_fso.cfg", data_path);
fp = fopen(resolved_path, "rt");
fp = fopen(resolved_path, "rt");
#else
fp = fopen("data/cmdline_fso.cfg", "rt");
fp = fopen("data/cmdline_fso.cfg", "rt");
#endif
// if the file exists, get a single line, and deal with it
if ( fp && parse_config ) {
char *buf, *p;
// if the file exists, get a single line, and deal with it
if ( fp ) {
char *buf, *p;
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
fgets(buf, len-1, fp);
fgets(buf, len-1, fp);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
}
#ifdef SCP_UNIX
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
#endif
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
#ifdef SCP_UNIX
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
#endif
// parse user specific cmdline_fso config file (will supersede options in global file)
char cmdname[MAX_PATH];
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
#ifdef SCP_UNIX
// parse user specific cmdline config file (will supersede options in global file)
char cmdname[MAX_PATH];
snprintf(cmdname, MAX_PATH, "%s/%s/data/cmdline_fso.cfg", detect_home(), Osreg_user_dir);
fp = fopen(cmdname, "rt");
if ( !fp ) {
// try for non "_fso", for older code versions
snprintf(cmdname, MAX_PATH, "%s/%s/data/cmdline.cfg", detect_home(), Osreg_user_dir);
snprintf(cmdname, MAX_PATH, "%s/%s/data/cmdline_fso.cfg", detect_home(), Osreg_user_dir);
fp = fopen(cmdname, "rt");
}
// if the file exists, get a single line, and deal with it
if ( fp ) {
char *buf, *p;
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
fgets(buf, len-1, fp);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
if ( !fp ) {
// try for non "_fso", for older code versions
snprintf(cmdname, MAX_PATH, "%s/%s/data/cmdline.cfg", detect_home(), Osreg_user_dir);
fp = fopen(cmdname, "rt");
}
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
// if the file exists, get a single line, and deal with it
if ( fp ) {
char *buf, *p;
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
fgets(buf, len-1, fp);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
*p = '\0';
}
// append a space for the os_parse_parms() check
strcat_s(buf, len, " ");
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
#endif
} // If cmdline included PARSE_COMMAND_LINE_STRING
// By parsing cmdline last, anything actually on the command line will take precedence.
os_parse_parms(cmdline);
os_validate_parms(cmdline);
}
// arg constructor
// name_ - name of the parameter, must start with '-' character
// help_ - help text for this parameter
cmdline_parm::cmdline_parm(char *name_, char *help_, bool stacks_)
/*
* arg constructor
*
* @param name_ name of the parameter, must start with '-' character
* @param help_ help text for this parameter
* @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_):
name(name_), help(help_), stacks(stacks_), arg_type(arg_type_)
{
name = name_;
help = help_;
stacks = stacks_;
args = NULL;
name_found = 0;
if (Parm_list_inited == 0) {
list_init(&Parm_list);
Assertion(&Parm_list == this, "Coding error! 1st initialised cmdline_parm must be static Parm_list\n");
list_init(this);
Parm_list_inited = 1;
}
if (name != NULL) {
} else {
Assertion(name, "Coding error! cmdline_parm's must have a non-NULL name\n");
Assertion(name[0] == '-', "Coding error! cmdline_parm's must start with a '-'\n");
// not in the static Parm_list init, so lookup the NULL help args
if (help == NULL) {
help = get_param_desc(name);
}
list_append(&Parm_list, this);
}
}
@@ -915,6 +960,7 @@ int cmdline_parm::found()
// returns - the interger representation for the parameter argument
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();
int offset = 0;
@@ -939,6 +985,7 @@ int cmdline_parm::get_int()
// returns - the float representation for the parameter argument
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();
int offset = 0;
@@ -963,6 +1010,7 @@ float cmdline_parm::get_float()
// returns - the string value for the parameter argument
char *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;
@@ -1230,12 +1278,6 @@ bool SetCmdlineParams()
if(mod_arg.found() ) {
Cmdline_mod = mod_arg.str();
// be sure that this string fits in our limits
/* This has to be disabled because the max size is going to be mods*MAX_FILENAME_LEN
if ( strlen(Cmdline_mod) > MAX_FILENAME_LEN ) {
Cmdline_mod[MAX_FILENAME_LEN-1] = '\0';
}*/
// strip off blank space it it's there
if ( Cmdline_mod[strlen(Cmdline_mod)-1] == ' ' ) {
Cmdline_mod[strlen(Cmdline_mod)-1] = '\0';
@@ -1247,7 +1289,49 @@ bool SetCmdlineParams()
memset( modlist, 0, len + 2 );
strcpy_s(modlist, len+2, Cmdline_mod);
//modlist[len]= '\0'; // double null termination at the end
#ifdef SCP_UNIX
// for case sensitive filesystems (e.g. Linux/BSD) perform case-insensitive dir matches
DIR *dp;
dirent *dirp;
char *cur_pos, *temp;
char cur_dir[CF_MAX_PATHNAME_LENGTH], delim[] = ",";
SCP_vector<SCP_string> temp_modlist;
size_t total_len = 0;
if ( !_getcwd(cur_dir, CF_MAX_PATHNAME_LENGTH ) ) {
Error(LOCATION, "Can't get current working directory -- %d", errno );
}
for (cur_pos = strtok(modlist, delim); cur_pos != NULL; cur_pos = strtok(NULL, delim))
{
if ((dp = opendir(cur_dir)) == NULL) {
Error(LOCATION, "Can't open directory '%s' -- %d", cur_dir, errno );
}
while ((dirp = readdir(dp)) != NULL) {
if (!stricmp(dirp->d_name, cur_pos)) {
temp_modlist.push_back(dirp->d_name);
total_len += (strlen(dirp->d_name) + 1);
}
}
(void)closedir(dp);
}
// create new char[] to replace modlist
char *new_modlist = new char[total_len+1];
memset( new_modlist, 0, total_len + 1 );
SCP_vector<SCP_string>::iterator ii, end = temp_modlist.end();
for (ii = temp_modlist.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
}
// make the rest of the function unaware that anything happened here
temp = modlist;
modlist = new_modlist;
delete [] temp;
len = total_len;
#endif
// null terminate each individual
for (int i = 0; i < len; i++)
@@ -1312,6 +1396,10 @@ bool SetCmdlineParams()
if ( allow_autpilot_interrupt.found() ) {
Cmdline_autopilot_interruptable = 0;
}
if ( stretch_menu.found() ) {
Cmdline_stretch_menu = 1;
}
// specular comand lines
if ( spec_exp_arg.found() ) {
specular_exponent_value = spec_exp_arg.get_float();
@@ -1441,6 +1529,11 @@ bool SetCmdlineParams()
Cmdline_keyboard_layout = keyboard_layout.str();
}
if (gl_finish.found())
{
Cmdline_gl_finish = true;
}
if ( snd_preload_arg.found() )
{
Cmdline_snd_preload = 1;
@@ -1523,6 +1616,11 @@ bool SetCmdlineParams()
Cmdline_fb_explosions = 1;
}
if ( brieflighting_arg.found() )
{
Cmdline_brief_lighting = 1;
}
if ( postprocess_arg.found() )
{
Cmdline_postprocess = 1;
@@ -1636,3 +1734,16 @@ int parse_cmdline(char *cmdline)
// I did this because of fred2_parse_cmdline()
return SetCmdlineParams();
}
const char * get_param_desc(const char *flag_name)
{
int i;
int flag_size = sizeof(Flag);
int num_flags = sizeof(exe_params) / flag_size;
for (i = 0; i < num_flags; ++i) {
if (!strcmp(flag_name, exe_params[i].name)) {
return exe_params[i].desc;
}
}
return "UNKNOWN - FIXME!";
}
+2
View File
@@ -96,6 +96,7 @@ extern int Cmdline_ship_choice_3d;
extern int Cmdline_weapon_choice_3d;
extern int Cmdline_warp_flash;
extern int Cmdline_autopilot_interruptable;
extern int Cmdline_stretch_menu;
// Audio related
extern int Cmdline_query_speech;
@@ -129,6 +130,7 @@ extern int Cmdline_no_glsl_model_rendering;
extern int Cmdline_no_di_mouse;
extern int Cmdline_drawelements;
extern char* Cmdline_keyboard_layout;
extern bool Cmdline_gl_finish;
// Developer/Testing related
extern char *Cmdline_start_mission;
+35 -35
View File
@@ -29,6 +29,7 @@
#include "network/multi_pmsg.h"
#include "network/multiutil.h"
#include "parse/scripting.h"
#include "debugconsole/console.h"
#ifndef NDEBUG
@@ -178,6 +179,8 @@ static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of te
static UI_WINDOW Ui_window;
static unsigned int Defaults_cycle_pos; // the controls preset that was last selected
int Control_config_overlay_id;
static struct {
int key; // index of other control in conflict with this one
int joy; // index of other control in conflict with this one
@@ -348,7 +351,7 @@ int Config_allowed[] = {
#ifndef NDEBUG
int Show_controls_info = 0;
DCF_BOOL(show_controls_info, Show_controls_info)
DCF_BOOL(show_controls_info, Show_controls_info);
#endif
static int Axes_origin[JOY_NUM_AXES];
@@ -1293,8 +1296,8 @@ void control_config_init()
Ui_window.tooltip_handler = control_config_tooltip_handler;
// load in help overlay bitmap
help_overlay_load(CONTROL_CONFIG_OVERLAY);
help_overlay_set_state(CONTROL_CONFIG_OVERLAY,0);
Control_config_overlay_id = help_overlay_get_index(CONTROL_CONFIG_OVERLAY);
help_overlay_set_state(Control_config_overlay_id,gr_screen.res,0);
// reset conflict flashing
Conflict_stamp = -1;
@@ -1384,9 +1387,6 @@ void control_config_close()
while (Config_item_undo){
free_undo_block();
}
// unload the overlay bitmap
help_overlay_unload(CONTROL_CONFIG_OVERLAY);
if (Background_bitmap){
bm_release(Background_bitmap);
@@ -1498,7 +1498,7 @@ void control_config_do_frame(float frametime)
}
} else {
if (help_overlay_active(CONTROL_CONFIG_OVERLAY)) {
if (help_overlay_active(Control_config_overlay_id)) {
CC_Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
Ui_window.set_ignore_gadgets(1);
}
@@ -1508,14 +1508,14 @@ void control_config_do_frame(float frametime)
Ui_window.process(0);
if ( (k > 0) || B1_JUST_RELEASED ) {
if (help_overlay_active(CONTROL_CONFIG_OVERLAY)) {
help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
if (help_overlay_active(Control_config_overlay_id)) {
help_overlay_set_state(Control_config_overlay_id, gr_screen.res, 0);
Ui_window.set_ignore_gadgets(0);
k = 0;
}
}
if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
if ( !help_overlay_active(Control_config_overlay_id) ) {
Ui_window.set_ignore_gadgets(0);
}
@@ -1542,7 +1542,7 @@ void control_config_do_frame(float frametime)
}
if ((k > 0) && !Config_allowed[k & KEY_MASK]) {
popup(0, 1, POPUP_OK, XSTR( "That is a non-bindable key. Please try again.", 207));
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "That is a non-bindable key. Please try again.", 207));
k = 0;
}
@@ -1609,7 +1609,7 @@ void control_config_do_frame(float frametime)
}
} else if (Search_mode) {
if (help_overlay_active(CONTROL_CONFIG_OVERLAY)) {
if (help_overlay_active(Control_config_overlay_id)) {
CC_Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
Ui_window.set_ignore_gadgets(1);
}
@@ -1619,14 +1619,14 @@ void control_config_do_frame(float frametime)
Ui_window.process(0);
if ( (k > 0) || B1_JUST_RELEASED ) {
if ( help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
if ( help_overlay_active(Control_config_overlay_id) ) {
help_overlay_set_state(Control_config_overlay_id, gr_screen.res, 0);
Ui_window.set_ignore_gadgets(0);
k = 0;
}
}
if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
if ( !help_overlay_active(Control_config_overlay_id) ) {
Ui_window.set_ignore_gadgets(0);
}
@@ -1720,7 +1720,7 @@ void control_config_do_frame(float frametime)
CC_Buttons[gr_screen.res][UNDO_BUTTON].button.enable(Config_item_undo != NULL);
if ( help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
if ( help_overlay_active(Control_config_overlay_id) ) {
CC_Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
Ui_window.set_ignore_gadgets(1);
}
@@ -1728,14 +1728,14 @@ void control_config_do_frame(float frametime)
k = Ui_window.process();
if ( (k > 0) || B1_JUST_RELEASED ) {
if ( help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
if ( help_overlay_active(Control_config_overlay_id) ) {
help_overlay_set_state(Control_config_overlay_id, gr_screen.res, 0);
Ui_window.set_ignore_gadgets(0);
k = 0;
}
}
if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
if ( !help_overlay_active(Control_config_overlay_id) ) {
Ui_window.set_ignore_gadgets(0);
}
@@ -1841,7 +1841,7 @@ void control_config_do_frame(float frametime)
GR_MAYBE_CLEAR_RES(Background_bitmap);
if (Background_bitmap >= 0) {
gr_set_bitmap(Background_bitmap);
gr_bitmap(0, 0);
gr_bitmap(0, 0, GR_RESIZE_MENU);
}
// highlight tab with conflict
@@ -1875,7 +1875,7 @@ void control_config_do_frame(float frametime)
int sw, sh;
gr_get_string_size(&sw, &sh, conflict_str);
gr_string((gr_screen.max_w / 2) - (sw / 2), Conflict_warning_coords[gr_screen.res][1], conflict_str);
gr_string((gr_screen.max_w / 2) - (sw / 2), Conflict_warning_coords[gr_screen.res][1], conflict_str, GR_RESIZE_MENU);
gr_set_font(FONT1);
} else {
@@ -1931,7 +1931,7 @@ void control_config_do_frame(float frametime)
if (t % 2) {
gr_set_color_fast(&Color_text_normal);
gr_get_string_size(&w, NULL, XSTR( "?", 208));
gr_printf(x - w / 2, y - font_height / 2, XSTR( "?", 208));
gr_printf_menu(x - w / 2, y - font_height / 2, XSTR( "?", 208));
}
} else if (!(z & JOY_AXIS) && ((Conflicts[z].key >= 0) || (Conflicts[z].joy >= 0))) {
@@ -1943,7 +1943,7 @@ void control_config_do_frame(float frametime)
gr_set_color_fast(&Color_text_normal);
str = XSTR( "Control conflicts with:", 209);
gr_get_string_size(&w, NULL, str);
gr_printf(x - w / 2, y - font_height, str);
gr_printf_menu(x - w / 2, y - font_height, str);
if (Control_config[i].hasXSTR) {
strcpy_s(buf, XSTR(Control_config[i].text, CONTROL_CONFIG_XSTR + i));
@@ -1953,12 +1953,12 @@ void control_config_do_frame(float frametime)
gr_force_fit_string(buf, 255, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
gr_get_string_size(&w, NULL, buf);
gr_printf(x - w / 2, y, buf);
gr_printf_menu(x - w / 2, y, buf);
} else if (*bound_string) {
gr_set_color_fast(&Color_text_normal);
gr_get_string_size(&w, NULL, bound_string);
gr_printf(x - w / 2, y - font_height / 2, bound_string);
gr_printf_menu(x - w / 2, y - font_height / 2, bound_string);
if (timestamp_elapsed(bound_timestamp)) {
*bound_string = 0;
}
@@ -1966,7 +1966,7 @@ void control_config_do_frame(float frametime)
if (Cc_lines[Num_cc_lines - 1].y + font_height > Cc_lines[Scroll_offset].y + Control_list_coords[gr_screen.res][CONTROL_H_COORD]) {
gr_set_color_fast(&Color_white);
gr_printf(Control_more_coords[gr_screen.res][CONTROL_X_COORD], Control_more_coords[gr_screen.res][CONTROL_Y_COORD], XSTR( "More...", 210));
gr_printf_menu(Control_more_coords[gr_screen.res][CONTROL_X_COORD], Control_more_coords[gr_screen.res][CONTROL_Y_COORD], XSTR( "More...", 210));
}
conflict = 0;
@@ -1992,7 +1992,7 @@ void control_config_do_frame(float frametime)
if (Cc_lines[line].label) {
strcpy_s(buf, Cc_lines[line].label);
gr_force_fit_string(buf, 255, Control_list_ctrl_w[gr_screen.res]);
gr_printf(Control_list_coords[gr_screen.res][CONTROL_X_COORD], y, buf);
gr_printf_menu(Control_list_coords[gr_screen.res][CONTROL_X_COORD], y, buf);
}
if (!(z & JOY_AXIS)) {
@@ -2004,7 +2004,7 @@ void control_config_do_frame(float frametime)
if ((k < 0) && (j < 0)) {
gr_set_color_fast(&Color_grey);
gr_printf(x, y, XSTR( "None", 211));
gr_printf_menu(x, y, XSTR( "None", 211));
} else {
if (k >= 0) {
@@ -2024,7 +2024,7 @@ void control_config_do_frame(float frametime)
gr_set_color_fast(c);
}
gr_printf(x, y, buf);
gr_printf_menu(x, y, buf);
len = strlen(buf);
Cc_lines[line].kx = x - Control_list_coords[gr_screen.res][CONTROL_X_COORD];
@@ -2034,7 +2034,7 @@ void control_config_do_frame(float frametime)
if (j >= 0) {
gr_set_color_fast(&Color_text_normal);
gr_printf(x, y, XSTR( ", ", 212));
gr_printf_menu(x, y, XSTR( ", ", 212));
gr_get_string_size(&w, NULL, XSTR( ", ", 212));
x += w;
}
@@ -2058,7 +2058,7 @@ void control_config_do_frame(float frametime)
}
gr_force_fit_string(buf, 255, Control_list_key_w[gr_screen.res] + Control_list_key_x[gr_screen.res] - x);
gr_printf(x, y, buf);
gr_printf_menu(x, y, buf);
Cc_lines[line].jx = x - Control_list_coords[gr_screen.res][CONTROL_X_COORD];
gr_get_string_size(&Cc_lines[line].jw, NULL, buf);
@@ -2074,7 +2074,7 @@ void control_config_do_frame(float frametime)
if (j < 0) {
gr_set_color_fast(&Color_grey);
gr_printf(x, y, XSTR( "None", 211));
gr_printf_menu(x, y, XSTR( "None", 211));
} else {
if (Conflicts_axes[z & ~JOY_AXIS] >= 0) {
@@ -2093,7 +2093,7 @@ void control_config_do_frame(float frametime)
gr_set_color_fast(c);
}
gr_string(x, y, Joy_axis_text[j]);
gr_string(x, y, Joy_axis_text[j], GR_RESIZE_MENU);
}
}
@@ -2108,7 +2108,7 @@ void control_config_do_frame(float frametime)
}
// blit help overlay if active
help_overlay_maybe_blit(CONTROL_CONFIG_OVERLAY);
help_overlay_maybe_blit(Control_config_overlay_id, gr_screen.res);
gr_flip();
}
@@ -2165,7 +2165,7 @@ void control_check_indicate()
#ifndef NDEBUG
if (Show_controls_info) {
gr_set_color_fast(&HUD_color_debug);
gr_printf(490, 15, NOX("Ctrls checked: %d"), Control_check_count);
gr_printf_no_resize(gr_screen.max_w - 154, 5, NOX("Ctrls checked: %d"), Control_check_count);
}
#endif
+2
View File
@@ -288,6 +288,8 @@ extern int Axis_map_to[];
extern int Invert_axis[];
extern int Invert_axis_defaults[];
extern int Control_config_overlay_id;
extern config_item Control_config[]; //!< Stores the keyboard configuration
extern SCP_vector<config_item*> Control_config_presets; // tabled control presets; pointers to config_item arrays
extern char **Scan_code_text;
+474 -384
View File
@@ -19,10 +19,14 @@
#include "globalincs/systemvars.h"
#include "globalincs/def_files.h"
#define TARGET_TAB 0
#define SHIP_TAB 1
#define WEAPON_TAB 2
#define COMPUTER_TAB 3
// z64: These enumerations MUST equal to those in controlsconfig.cpp...
// z64: Really need a better way than this.
enum CC_tab {
TARGET_TAB =0,
SHIP_TAB =1,
WEAPON_TAB =2,
COMPUTER_TAB =3
};
int Failed_key_index;
@@ -36,169 +40,169 @@ int Axis_enabled_defaults[JOY_NUM_AXES] = { 1, 1, 1, 0, 0, 0 };
int Invert_axis[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
int Invert_axis_defaults[JOY_NUM_AXES] = { 0, 0, 0, 0, 0, 0 };
// arrays which hold the key mappings. The array index represents a key-independent action.
//
//! arrays which hold the key mappings. The array index represents a key-independent action.
//! please use SPACES for aligning the fields of this array
//XSTR:OFF
config_item Control_config[CCFG_MAX + 1] = {
// targeting a ship
{ KEY_T, -1, TARGET_TAB, true, "Target Next Ship" },
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, true, "Target Previous Ship" },
{ KEY_H, 2, TARGET_TAB, true, "Target Next Closest Hostile Ship" },
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, true, "Target Previous Closest Hostile Ship" },
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, true, "Toggle Auto Targeting" },
{ KEY_F, -1, TARGET_TAB, true, "Target Next Closest Friendly Ship" },
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, true, "Target Previous Closest Friendly Ship" },
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle" },
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker" },
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission" },
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting" },
{ KEY_T, -1, TARGET_TAB, true, "Target Next Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_T, -1, TARGET_TAB, true, "Target Previous Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_H, 2, TARGET_TAB, true, "Target Next Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_H, -1, TARGET_TAB, true, "Target Previous Closest Hostile Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_H, -1, TARGET_TAB, true, "Toggle Auto Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_F, -1, TARGET_TAB, true, "Target Next Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_F, -1, TARGET_TAB, true, "Target Previous Closest Friendly Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_Y, 4, TARGET_TAB, true, "Target Ship in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_G, -1, TARGET_TAB, true, "Target Target's Nearest Attacker", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_Y, -1, TARGET_TAB, true, "Target Last Ship to Send Transmission", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_T, -1, TARGET_TAB, true, "Turn Off Targeting", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// targeting a ship's subsystem
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle" },
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem" },
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem" },
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems" },
{ KEY_V, -1, TARGET_TAB, true, "Target Subsystem in Reticle", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_S, -1, TARGET_TAB, true, "Target Next Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_S, -1, TARGET_TAB, true, "Target Previous Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_S, -1, TARGET_TAB, true, "Turn Off Targeting of Subsystems", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// matching speed
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed" },
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, true, "Toggle Auto Speed Matching" },
{ KEY_M, -1, COMPUTER_TAB, true, "Match Target Speed", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_M, -1, COMPUTER_TAB, true, "Toggle Auto Speed Matching", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// weapons
{ KEY_LCTRL, 0, WEAPON_TAB, true, "Fire Primary Weapon", CC_TYPE_CONTINUOUS },
{ KEY_SPACEBAR, 1, WEAPON_TAB, true, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS },
{ KEY_PERIOD, -1, WEAPON_TAB, true, "Cycle Forward Primary Weapon" },
{ KEY_COMMA, -1, WEAPON_TAB, true, "Cycle Backward Primary Weapon" },
{ KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Bank" },
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Firing Rate" },
{ KEY_X, 3, WEAPON_TAB, true, "Launch Countermeasure" },
{ KEY_LCTRL, 0, WEAPON_TAB, true, "Fire Primary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SPACEBAR, 1, WEAPON_TAB, true, "Fire Secondary Weapon", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PERIOD, -1, WEAPON_TAB, true, "Cycle Forward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_COMMA, -1, WEAPON_TAB, true, "Cycle Backward Primary Weapon", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Bank", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_DIVIDE, -1, WEAPON_TAB, true, "Cycle Secondary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_X, 3, WEAPON_TAB, true, "Launch Countermeasure", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// controls
{ KEY_A, -1, SHIP_TAB, true, "Forward Thrust", CC_TYPE_CONTINUOUS },
{ KEY_Z, -1, SHIP_TAB, true, "Reverse Thrust", CC_TYPE_CONTINUOUS },
{ KEY_PAD7, -1, SHIP_TAB, true, "Bank Left", CC_TYPE_CONTINUOUS },
{ KEY_PAD9, -1, SHIP_TAB, true, "Bank Right", CC_TYPE_CONTINUOUS },
{ KEY_PAD8, -1, SHIP_TAB, true, "Pitch Forward", CC_TYPE_CONTINUOUS },
{ KEY_PAD2, -1, SHIP_TAB, true, "Pitch Backward", CC_TYPE_CONTINUOUS },
{ KEY_PAD4, -1, SHIP_TAB, true, "Turn Left", CC_TYPE_CONTINUOUS },
{ KEY_PAD6, -1, SHIP_TAB, true, "Turn Right", CC_TYPE_CONTINUOUS },
{ KEY_A, -1, SHIP_TAB, true, "Forward Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_Z, -1, SHIP_TAB, true, "Reverse Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD7, -1, SHIP_TAB, true, "Bank Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD9, -1, SHIP_TAB, true, "Bank Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD8, -1, SHIP_TAB, true, "Pitch Forward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD2, -1, SHIP_TAB, true, "Pitch Backward", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD4, -1, SHIP_TAB, true, "Turn Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD6, -1, SHIP_TAB, true, "Turn Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
// throttle controls
{ KEY_BACKSP, -1, SHIP_TAB, true, "Set Throttle to Zero" },
{ KEY_SLASH, -1, SHIP_TAB, true, "Set Throttle to Max" },
{ KEY_LBRACKET, -1, SHIP_TAB, true, "Set Throttle to One-Third" },
{ KEY_RBRACKET, -1, SHIP_TAB, true, "Set Throttle to Two-Thirds" },
{ KEY_EQUAL, -1, SHIP_TAB, true, "Increase Throttle 5 Percent" },
{ KEY_MINUS, -1, SHIP_TAB, true, "Decrease Throttle 5 Percent" },
{ KEY_BACKSP, -1, SHIP_TAB, true, "Set Throttle to Zero", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SLASH, -1, SHIP_TAB, true, "Set Throttle to Max", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LBRACKET, -1, SHIP_TAB, true, "Set Throttle to One-Third", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_RBRACKET, -1, SHIP_TAB, true, "Set Throttle to Two-Thirds", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_EQUAL, -1, SHIP_TAB, true, "Increase Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_MINUS, -1, SHIP_TAB, true, "Decrease Throttle 5 Percent", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// squadmate messaging
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target" },
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target" },
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target" },
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem" },
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target" },
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy" },
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing" },
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target" },
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target" },
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me" },
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base" },
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me" },
{ KEY_SHIFTED | KEY_A, -1, COMPUTER_TAB, true, "Attack My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_Z, -1, COMPUTER_TAB, true, "Disarm My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_D, -1, COMPUTER_TAB, true, "Disable My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_V, -1, COMPUTER_TAB, true, "Attack My Subsystem", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_X, -1, COMPUTER_TAB, true, "Capture My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Engage Enemy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_W, -1, COMPUTER_TAB, true, "Form on My Wing", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_I, -1, COMPUTER_TAB, true, "Ignore My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_P, -1, COMPUTER_TAB, true, "Protect My Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_C, -1, COMPUTER_TAB, true, "Cover Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_J, -1, COMPUTER_TAB, true, "Return to Base", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_R, -1, COMPUTER_TAB, true, "Rearm Me", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship" },
{ KEY_R, 6, TARGET_TAB, true, "Target Closest Attacking Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// Views
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View" },
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View"},
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock"},
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS }, // Not in use anymore (Swifty)
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View" },
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS },
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS },
{ KEY_PAD5, -1, COMPUTER_TAB, true, "Center View", CC_TYPE_CONTINUOUS },
{ -1, 33, COMPUTER_TAB, true, "View Up", CC_TYPE_CONTINUOUS },
{ -1, 32, COMPUTER_TAB, true, "View Rear", CC_TYPE_CONTINUOUS },
{ -1, 34, COMPUTER_TAB, true, "View Left", CC_TYPE_CONTINUOUS },
{ -1, 35, COMPUTER_TAB, true, "View Right", CC_TYPE_CONTINUOUS },
{ KEY_PADMULTIPLY, -1, COMPUTER_TAB, true, "Chase View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADPERIOD, -1, COMPUTER_TAB, true, "External View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADENTER, -1, COMPUTER_TAB, true, "Toggle External Camera Lock", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAD0, -1, COMPUTER_TAB, true, "Free Look View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false }, // Not in use anymore (Swifty)
{ KEY_PADDIVIDE, -1, COMPUTER_TAB, true, "Current Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PADPLUS, -1, COMPUTER_TAB, true, "Increase View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PADMINUS, -1, COMPUTER_TAB, true, "Decrease View Distance", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_PAD5, -1, COMPUTER_TAB, true, "Center View", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 33, COMPUTER_TAB, true, "View Up", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 32, COMPUTER_TAB, true, "View Rear", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 34, COMPUTER_TAB, true, "View Left", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, 35, COMPUTER_TAB, true, "View Right", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, true, "Cycle Radar Range" },
{ KEY_C, -1, COMPUTER_TAB, true, "Communications Menu" },
{ -1, -1, -1, true, "Show Objectives" },
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, true, "Enter Subspace (End Mission)" },
{ KEY_J, -1, TARGET_TAB, true, "Target Target's Target" },
{ KEY_TAB, 5, SHIP_TAB, true, "Afterburner", CC_TYPE_CONTINUOUS },
{ KEY_RAPOSTRO, -1, COMPUTER_TAB, true, "Cycle Radar Range", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_C, -1, COMPUTER_TAB, true, "Communications Menu", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, -1, true, "Show Objectives", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_J, -1, COMPUTER_TAB, true, "Enter Subspace (End Mission)", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_J, -1, TARGET_TAB, true, "Target Target's Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_TAB, 5, SHIP_TAB, true, "Afterburner", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_INSERT, -1, COMPUTER_TAB, true, "Increase Weapon Energy" },
{ KEY_DELETE, -1, COMPUTER_TAB, true, "Decrease Weapon Energy" },
{ KEY_HOME, -1, COMPUTER_TAB, true, "Increase Shield Energy" },
{ KEY_END, -1, COMPUTER_TAB, true, "Decrease Shield Energy" },
{ KEY_PAGEUP, -1, COMPUTER_TAB, true, "Increase Engine Energy" },
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy" },
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings" },
{ KEY_INSERT, -1, COMPUTER_TAB, true, "Increase Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DELETE, -1, COMPUTER_TAB, true, "Decrease Weapon Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_HOME, -1, COMPUTER_TAB, true, "Increase Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_END, -1, COMPUTER_TAB, true, "Decrease Shield Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAGEUP, -1, COMPUTER_TAB, true, "Increase Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_PAGEDOWN, -1, COMPUTER_TAB, true, "Decrease Engine Energy", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_D, -1, COMPUTER_TAB, true, "Equalize Energy Settings", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields" },
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield" },
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield" },
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield" },
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield" },
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield" },
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser" },
// { -1, -1, -1, true, "Show Damage Popup Window" },
{ KEY_Q, 7, COMPUTER_TAB, true, "Equalize Shields", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_UP, -1, COMPUTER_TAB, true, "Augment Forward Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_DOWN, -1, COMPUTER_TAB, true, "Augment Rear Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_LEFT, -1, COMPUTER_TAB, true, "Augment Left Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_RIGHT, -1, COMPUTER_TAB, true, "Augment Right Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Laser->Shield", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_SCROLLOCK, -1, COMPUTER_TAB, true, "Transfer Energy Shield->Laser", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// { -1, -1, -1, true, "Show Damage Popup Window" },
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS },
{ -1, -1, SHIP_TAB, false, "Glide When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
//Backslash -- this was a convenient place for Glide When Pressed, as Show Damage Popup isn't used
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS },
{ -1, -1, -1, true, "Show Nav Map" },
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort" },
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List" },
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship" },
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, true, "Target Closest Repair Ship" },
{ -1, -1, SHIP_TAB, true, "Bank When Pressed", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ -1, -1, -1, true, "Show Nav Map", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_E, -1, COMPUTER_TAB, true, "Add or Remove Escort", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_E, -1, COMPUTER_TAB, true, "Clear Escort List", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_E, -1, TARGET_TAB, true, "Target Next Escort Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_R, -1, TARGET_TAB, true, "Target Closest Repair Ship", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo" },
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo" },
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area" },
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret" },
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret" },
{ KEY_U, -1, TARGET_TAB, true, "Target Next Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_U, -1, TARGET_TAB, true, "Target Previous Uninspected Cargo", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_N, -1, TARGET_TAB, true, "Target Newest Ship in Area", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_K, -1, TARGET_TAB, true, "Target Next Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_K, -1, TARGET_TAB, true, "Target Previous Live Turret", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_B, -1, TARGET_TAB, true, "Target Next Hostile Bomb or Bomber" },
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber" },
{ KEY_B, -1, TARGET_TAB, true, "Target Next Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// multiplayer messaging keys
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All" },
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly" },
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile" },
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target" },
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target"},
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression" },
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression" },
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast" },
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info"},
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct"},
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_X, -1, COMPUTER_TAB, true, "(Multiplayer) Observer Zoom to Target", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PERIOD, -1, COMPUTER_TAB, true, "Increase Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_COMMA, -1, COMPUTER_TAB, true, "Decrease Time Compression", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_L, -1, COMPUTER_TAB, true, "Toggle High HUD Contrast", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_N, -1, COMPUTER_TAB, true, "(Multiplayer) Toggle Network Info", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_END, -1, COMPUTER_TAB, true, "(Multiplayer) Self Destruct", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
// Misc
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD"},
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, true, "Right Thrust", CC_TYPE_CONTINUOUS},
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS},
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS},
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS},
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View"},
{ -1, -1, COMPUTER_TAB, false, "Top-Down View"},
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View"}, // (Swifty) Toggle for VM_TRACK
{ KEY_SHIFTED | KEY_O, -1, COMPUTER_TAB, true, "Toggle HUD", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_3, -1, SHIP_TAB, true, "Right Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_1, -1, SHIP_TAB, true, "Left Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PADPLUS, -1, SHIP_TAB, true, "Up Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_SHIFTED | KEY_PADENTER, -1, SHIP_TAB, true, "Down Thrust", CC_TYPE_CONTINUOUS, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_SHIFTED | KEY_Q, -1, COMPUTER_TAB, true, "Toggle HUD Wireframe Target View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, COMPUTER_TAB, false, "Top-Down View", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, COMPUTER_TAB, false, "Target Padlock View", CC_TYPE_TRIGGER, -1, -1, 0, false, false }, // (Swifty) Toggle for VM_TRACK
// Auto Navigation Systen
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot"},
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points"},
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding"},
{ KEY_O, -1, WEAPON_TAB, false, "Cycle Primary Weapon Firing Rate" },
{ -1, -1, -1, false, "" }
{ KEY_ALTED | KEY_A, -1, COMPUTER_TAB, false, "Toggle Auto Pilot", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_N, -1, COMPUTER_TAB, false, "Cycle Nav Points", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_ALTED | KEY_G, -1, SHIP_TAB, false, "Toggle Gliding", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ KEY_O, -1, WEAPON_TAB, false, "Cycle Primary Weapon Firing Rate", CC_TYPE_TRIGGER, -1, -1, 0, false, false },
{ -1, -1, -1, false, "", CC_TYPE_TRIGGER, -1, -1, 0, false, false }
};
char *Scan_code_text_german[] = {
"", "Esc", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "0", "Akzent '", "\xE1", "R\x81""cktaste", "Tab",
"7", "8", "9", "0", "Akzent '", "Eszett", "R\x81""cktaste", "Tab",
"Q", "W", "E", "R", "T", "Z", "U", "I",
"O", "P", "\x9A", "+", "Eingabe", "Strg Links", "A", "S",
"D", "F", "G", "H", "J", "K", "L", "\x99",
"\xAE", "`", "Shift", "#", "Y", "X", "C", "V",
"\x8E", "`", "Shift", "#", "Y", "X", "C", "V",
"B", "N", "M", ",", ".", "-", "Shift", "Num *",
"Alt", "Leertaste", "Hochstell", "F1", "F2", "F3", "F4", "F5",
@@ -290,10 +294,61 @@ char *Joy_button_text_french[] = {
"Bouton 13", "Bouton 14", "Bouton 15", "Bouton 16", "Bouton 17", "Bouton 18",
"Bouton 19", "Bouton 20", "Bouton 21", "Bouton 22", "Bouton 23", "Bouton 24",
"Bouton 25", "Bouton 26", "Bouton 27", "Bouton 28", "Bouton 29", "Bouton 30",
"Bouton 31", "Bouton 32", "Chapeau Arriere", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
"Bouton 31", "Bouton 32", "Chapeau Arri\x8Are", "Chapeau Avant", "Chapeau Gauche", "Chapeau Droite"
};
// This is the text that is displayed on the screen for the keys a player selects
char *Scan_code_text_polish[] = {
"", "Esc", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "0", "-", "=", "Backspace", "Tab",
"Q", "W", "E", "R", "T", "Y", "U", "I",
"O", "P", "[", "]", "Enter", "Lewy Ctrl", "A", "S",
"D", "F", "G", "H", "J", "K", "L", ";",
"'", "`", "LShift", "\\", "Z", "X", "C", "V",
"B", "N", "M", ",", ".", "/", "PShift", "Num *",
"Alt", "Spacja", "CapsLock", "F1", "F2", "F3", "F4", "F5",
"F6", "F7", "F8", "F9", "F10", "Pause", "Scrlock", "Num 7",
"Num 8", "Num 9", "Num -", "Num 4", "Num 5", "Num 6", "Num +", "Num 1",
"Num 2", "Num 3", "Num 0", "Num .", "", "", "", "F11",
"F12", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "Num Enter", "Prawy Ctrl", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "Num /", "", "PrntScr",
"Alt", "", "", "", "", "", "", "",
"", "", "", "", "", "Num Lock", "", "Home",
"Kursor G\xF3ra", "Page Up", "", "Kursor Lewo", "", "Kursor Prawo", "", "End",
"Kursor D\xF3\xB3", "Page Down", "Insert", "Delete", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
};
char *Joy_button_text_polish[] = {
"Przyc.1", "Przyc.2", "Przyc.3", "Przyc.4", "Przyc.5", "Przyc.6",
"Przyc.7", "Przyc.8", "Przyc.9", "Przyc.10", "Przyc.11", "Przyc.12",
"Przyc.13", "Przyc.14", "Przyc.15", "Przyc.16", "Przyc.17", "Przyc.18",
"Przyc.19", "Przyc.20", "Przyc.21", "Przyc.22", "Przyc.23", "Przyc.24",
"Przyc.25", "Przyc.26", "Przyc.27", "Przyc.28", "Przyc.29", "Przyc.30",
"Przyc.31", "Przyc.32", "Hat Ty\xB3", "Hat Prz\xF3\x64", "Hat Lewo", "Hat Prawo"
};
//! This is the text that is displayed on the screen for the keys a player selects
char *Scan_code_text_english[] = {
"", "Esc", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "0", "-", "=", "Backspace", "Tab",
@@ -382,13 +437,7 @@ int translate_key_to_index(const char *key, bool find_override)
{
int i, index = -1, alt = 0, shift = 0, max_scan_codes;
if (Lcl_gr) {
max_scan_codes = sizeof(Scan_code_text_german) / sizeof(char *);
} else if (Lcl_fr) {
max_scan_codes = sizeof(Scan_code_text_french) / sizeof(char *);
} else {
max_scan_codes = sizeof(Scan_code_text_english) / sizeof(char *);
}
max_scan_codes = sizeof(Scan_code_text_english) / sizeof(char *);
// look for modifiers
Assert(key);
@@ -399,17 +448,7 @@ int translate_key_to_index(const char *key, bool find_override)
key++;
}
char *translated_shift;
if(Lcl_gr){
translated_shift = "Shift";
} else if(Lcl_fr){
translated_shift = "Maj.";
} else {
translated_shift = "Shift";
}
if (!strnicmp(key, translated_shift, 5)) {
if (!strnicmp(key, "Shift", 5)) {
shift = 1;
key += 5;
if (*key)
@@ -435,14 +474,14 @@ int translate_key_to_index(const char *key, bool find_override)
// convert scancode to Control_config index
if (find_override) {
for (i=0; i<CCFG_MAX; i++) {
if (Control_config[i].key_id == index) {
if (!Control_config[i].disabled && Control_config[i].key_id == index) {
index = i;
break;
}
}
} else {
for (i=0; i<CCFG_MAX; i++) {
if (Control_config[i].key_default == index) {
if (!Control_config[i].disabled && Control_config[i].key_default == index) {
index = i;
break;
}
@@ -458,10 +497,11 @@ int translate_key_to_index(const char *key, bool find_override)
return -1;
}
// Given the system default key 'key', return the current key that is bound to the function
// Both are 'key' and the return value are descriptive strings that can be displayed
// directly to the user. If 'key' isn't a real key or not normally bound to anything,
// or there is no key current bound to the function, NULL is returned.
/*! Given the system default key 'key', return the current key that is bound to that function.
* Both are 'key' and the return value are descriptive strings that can be displayed
* directly to the user. If 'key' isn't a real key, is not normally bound to anything,
* or there is no key currently bound to the function, NULL is returned.
*/
char *translate_key(char *key)
{
int index = -1, key_code = -1, joy_code = -1;
@@ -553,19 +593,16 @@ void control_config_common_init()
Control_config[i].continuous_ongoing = false;
}
control_config_common_load_overrides();
control_config_common_load_overrides();
if(Lcl_gr){
Scan_code_text = Scan_code_text_german;
Joy_button_text = Joy_button_text_german;
// swap init bindings for y and z keys
Control_config[TARGET_SHIP_IN_RETICLE].key_default = KEY_Z;
Control_config[TARGET_LAST_TRANMISSION_SENDER].key_default = KEY_ALTED | KEY_Z;
Control_config[REVERSE_THRUST].key_default = KEY_Y;
Control_config[DISARM_MESSAGE].key_default = KEY_SHIFTED | KEY_Y;
} else if(Lcl_fr){
Scan_code_text = Scan_code_text_french;
Joy_button_text = Joy_button_text_french;
} else if(Lcl_pl){
Scan_code_text = Scan_code_text_polish;
Joy_button_text = Joy_button_text_polish;
} else {
Scan_code_text = Scan_code_text_english;
Joy_button_text = Joy_button_text_english;
@@ -576,237 +613,290 @@ void control_config_common_init()
#include <map>
#include <string>
SCP_map<SCP_string, int> mEnumNameToVal;
SCP_map<SCP_string, int> mKeyNameToVal;
SCP_map<SCP_string, CC_type> mCCTypeNameToVal;
SCP_map<SCP_string, char> mCCTabNameToVal;
void LoadEnumsIntoMap();
/*! Helper function to LoadEnumsIntoMaps(), Loads the Keyboard definitions/enumerations into mKeyNameToVal
*/
void LoadEnumsIntoKeyMap(void) {
// Dirty macro hack :D
#define ADD_ENUM_TO_KEY_MAP(Enum) mKeyNameToVal[#Enum] = (Enum);
ADD_ENUM_TO_KEY_MAP(KEY_SHIFTED)
/*
ADD_ENUM_TO_KEY_MAP(KEY_ALTED)
ADD_ENUM_TO_KEY_MAP(KEY_CTRLED)
ADD_ENUM_TO_KEY_MAP(KEY_DEBUGGED)
ADD_ENUM_TO_KEY_MAP(KEY_DEBUGGED1)
ADD_ENUM_TO_KEY_MAP(KEY_MASK)
ADD_ENUM_TO_KEY_MAP(KEY_DEBUG_KEY)
*/
ADD_ENUM_TO_KEY_MAP(KEY_0)
ADD_ENUM_TO_KEY_MAP(KEY_1)
ADD_ENUM_TO_KEY_MAP(KEY_2)
ADD_ENUM_TO_KEY_MAP(KEY_3)
ADD_ENUM_TO_KEY_MAP(KEY_4)
ADD_ENUM_TO_KEY_MAP(KEY_5)
ADD_ENUM_TO_KEY_MAP(KEY_6)
ADD_ENUM_TO_KEY_MAP(KEY_7)
ADD_ENUM_TO_KEY_MAP(KEY_8)
ADD_ENUM_TO_KEY_MAP(KEY_9)
ADD_ENUM_TO_KEY_MAP(KEY_A)
ADD_ENUM_TO_KEY_MAP(KEY_B)
ADD_ENUM_TO_KEY_MAP(KEY_C)
ADD_ENUM_TO_KEY_MAP(KEY_D)
ADD_ENUM_TO_KEY_MAP(KEY_E)
ADD_ENUM_TO_KEY_MAP(KEY_F)
ADD_ENUM_TO_KEY_MAP(KEY_G)
ADD_ENUM_TO_KEY_MAP(KEY_H)
ADD_ENUM_TO_KEY_MAP(KEY_I)
ADD_ENUM_TO_KEY_MAP(KEY_J)
ADD_ENUM_TO_KEY_MAP(KEY_K)
ADD_ENUM_TO_KEY_MAP(KEY_L)
ADD_ENUM_TO_KEY_MAP(KEY_M)
ADD_ENUM_TO_KEY_MAP(KEY_N)
ADD_ENUM_TO_KEY_MAP(KEY_O)
ADD_ENUM_TO_KEY_MAP(KEY_P)
ADD_ENUM_TO_KEY_MAP(KEY_Q)
ADD_ENUM_TO_KEY_MAP(KEY_R)
ADD_ENUM_TO_KEY_MAP(KEY_S)
ADD_ENUM_TO_KEY_MAP(KEY_T)
ADD_ENUM_TO_KEY_MAP(KEY_U)
ADD_ENUM_TO_KEY_MAP(KEY_V)
ADD_ENUM_TO_KEY_MAP(KEY_W)
ADD_ENUM_TO_KEY_MAP(KEY_X)
ADD_ENUM_TO_KEY_MAP(KEY_Y)
ADD_ENUM_TO_KEY_MAP(KEY_Z)
ADD_ENUM_TO_KEY_MAP(KEY_MINUS)
ADD_ENUM_TO_KEY_MAP(KEY_EQUAL)
ADD_ENUM_TO_KEY_MAP(KEY_DIVIDE)
ADD_ENUM_TO_KEY_MAP(KEY_SLASH)
ADD_ENUM_TO_KEY_MAP(KEY_SLASH_UK)
ADD_ENUM_TO_KEY_MAP(KEY_COMMA)
ADD_ENUM_TO_KEY_MAP(KEY_PERIOD)
ADD_ENUM_TO_KEY_MAP(KEY_SEMICOL)
ADD_ENUM_TO_KEY_MAP(KEY_LBRACKET)
ADD_ENUM_TO_KEY_MAP(KEY_RBRACKET)
ADD_ENUM_TO_KEY_MAP(KEY_RAPOSTRO)
ADD_ENUM_TO_KEY_MAP(KEY_LAPOSTRO)
ADD_ENUM_TO_KEY_MAP(KEY_ESC)
ADD_ENUM_TO_KEY_MAP(KEY_ENTER)
ADD_ENUM_TO_KEY_MAP(KEY_BACKSP)
ADD_ENUM_TO_KEY_MAP(KEY_TAB)
ADD_ENUM_TO_KEY_MAP(KEY_SPACEBAR)
ADD_ENUM_TO_KEY_MAP(KEY_NUMLOCK)
ADD_ENUM_TO_KEY_MAP(KEY_SCROLLOCK)
ADD_ENUM_TO_KEY_MAP(KEY_CAPSLOCK)
ADD_ENUM_TO_KEY_MAP(KEY_LSHIFT)
ADD_ENUM_TO_KEY_MAP(KEY_RSHIFT)
ADD_ENUM_TO_KEY_MAP(KEY_LALT)
ADD_ENUM_TO_KEY_MAP(KEY_RALT)
ADD_ENUM_TO_KEY_MAP(KEY_LCTRL)
ADD_ENUM_TO_KEY_MAP(KEY_RCTRL)
ADD_ENUM_TO_KEY_MAP(KEY_F1)
ADD_ENUM_TO_KEY_MAP(KEY_F2)
ADD_ENUM_TO_KEY_MAP(KEY_F3)
ADD_ENUM_TO_KEY_MAP(KEY_F4)
ADD_ENUM_TO_KEY_MAP(KEY_F5)
ADD_ENUM_TO_KEY_MAP(KEY_F6)
ADD_ENUM_TO_KEY_MAP(KEY_F7)
ADD_ENUM_TO_KEY_MAP(KEY_F8)
ADD_ENUM_TO_KEY_MAP(KEY_F9)
ADD_ENUM_TO_KEY_MAP(KEY_F10)
ADD_ENUM_TO_KEY_MAP(KEY_F11)
ADD_ENUM_TO_KEY_MAP(KEY_F12)
ADD_ENUM_TO_KEY_MAP(KEY_PAD0)
ADD_ENUM_TO_KEY_MAP(KEY_PAD1)
ADD_ENUM_TO_KEY_MAP(KEY_PAD2)
ADD_ENUM_TO_KEY_MAP(KEY_PAD3)
ADD_ENUM_TO_KEY_MAP(KEY_PAD4)
ADD_ENUM_TO_KEY_MAP(KEY_PAD5)
ADD_ENUM_TO_KEY_MAP(KEY_PAD6)
ADD_ENUM_TO_KEY_MAP(KEY_PAD7)
ADD_ENUM_TO_KEY_MAP(KEY_PAD8)
ADD_ENUM_TO_KEY_MAP(KEY_PAD9)
ADD_ENUM_TO_KEY_MAP(KEY_PADMINUS)
ADD_ENUM_TO_KEY_MAP(KEY_PADPLUS)
ADD_ENUM_TO_KEY_MAP(KEY_PADPERIOD)
ADD_ENUM_TO_KEY_MAP(KEY_PADDIVIDE)
ADD_ENUM_TO_KEY_MAP(KEY_PADMULTIPLY)
ADD_ENUM_TO_KEY_MAP(KEY_PADENTER)
ADD_ENUM_TO_KEY_MAP(KEY_INSERT)
ADD_ENUM_TO_KEY_MAP(KEY_HOME)
ADD_ENUM_TO_KEY_MAP(KEY_PAGEUP)
ADD_ENUM_TO_KEY_MAP(KEY_DELETE)
ADD_ENUM_TO_KEY_MAP(KEY_END)
ADD_ENUM_TO_KEY_MAP(KEY_PAGEDOWN)
ADD_ENUM_TO_KEY_MAP(KEY_UP)
ADD_ENUM_TO_KEY_MAP(KEY_DOWN)
ADD_ENUM_TO_KEY_MAP(KEY_LEFT)
ADD_ENUM_TO_KEY_MAP(KEY_RIGHT)
ADD_ENUM_TO_KEY_MAP(KEY_PRINT_SCRN)
ADD_ENUM_TO_KEY_MAP(KEY_PAUSE)
ADD_ENUM_TO_KEY_MAP(KEY_BREAK)
#undef ADD_ENUM_TO_KEY_MAP
}
/*! Helper function to LoadEnumsIntoMaps(), Loads the Control Types enumerations into mCCTypeNameToVal
*/
void LoadEnumsIntoCCTypeMap(void) {
// Dirty macro hack :D
#define ADD_ENUM_TO_CCTYPE_MAP(Enum) mCCTypeNameToVal[#Enum] = (Enum);
ADD_ENUM_TO_CCTYPE_MAP(CC_TYPE_TRIGGER)
ADD_ENUM_TO_CCTYPE_MAP(CC_TYPE_CONTINUOUS)
#undef ADD_ENUM_TO_CCTYPE_MAP
}
/*! Helper function to LoadEnumsIntoMaps(), Loads the Control Tabs enumerations into mCCTabNameToVal
*/
void LoadEnumsIntoCCTabMap(void) {
// Dirty macro hack :D
#define ADD_ENUM_TO_CCTAB_MAP(Enum) mCCTabNameToVal[#Enum] = (Enum);
ADD_ENUM_TO_CCTAB_MAP(TARGET_TAB)
ADD_ENUM_TO_CCTAB_MAP(SHIP_TAB)
ADD_ENUM_TO_CCTAB_MAP(WEAPON_TAB)
ADD_ENUM_TO_CCTAB_MAP(COMPUTER_TAB)
#undef ADD_ENUM_TO_CCTAB_MAP
}
/*! Loads the various control configuration maps to allow the parsing functions to appropriately map string tokns to
* their associated enumerations. The string tokens in the controlconfigdefaults.tbl match directly to their names in
* the C++ code, such as "KEY_5" in the .tbl mapping to the #define KEY_5 value
*/
void LoadEnumsIntoMaps() {
LoadEnumsIntoKeyMap();
LoadEnumsIntoCCTypeMap();
LoadEnumsIntoCCTabMap();
}
/**
* @brief Parses controlconfigdefault.tbl, and overrides the default control configuration for each valid entry in the .tbl
*/
void control_config_common_load_overrides()
{
LoadEnumsIntoMap();
if (cf_exists_full("controlconfigdefaults.tbl", CF_TYPE_TABLES))
read_file_text("controlconfigdefaults.tbl", CF_TYPE_TABLES);
else
read_file_text_from_array(defaults_get_file("controlconfigdefaults.tbl"));
reset_parse();
LoadEnumsIntoMaps();
if (cf_exists_full("controlconfigdefaults.tbl", CF_TYPE_TABLES)) {
read_file_text("controlconfigdefaults.tbl", CF_TYPE_TABLES);
} else {
read_file_text_from_array(defaults_get_file("controlconfigdefaults.tbl"));
}
reset_parse();
// start parsing
// TODO: Split this out into more helps. Too many tabs!
while(optional_string("#ControlConfigOverride")) {
config_item *cfg_preset = new config_item[CCFG_MAX + 1];
std::copy(Control_config, Control_config + CCFG_MAX + 1, cfg_preset);
Control_config_presets.push_back(cfg_preset);
config_item *cfg_preset = new config_item[CCFG_MAX + 1];
std::copy(Control_config, Control_config + CCFG_MAX + 1, cfg_preset);
Control_config_presets.push_back(cfg_preset);
while (required_string_either("#End","$Bind Name:"))
{
const int iBufferLength = 64;
char szTempBuffer[iBufferLength];
required_string("$Bind Name:");
stuff_string(szTempBuffer, F_NAME, iBufferLength);
const size_t cCntrlAryLength = sizeof(Control_config) / sizeof(Control_config[0]);
for (size_t i = 0; i < cCntrlAryLength; ++i)
{
config_item& r_ccConfig = cfg_preset[i];
if (!strcmp(szTempBuffer, r_ccConfig.text))
{
/**
* short key_default;
* short joy_default;
* char tab;
* bool hasXSTR;
* char type;
*/
int iTemp;
if (optional_string("$Key Default:"))
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.key_default = (short)mEnumNameToVal[szTempBuffer];}
if (optional_string("$Joy Default:"))
{stuff_int(&iTemp); r_ccConfig.joy_default = (short)iTemp;}
if (optional_string("$Key Mod Shift:"))
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_SHIFTED : 0;}
if (optional_string("$Key Mod Alt:"))
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_ALTED : 0;}
if (optional_string("$Key Mod Ctrl:"))
{stuff_int(&iTemp); r_ccConfig.key_default |= (iTemp == 1) ? KEY_CTRLED : 0;}
if (optional_string("$Category:"))
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.tab = (char)mEnumNameToVal[szTempBuffer];}
if (optional_string("$Has XStr:"))
{stuff_int(&iTemp); r_ccConfig.hasXSTR = (iTemp == 1);}
if (optional_string("$Type:"))
{stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.type = (char)mEnumNameToVal[szTempBuffer];}
if (optional_string("+Disable"))
r_ccConfig.disabled = true;
// Nerf the buffer now.
szTempBuffer[0] = '\0';
}
else if ((i + 1) == cCntrlAryLength)
{
error_display(1, "Bind Name not found: %s\n", szTempBuffer);
advance_to_eoln(NULL);
ignore_white_space();
return;
}
}
}
while (required_string_either("#End","$Bind Name:")) {
const int iBufferLength = 64;
char szTempBuffer[iBufferLength];
required_string("#End");
}
required_string("$Bind Name:");
stuff_string(szTempBuffer, F_NAME, iBufferLength);
const size_t cCntrlAryLength = sizeof(Control_config) / sizeof(Control_config[0]);
for (size_t i = 0; i < cCntrlAryLength; ++i) {
config_item& r_ccConfig = cfg_preset[i];
if (!strcmp(szTempBuffer, r_ccConfig.text)) {
/**
* short key_default;
* short joy_default;
* char tab;
* bool hasXSTR;
* char type;
*/
int iTemp;
if (optional_string("$Key Default:")) {
if (optional_string("NONE")) {
r_ccConfig.key_default = (short)-1;
} else {
stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.key_default = (short)mKeyNameToVal[szTempBuffer];
}
}
if (optional_string("$Joy Default:")) {
stuff_int(&iTemp);
r_ccConfig.joy_default = (short)iTemp;
}
if (optional_string("$Key Mod Shift:")) {
stuff_int(&iTemp);
r_ccConfig.key_default |= (iTemp == 1) ? KEY_SHIFTED : 0;
}
if (optional_string("$Key Mod Alt:")) {
stuff_int(&iTemp);
r_ccConfig.key_default |= (iTemp == 1) ? KEY_ALTED : 0;
}
if (optional_string("$Key Mod Ctrl:")) {
stuff_int(&iTemp);
r_ccConfig.key_default |= (iTemp == 1) ? KEY_CTRLED : 0;
}
if (optional_string("$Category:")) {
stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.tab = (char)mCCTabNameToVal[szTempBuffer];
}
if (optional_string("$Has XStr:")) {
stuff_int(&iTemp);
r_ccConfig.hasXSTR = (iTemp == 1);
}
if (optional_string("$Type:")) {
stuff_string(szTempBuffer, F_NAME, iBufferLength);
r_ccConfig.type = (char)mCCTypeNameToVal[szTempBuffer];
}
if (optional_string("+Disable")) {
r_ccConfig.disabled = true;
}
// Nerf the buffer now.
szTempBuffer[0] = '\0';
} else if ((i + 1) == cCntrlAryLength) {
error_display(1, "Bind Name not found: %s\n", szTempBuffer);
advance_to_eoln(NULL);
ignore_white_space();
return;
}
}
}
required_string("#End");
}
// Overwrite the control config with the first preset that was found
if (Control_config_presets.size() > 0) {
std::copy(Control_config_presets[0], Control_config_presets[0] + CCFG_MAX + 1, Control_config);
}
}
#define ADD_ENUM_TO_ENUM_MAP(Enum) mEnumNameToVal[#Enum] = (Enum);
void LoadEnumsIntoMap()
{
mEnumNameToVal["KEY_SHIFTED"] = KEY_SHIFTED;
/*
ADD_ENUM_TO_ENUM_MAP(KEY_SHIFTED)
ADD_ENUM_TO_ENUM_MAP(KEY_ALTED)
ADD_ENUM_TO_ENUM_MAP(KEY_CTRLED)
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUGGED)
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUGGED1)
ADD_ENUM_TO_ENUM_MAP(KEY_MASK)
ADD_ENUM_TO_ENUM_MAP(KEY_DEBUG_KEY)
*/
ADD_ENUM_TO_ENUM_MAP(KEY_0)
ADD_ENUM_TO_ENUM_MAP(KEY_1)
ADD_ENUM_TO_ENUM_MAP(KEY_2)
ADD_ENUM_TO_ENUM_MAP(KEY_3)
ADD_ENUM_TO_ENUM_MAP(KEY_4)
ADD_ENUM_TO_ENUM_MAP(KEY_5)
ADD_ENUM_TO_ENUM_MAP(KEY_6)
ADD_ENUM_TO_ENUM_MAP(KEY_7)
ADD_ENUM_TO_ENUM_MAP(KEY_8)
ADD_ENUM_TO_ENUM_MAP(KEY_9)
ADD_ENUM_TO_ENUM_MAP(KEY_A)
ADD_ENUM_TO_ENUM_MAP(KEY_B)
ADD_ENUM_TO_ENUM_MAP(KEY_C)
ADD_ENUM_TO_ENUM_MAP(KEY_D)
ADD_ENUM_TO_ENUM_MAP(KEY_E)
ADD_ENUM_TO_ENUM_MAP(KEY_F)
ADD_ENUM_TO_ENUM_MAP(KEY_G)
ADD_ENUM_TO_ENUM_MAP(KEY_H)
ADD_ENUM_TO_ENUM_MAP(KEY_I)
ADD_ENUM_TO_ENUM_MAP(KEY_J)
ADD_ENUM_TO_ENUM_MAP(KEY_K)
ADD_ENUM_TO_ENUM_MAP(KEY_L)
ADD_ENUM_TO_ENUM_MAP(KEY_M)
ADD_ENUM_TO_ENUM_MAP(KEY_N)
ADD_ENUM_TO_ENUM_MAP(KEY_O)
ADD_ENUM_TO_ENUM_MAP(KEY_P)
ADD_ENUM_TO_ENUM_MAP(KEY_Q)
ADD_ENUM_TO_ENUM_MAP(KEY_R)
ADD_ENUM_TO_ENUM_MAP(KEY_S)
ADD_ENUM_TO_ENUM_MAP(KEY_T)
ADD_ENUM_TO_ENUM_MAP(KEY_U)
ADD_ENUM_TO_ENUM_MAP(KEY_V)
ADD_ENUM_TO_ENUM_MAP(KEY_W)
ADD_ENUM_TO_ENUM_MAP(KEY_X)
ADD_ENUM_TO_ENUM_MAP(KEY_Y)
ADD_ENUM_TO_ENUM_MAP(KEY_Z)
ADD_ENUM_TO_ENUM_MAP(KEY_MINUS)
ADD_ENUM_TO_ENUM_MAP(KEY_EQUAL)
ADD_ENUM_TO_ENUM_MAP(KEY_DIVIDE)
ADD_ENUM_TO_ENUM_MAP(KEY_SLASH)
ADD_ENUM_TO_ENUM_MAP(KEY_SLASH_UK)
ADD_ENUM_TO_ENUM_MAP(KEY_COMMA)
ADD_ENUM_TO_ENUM_MAP(KEY_PERIOD)
ADD_ENUM_TO_ENUM_MAP(KEY_SEMICOL)
ADD_ENUM_TO_ENUM_MAP(KEY_LBRACKET)
ADD_ENUM_TO_ENUM_MAP(KEY_RBRACKET)
ADD_ENUM_TO_ENUM_MAP(KEY_RAPOSTRO)
ADD_ENUM_TO_ENUM_MAP(KEY_LAPOSTRO)
ADD_ENUM_TO_ENUM_MAP(KEY_ESC)
ADD_ENUM_TO_ENUM_MAP(KEY_ENTER)
ADD_ENUM_TO_ENUM_MAP(KEY_BACKSP)
ADD_ENUM_TO_ENUM_MAP(KEY_TAB)
ADD_ENUM_TO_ENUM_MAP(KEY_SPACEBAR)
ADD_ENUM_TO_ENUM_MAP(KEY_NUMLOCK)
ADD_ENUM_TO_ENUM_MAP(KEY_SCROLLOCK)
ADD_ENUM_TO_ENUM_MAP(KEY_CAPSLOCK)
ADD_ENUM_TO_ENUM_MAP(KEY_LSHIFT)
ADD_ENUM_TO_ENUM_MAP(KEY_RSHIFT)
ADD_ENUM_TO_ENUM_MAP(KEY_LALT)
ADD_ENUM_TO_ENUM_MAP(KEY_RALT)
ADD_ENUM_TO_ENUM_MAP(KEY_LCTRL)
ADD_ENUM_TO_ENUM_MAP(KEY_RCTRL)
ADD_ENUM_TO_ENUM_MAP(KEY_F1)
ADD_ENUM_TO_ENUM_MAP(KEY_F2)
ADD_ENUM_TO_ENUM_MAP(KEY_F3)
ADD_ENUM_TO_ENUM_MAP(KEY_F4)
ADD_ENUM_TO_ENUM_MAP(KEY_F5)
ADD_ENUM_TO_ENUM_MAP(KEY_F6)
ADD_ENUM_TO_ENUM_MAP(KEY_F7)
ADD_ENUM_TO_ENUM_MAP(KEY_F8)
ADD_ENUM_TO_ENUM_MAP(KEY_F9)
ADD_ENUM_TO_ENUM_MAP(KEY_F10)
ADD_ENUM_TO_ENUM_MAP(KEY_F11)
ADD_ENUM_TO_ENUM_MAP(KEY_F12)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD0)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD1)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD2)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD3)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD4)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD5)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD6)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD7)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD8)
ADD_ENUM_TO_ENUM_MAP(KEY_PAD9)
ADD_ENUM_TO_ENUM_MAP(KEY_PADMINUS)
ADD_ENUM_TO_ENUM_MAP(KEY_PADPLUS)
ADD_ENUM_TO_ENUM_MAP(KEY_PADPERIOD)
ADD_ENUM_TO_ENUM_MAP(KEY_PADDIVIDE)
ADD_ENUM_TO_ENUM_MAP(KEY_PADMULTIPLY)
ADD_ENUM_TO_ENUM_MAP(KEY_PADENTER)
ADD_ENUM_TO_ENUM_MAP(KEY_INSERT)
ADD_ENUM_TO_ENUM_MAP(KEY_HOME)
ADD_ENUM_TO_ENUM_MAP(KEY_PAGEUP)
ADD_ENUM_TO_ENUM_MAP(KEY_DELETE)
ADD_ENUM_TO_ENUM_MAP(KEY_END)
ADD_ENUM_TO_ENUM_MAP(KEY_PAGEDOWN)
ADD_ENUM_TO_ENUM_MAP(KEY_UP)
ADD_ENUM_TO_ENUM_MAP(KEY_DOWN)
ADD_ENUM_TO_ENUM_MAP(KEY_LEFT)
ADD_ENUM_TO_ENUM_MAP(KEY_RIGHT)
ADD_ENUM_TO_ENUM_MAP(KEY_PRINT_SCRN)
ADD_ENUM_TO_ENUM_MAP(KEY_PAUSE)
ADD_ENUM_TO_ENUM_MAP(KEY_BREAK)
ADD_ENUM_TO_ENUM_MAP(TARGET_TAB)
ADD_ENUM_TO_ENUM_MAP(SHIP_TAB)
ADD_ENUM_TO_ENUM_MAP(WEAPON_TAB)
ADD_ENUM_TO_ENUM_MAP(COMPUTER_TAB)
}
+12 -15
View File
@@ -55,12 +55,8 @@ void cutscene_init()
int rval;
cutscene_info cutinfo;
// open localization
lcl_ext_open();
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "cutscenes.tbl", rval));
lcl_ext_close();
return;
}
@@ -88,8 +84,10 @@ void cutscene_init()
compact_multitext_string(buf);
cutinfo.description = vm_strdup(buf);
required_string("$cd:");
stuff_int( &cutinfo.cd );
if (optional_string("$cd:"))
stuff_int( &cutinfo.cd );
else
cutinfo.cd = 0;
cutinfo.viewable = false;
@@ -107,9 +105,6 @@ void cutscene_init()
}
required_string("#End");
// close localization
lcl_ext_close();
}
// function to return 0 based index of which CD a particular movie is on
@@ -155,6 +150,8 @@ void cutscene_mark_viewable(char *filename)
}
i++;
}
Warning(LOCATION, "Could not find cutscene '%s' in listing; cannot mark it viewable...", filename);
}
#define NUM_BUTTONS 8
@@ -261,7 +258,7 @@ int cutscenes_validate_cd(char *mve_name, int prompt_for_cd)
int cd_present = 0;
int cd_drive_num;
int cd_mve_is_on;
char volume_name[128];
char volume_name[MAX_PATH_LEN];
int num_attempts = 0;
@@ -321,7 +318,7 @@ void cutscenes_screen_play()
strcpy_s(name, Cutscenes[which_cutscene].filename );
// full_name = cf_add_ext(name, NOX(".mve"));
main_hall_stop_music();
main_hall_stop_music(true);
main_hall_stop_ambient();
int rval = movie_play(name);
main_hall_start_music();
@@ -334,7 +331,7 @@ void cutscenes_screen_play()
else
sprintf(str, XSTR("Unable to play movie %s.", 204), Cutscenes[which_cutscene].name);
popup(0, 1, POPUP_OK, str );
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, str );
}
}
@@ -581,7 +578,7 @@ void cutscenes_screen_do_frame()
GR_MAYBE_CLEAR_RES(Background_bitmap);
if (Background_bitmap >= 0) {
gr_set_bitmap(Background_bitmap);
gr_bitmap(0, 0);
gr_bitmap(0, 0, GR_RESIZE_MENU);
}
Ui_window.draw();
@@ -611,7 +608,7 @@ void cutscenes_screen_do_frame()
gr_set_color_fast(&Color_text_normal);
}
gr_printf(Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1] + y, Cutscenes[Cutscene_list[z]].name);
gr_printf_menu(Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1] + y, Cutscenes[Cutscene_list[z]].name);
y += font_height;
z++;
@@ -650,7 +647,7 @@ void cutscenes_screen_do_frame()
strncpy(line, Text_lines[z], len);
line[len] = 0;
gr_string(Cutscene_desc_coords[gr_screen.res][0], Cutscene_desc_coords[gr_screen.res][1] + y, line);
gr_string(Cutscene_desc_coords[gr_screen.res][0], Cutscene_desc_coords[gr_screen.res][1] + y, line, GR_RESIZE_MENU);
y += font_height;
z++;
+1 -1
View File
@@ -614,7 +614,7 @@ void mve_video_display()
// DDOI - This is probably really fricking slow
int bitmap = bm_create (16, g_screenWidth, g_screenHeight, pixelbuf, 0);
gr_set_bitmap (bitmap);
gr_bitmap ((int)g_screenX, (int)g_screenY, true);
gr_bitmap ((int)g_screenX, (int)g_screenY, GR_RESIZE_FULL);
bm_release (bitmap);
}
+1 -1
View File
@@ -797,7 +797,7 @@ THEORAFILE *theora_open(char *filename)
// lower case filename for checking
memset( lower_name, 0, sizeof(lower_name) );
strncpy( lower_name, filename, strlen(filename) );
strncpy( lower_name, filename, sizeof(lower_name)-1 );
strlwr(lower_name);
char *p = strchr( lower_name, '.' );
+2 -2
View File
@@ -526,11 +526,11 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
// Create Debris piece n!
if ( hull_flag ) {
if (rand() < RAND_MAX/6) // Make some pieces blow up shortly after explosion.
db->lifeleft = 2.0f * ((float) myrand()/(float) RAND_MAX) + 0.5f;
db->lifeleft = 2.0f * (myrand() * RAND_MAX_1f) + 0.5f;
else
db->lifeleft = -1.0f; // large hull pieces stay around forever
} else {
db->lifeleft = (i2fl(myrand())/i2fl(RAND_MAX))*2.0f+0.1f;
db->lifeleft = (myrand() * RAND_MAX_1f) * 2.0f + 0.1f;
}
}
File diff suppressed because it is too large. Load diff
+279
View File
@@ -0,0 +1,279 @@
#ifndef _CONSOLE_H
#define _CONSOLE_H
/*
* z64555's debug console, created for the FreeSpace Source Code project
*
* Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
* commercially exploit the source or things you created based on the source.
*/
/**
* @file console.h
* @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
*
* @details
* Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
* debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
* that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
* a pair of -'s, or --)
*/
#include "debugconsole/consoleparse.h"
#include "globalincs/pstypes.h"
#include "globalincs/vmallocator.h"
#define DC_MAX_COMMANDS 300
class debug_command;
/**
* @def DCF
*
* @brief The potent DCF macro, used to define new debug commands for the console.
*
* @param function_name[in] The name of the function, as shown in the debug console
* @param help_txt[in] The short-help text, as shown as listed from the 'help' command
*
* @details
* Each DCF is responsible for getting data from the debug console's command line. The parsing functions for the
* command line have been set up to have similar syntax and usage as the parselo commands. (see consoleparse.h)
* Most, if not all, argument and subcommand strings should be parsed by the dc_optional_string functions.
* Usage example:
* DCF(toggle_it, "description")
* {
* if (dc_optional_string_either("help", "--help")) {
* dc_printf("Usage: sample. Toggles This_var on/off\n");
*
* } else if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
* dc_printf("This_var is %s\n", (This_var ? "ON" : "OFF"));
*
* } else {
* This_var = !This_var;
*
* }
* }
*
* In the console, the command would be listed as 'toggle_it', and dcf_help would display it as:
* toggle_it - Usage: sample. Toggles This_var on/off.
* Note: The only allowed function type is a void fn( void )
*/
#define DCF(function_name, help_text) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
void dcf_##function_name()
/**
* @def Shortcut for debug commands that toggle a bool, such as Show_lightning
*
* @param [in] function_name Name of the function, as shown in the debug console
* @param [in] bool_variable Name of the variable to allow toggling.
*/
#define DCF_BOOL(function_name, bool_variable) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name ); \
void dcf_##function_name() { \
bool bool_tmp = bool_variable != 0; \
if (dc_optional_string_either("help", "--help")) { \
dc_printf( "Usage: %s [bool]\nSets %s to true or false. If nothing passed, then toggles it.\n", #function_name, #bool_variable ); \
return; \
} \
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
dc_printf("%s = %s\n", #bool_variable, (bool_variable ? "TRUE" : "FALSE")); \
return; \
} \
if (!dc_maybe_stuff_boolean(&bool_tmp)) { \
if (bool_variable != 0) \
bool_variable = 0; \
else \
bool_variable = 1; \
} else { \
if (bool_tmp) \
bool_variable = 1; \
else \
bool_variable = 0; \
} \
dc_printf("%s set to %s\n", #bool_variable, (bool_variable != 0 ? "TRUE" : "FALSE")); \
}
/**
* @def Same as DCF_BOOL, but with custom help strings
*
* @param [in] function_name Name of the function, as shown in the debug console
* @param [in] bool_variable Name of the variable to allow toggling.
*/
#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
void dcf_##function_name() { \
if (dc_optional_string_either("help", "--help")) { \
dc_printf( #long_help ); \
return; \
} \
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE")); \
return; \
} \
if (!dc_maybe_stuff_boolean(&bool_variable)) { \
bool_variable = !bool_variable; \
} \
}
/**
* @def Shortcut for single-variable setters/monitors
*
* @param [in] function_name
* @param [in] float_variable
* @param [in] short_help
*/
#define DCF_FLOAT(function_name, float_variable, short_help) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
void dcf_##function_name() { \
float value; \
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
dc_printf("%s = %f\n", #float_variable, float_variable); \
return; \
} \
dc_stuff_float(&value); \
float_variable = value; \
dc_printf("%s set to %f\n", #float_variable, float_variable); \
}
/**
* @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
*
* @param [in] function_name
* @param [in] float_variable
* @param [in] lower_bounds
* @param [in] upper_bounds
* @param [in] short_help
*/
#define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
void dcf_##function_name() { \
float value; \
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
dc_printf("%s = %f\n", #float_variable, float_variable); \
return; \
} \
dc_stuff_float(&value); \
CLAMP(float_variable, lower_bounds, upper_bounds); \
float_variable = value; \
dc_printf("%s set to %f\n", #float_variable, float_variable); \
}
/**
* @def Shortcut for single-variable setters/monitors
*
* @param [in] function_name
* @param [in] int_variable
* @param [in] short_help
*/
#define DCF_INT(function_name, int_variable, short_help) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
void dcf_##function_name() { \
int value; \
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
dc_printf("%s = %i\n", #int_variable, int_variable); \
return; \
} \
dc_stuff_int(&value); \
int_variable = value; \
dc_printf("%s set to %i\n", #int_variable, int_variable); \
}
/**
* @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
*
* @param [in] function_name
* @param [in] int_variable
* @param [in] lower_bounds
* @param [in] upper_bounds
* @param [in] short_help
*/
#define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
void dcf_##function_name(); \
debug_command dcmd_##function_name(#function_name, short_help, dcf_##function_name ); \
void dcf_##function_name() { \
int value; \
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
dc_printf("%s = %i\n", #int_variable, int_variable); \
return; \
} \
dc_stuff_int(&value); \
CLAMP(int_variable, lower_bounds, upper_bounds); \
int_variable = value; \
dc_printf("%s set to %i\n", #int_variable, int_variable); \
}
/**
* @class debug_command
* @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
*
* @details
* Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
* that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
* size of the command function down.
*/
class debug_command {
public:
const char *name; //!< The name of the command, as shown in the debug console
const char *help; //!< The short help string, as shown by 'help <command>'
void (*func)(); //!< Pointer to the function that to run when this command is evoked
debug_command();
/**
* @brief Adds a debug command to the debug_commands map, if it isn't in there already.
*
* @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
* some extra caution.
*/
debug_command(const char *name, const char *help, void (*func)());
};
/**
* @class is_dcmd
* @brief Predicate class used to search for a dcmd by name
*/
class is_dcmd {
public:
const char *name;
is_dcmd(const char *_name) : name(_name) {}
bool operator() (debug_command* dcmd)
{
return (strcmp(name, dcmd->name) == 0);
}
};
extern bool Dc_debug_on;
extern int dc_commands_size;
extern uint lastline;
extern SCP_string dc_command_str; // The rest of the command line, from the end of the last processed arg on.
/**
* @brief Pauses the output of a command and allows user to scroll through the output history.
*
* @details Returns true if user has pressed Esc, returns false otherwise. Use this in your function to (safely?) break
* out of the loop it's presumably in.
*/
bool dc_pause_output(void);
/**
* @brief Prints the given char string to the debug console
* @details See the doc for std::printf() for formating and more details
*/
void dc_printf(const char *format, ...);
/**
* @brief Opens and processes the debug console. (Blocking call)
* @details TODO: Make this a non-blocking call so that the game can still run while the debug console is open.
*/
void debug_console(void (*func)(void) = NULL);
#endif // _CONSOLE_H
+162
View File
@@ -0,0 +1,162 @@
/*
* z64555's debug console
* Created for the FreeSpace Source Code project
*
* Portions of this source code are based on works by Volition, Inc. circa
* 1999. You may not sell or otherwise commercially exploit the source or things you
* created based on the source
*/
/**
* @file consolecmds.cpp
*
* @brief This file contains the "built-in" commands for the debug console, and is listed by the 'help' and '?' commands
*
* @details
* All other debug commands should be in their respective files and added to the console with the DCF macro. For
* further documentation, please see console.h
*/
#include "debugconsole/console.h"
#include "debugconsole/consoleparse.h"
#include "globalincs/pstypes.h"
#include "globalincs/vmallocator.h"
#include "io/key.h"
#include <algorithm>
// ========================= GLOBALS =========================
debug_command *dc_commands[DC_MAX_COMMANDS];
int dc_commands_size = 0;
// ========================= LOCALS ==========================
// dcf_shell commands
void dc_shell_font( void );
void dc_shell_resize( void );
void dc_shell_resize_buf( void );
// =================== class debug_command ===================
debug_command::debug_command()
: name(""), help(""), func(NULL) {
};
debug_command::debug_command(const char *_name, const char *_help, void(*_func)())
: name(_name), help(_help), func(_func) {
int i = 0;
int ret = 0;
if (dc_commands_size >= DC_MAX_COMMANDS) {
Error(LOCATION, "Too many debug console commands! Please inform a coder to increase DC_MAX_COMMANDS.");
return;
}
// Start the insertion sort by finding where to stick the debug command
for (; i < dc_commands_size; ++i) {
ret = stricmp(dc_commands[i]->name, _name);
if (ret == 0) {
Error(LOCATION, "Debug Command %s already exists! Please inform a coder immediately.", _name);
return;
} else if (ret > 0) {
// Insert the command here
break;
} // Else, do nothing
}
// Then, do the insertion
if (i < dc_commands_size) {
for (int j = dc_commands_size; j > i; --j) {
dc_commands[j] = dc_commands[j - 1];
}
dc_commands[i] = this;
dc_commands_size++;
} else {
dc_commands[dc_commands_size] = this;
dc_commands_size++;
}
}
// ============================== IMPLEMENTATIONS =============================
DCF(debug, "Runs a command in debug mode.")
{
int i;
SCP_string command = "";
Dc_debug_on = true;
dc_stuff_string_white(command);
if (command == "") {
dc_printf("<debug> No command given\n");
return;
} // Else, command is present.
for (i = 0; i < dc_commands_size; ++i) {
if (stricmp(dc_commands[i]->name, command.c_str()) == 0) {
break;
} // Else, continue
}
if (i == dc_commands_size) {
dc_printf("<debug> Command not found: '%s'\n", command.c_str());
return;
} // Else, we found our command
dc_printf("<debug> Executing command: '%s'\n", command.c_str());
// try {
dc_commands[i]->func();
// } catch {
// }
Dc_debug_on = false;
}
DCF(help, "Displays the help list." )
{
extern uint DROWS;
int i;
SCP_string command = "";
dc_maybe_stuff_string_white(command);
if ((command == "help") || (command == "man"))
{
// Moron filter :D
dc_printf("GTVA Command: Sorry pilot. You're on your own.\n");
return;
} else if (command != "") {
for (i = 0; i < dc_commands_size; ++i) {
if (stricmp(dc_commands[i]->name, command.c_str()) == 0) {
break;
} // Else, continue
}
if (i == dc_commands_size) {
dc_printf("Command not found: '%s'\n", command.c_str());
return;
} // Else, we found our command
dc_printf("%s\n", dc_commands[i]->help);
return;
} // Else, command line is empty, print out the help list
dc_printf("FreeSpace Open Debug Console\n");
dc_printf(" These commands are defined internally.\n");
dc_printf(" Typing 'help function_name' will give the short help on the function.\n");
dc_printf(" Some functions may have detailed help, try passing \"help\" or \"--help\" to them.");
dc_printf(" F3 selects last command line. Up and Down arrow keys scroll through the command history\n");
dc_printf("\n");
dc_printf(" Available commands:\n");
for (i = 0; i < dc_commands_size; ++i) {
if (((lastline % DROWS) == 0) && (lastline != 0)) {
dc_pause_output();
}
dc_printf(" %s - %s\n", dc_commands[i]->name, dc_commands[i]->help);
}
}
debug_command dc_man("man", "Also displays the help list", dcf_help);
File diff suppressed because it is too large. Load diff
+459
View File
@@ -0,0 +1,459 @@
#ifndef _CONSOLEPARSE_H
#define _CONSOLEPARSE_H
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
//
// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
// commercially exploit the source or things you created based on the source.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @file consoleparse.h
* @brief Parsing functions for the command line. Previously known as the command line scanner
*
* @details A lot of functions here are blatently copied from parselo.h :D
*/
#include "globalincs/pstypes.h"
#include <cstdarg>
#define MAX_CLI_LEN 512
#define MAX_TOKEN_LENGTH 255
enum dc_token {
DCT_NONE = 0, //!< No token
DCT_STRING, //!< String
DCT_FLOAT, //!< Floating point
DCT_INT, //!< Integral
DCT_UINT, //!< Unsigned Integral
DCT_BYTE, //!< Integral with values between -128 and 127
DCT_UBYTE, //!< Integral with values between 0 and 255
DCT_BOOL, //!< Integral or string evaluated as a boolean
DCT_MAX_ITEMS //!< Maximum number of dc_token elements. Primarily used as an end value in loops
};
/**
* @class errParse
*
* @brief Class thrown when a required token is not found
*
* @details This is a basic parser error, it contains the token (a single word) that was found, and the expected token
* type. Some DCT's, such as the DCT_STRING's, have their own specific requirements for error handling, and as
* such get their own class derived from errParse. The catching routines should be able to catch the derived error
* objects, but if not, they can be caught by a routine looking for the base class and then be casted to their
* proper type.
*/
class errParse {
public:
SCP_string found_token;
dc_token expected_type;
/**
* @brief Invalid/Unexpected token constructor
* @param [in] found_str The token that was found
* @param [in] expected_dct The token type that was expected
*/
errParse(const char *found_str, dc_token expected_dct)
: found_token(found_str), expected_type(expected_dct)
{
}
};
/**
* @class errParseString
*
* @brief Class thrown when an expected string was not found. Can/should contain all of the expected strings.
*/
class errParseString : public errParse
{
public:
SCP_vector<SCP_string> expected_tokens;
/**
* @brief Invalid/Unexpected token constructor.
*
* @param [in] found_str The string that was found
* @param [in] str The token that was expected
*/
errParseString(const char *found_str, char *str)
: errParse(found_str, DCT_STRING)
{
expected_tokens.push_back(str);
}
/**
* @brief Invalid/Unexpected token constructor.
*
* @param [in] found_str The string that was found
* @param [in] str1 The first token that was expected
* @param [in] str2 The second token that was expected
*/
errParseString(const char *found_str, char *str1, char *str2)
: errParse(found_str, DCT_STRING)
{
expected_tokens.push_back(str1);
expected_tokens.push_back(str2);
}
/**
* @brief Invalid/Unexpected token constructor.
*
* @param [in] found_str The string that was found
* @param [in] strings The strings that were expected
*/
errParseString(const char *found_str, SCP_vector<SCP_string> &strings)
: errParse(found_str, DCT_STRING), expected_tokens(strings)
{
}
};
/**
* @class errParseOverflow
*
* @brief Class thrown when the parsed string or token could not be stuffed into the smaller destination container
*
* @var found_str Contains the first 'len' valid characters.
*/
class errParseOverflow : public errParse
{
public:
size_t len; //!< The size of the destination container
errParseOverflow(const char *found_str, size_t _len)
: errParse(found_str, DCT_STRING), len(_len)
{
}
};
/**
* @brief Initializes the DC command line parser
*/
void dc_parse_init(SCP_string &str);
/**
* @brief Advances the parser past whitespace characters
*/
void dc_ignore_white_space(void);
/**
* @brief Advances the parser past grayspace characters
*/
void dc_ignore_gray_space(void);
// Required/Optional Token
/**
* @brief Searches for a specified required string, throwing an errParse if not found.
*
* @param[in] pstr The string to search for
*
* @throws errParseString with the required string
*/
void dc_required_string(char *pstr);
/**
* @brief Searchs for either of the specified required strings, throwing an errParse if neither are found
*
* @param[in] str1 The first string to search for
* @param[in] str2 The second string to search for
*
* @retval 0 if str1 was found, or
* @retval 1 if str2 was found
*
* @throws errParseString with the required strings
*/
int dc_required_string_either(char *str1, char *str2);
/**
* @brief Searches for specified required strings
*
* @param[in] n The number of char[] or c_str's given
* @param[in] ... A comma delimited list of one or more required strings.
*
* @returns The index of the specified required strings (as if they were an array)
*
* @throws errParseString with the required strings
*/
uint dc_required_string_any(const uint n, ...);
/**
* @brief Searches for an optional string
*
* @param[in] pstr The char[] to look for
*
* @retval true if the string was found,
* @retval false otherwise
*/
bool dc_optional_string(const char *pstr);
/**
* @brief Searches for an optional string and it's alias
*
* @param[in] str1 The char[] to look for
* @param[in] str2 The alternative char[] to look for
*
* @retval true if the string was found,
* @retval false otherwise
*/
bool dc_optional_string_either(const char *str1, const char *str2);
// ==========================
// Stuffers
// ==========================
/**
* @brief Stuffs a float to the given variable.
*
* @param[in] f The float variable to stuff to
*
* @throws errParse if an unexpected or otherwise malformed float string is found.
* @throws errParse if nothing was found
*/
void dc_stuff_float(float *f);
/**
* @brief Stuffs an int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
*
* @param[in] i The int variable to stuff to
*
* @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
* Ex: "0xDEADBEEF" would be parsed properly while "DEADBEEF" would throw an error
*
* @throws errParse if an unexpected or otherwise malformed float string is found.
* @throws errParse if nothing was found
*/
void dc_stuff_int(int *i);
/**
* @brief Stuffs an unsigned int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
*
* @param[in] i The unsigned int variable to stuff to
*
* @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
* Ex: "0xDEADBEEF" would be parsed properly while "DEADBEEF" would throw an error
*
* @throws errParse if an unexpected or otherwise malformed float string is found.
* @throws errParse if nothing was found
*/
void dc_stuff_uint(uint *i);
/**
* @brief Stuffs an unsigned byte to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
*
* @param[in] i The ubyte variable to stuff to
*
* @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
* Ex: "0x0F" would be parsed properly while "0F" would throw an error
*
* @throws errParse if an unexpected or otherwise malformed float string is found.
* @throws errParse if nothing was found
*/
void dc_stuff_ubyte(ubyte *i);
/**
* @brief stuffs a boolean evaluated integer or string into the given variable.
*
* @param[in] b The bool variable to stuff to
*
* @details Supports a number of literal strings as true and false, including "true", "false", "yes", "no" and the
* yes/no equivalents in other languages supported in localization.
* TODO: Make a static string map to handle this instead of being hard-coded
*
* @throws errParse if an unexpected or otherwise malformed float string is found.
* @throws errParse if nothing was found
*/
void dc_stuff_boolean(bool *b);
/**
* @brief stuffs a boolean evaluated integer or string into the given variable.
*
* @param[in] i The int variable to stuff to. 0 is false, 1 is true
*
* @details Supports a number of literal strings as true and false, including "true", "false", "yes", "no" and the
* yes/no equivalents in other languages supported in localization.
* TODO: Make a static string map to handle this instead of being hard-coded
*
* @throws errParse if an unexpected or otherwise malformed float string is found.
* @throws errParse if nothing was found
*/
void dc_stuff_boolean(int *i);
/**
* @brief Stuffs a string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string
* @param[in] maxlen Maximum length to copy. (maxlen <= sizeof(str)) && (maxlen <= MAX_TOKEN_LENGTH)
*
* @throws errParse when nothing left was found on the command line
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
*/
void dc_stuff_string(char *str, size_t maxlen);
/**
* @brief Stuffs a string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string
*
* @throws errParse when nothing left was found on the command line
*/
void dc_stuff_string(SCP_string &str);
/**
* @brief Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string
* @param[in] len Maximum length to copy. (len <= sizeof(str)) && (len <= MAX_TOKEN_LENGTH)
*
* @throws errParse when nothing left was found on the command line
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
*/
void dc_stuff_string_white(char *str, size_t len);
/**
* @brief Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string
*
* @throws errParse when nothing left was found on the command line
*/
void dc_stuff_string_white(SCP_string &str);
/**
* @brief Tries to stuff a float from the Command_string.
*
* @param[in] f The float variable to maybe stuff.
*
* @details
* If there's nothing on the command line, *f = 0 and false is returned
*
* If there's something on the command line, and we're able to convert it, *f = the converted value, true is
* returned, and the parser is advanced past the token
*
* If there's something on command line, but we can't convert it, an errParse is thrown
*/
bool dc_maybe_stuff_float(float *f);
/**
* @brief Tries to stuff an int from the Command_string.
*
* @param[in] i The int variable to maybe stuff.
*
* @details
* If there's nothing on the command line, *i = 0 and false is returned
*
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
* returned, and the parser is advanced past the token
*
* If there's something on command line, but we can't convert it, an errParse is thrown
*/
bool dc_maybe_stuff_int(int *i);
/**
* @brief Tries to stuff an uint from the Command_string.
*
* @param[in] i The uint variable to maybe stuff.
*
* @details
* If there's nothing on the command line, *i = 0 and false is returned
*
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
* returned, and the parser is advanced past the token
*
* If there's something on command line, but we can't convert it, an errParse is thrown
*/
bool dc_maybe_stuff_uint(uint *i);
/**
* @brief Tries to stuff an ubyte from the Command_string.
*
* @param[in] i The ubyte variable to maybe stuff.
*
* @details
* If there's nothing on the command line, *i = 0 and false is returned
*
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
* returned, and the parser is advanced past the token
*
* If there's something on command line, but we can't convert it, an errParse is thrown
*/
bool dc_maybe_stuff_ubyte(ubyte *i);
/**
* @brief Tries to stuff a bool from the Command_string.
*
* @param[in] b The bool variable to maybe stuff.
*
* @details
* If there's nothing on the command line, *b = false and false is returned
*
* If there's something on the command line, and we're able to convert it, *b = the converted value, true is
* returned, and the parser is advanced past the token
*
* If there's something on command line, but we can't convert it, an errParse is thrown
*/
bool dc_maybe_stuff_boolean(bool *b);
/**
* @brief Tries to stuff an int with a bool value from the Command_string.
*
* @param[in] i The int variable to maybe stuff.
*
* @details
* If there's nothing on the command line, *i = 0 and false is returned
*
* If there's something on the command line, and we're able to convert it, *i = the converted value, true is
* returned, and the parser is advanced past the token
*
* If there's something on command line, but we can't convert it, an errParse is thrown
*/
bool dc_maybe_stuff_boolean(int *i);
/**
* @brief Tries to stuff a string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string. If nothing was found, str = ""
* @param[in] len Maximum length to copy. (len <= sizeof(str)) && (len <= MAX_TOKEN_LENGTH)
*
* @retval true if the operation was successful,
* @retval false otherwise
*
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
*/
bool dc_maybe_stuff_string(char *str, size_t len);
/**
* @brief Tries to stuff a string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string. If nothing was found, str = ""
*
* @retval true if the operation was successful,
* @retval false otherwise
*/
bool dc_maybe_stuff_string(SCP_string &str);
/**
* @brief Tries to stuff a whitespace delimited string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string. If nothing was found, str = ""
* @param[in] len Maximum length to copy. (maxlen <= sizeof(str)) && (maxlen <= MAX_TOKEN_LENGTH)
*
* @retval true if the operation was successful,
* @retval false otherwise
*
* @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
*/
bool dc_maybe_stuff_string_white(char *str, size_t len);
/**
* @brief Tries to stuff a whitespace delimited string to out_str from the command line, stopping at the end of the command line
*
* @param[out] str Destination string. If nothing was found, str = ""
*
* @retval true if the operation was successful,
* @retval false otherwise
*/
bool dc_maybe_stuff_string_white(SCP_string &str);
#endif // _CONSOLEPARSE_H
+3 -8
View File
@@ -163,12 +163,8 @@ void parse_fireball_tbl(const char *filename)
lod_checker lod_check;
color fb_color;
// open localization
lcl_ext_open();
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
lcl_ext_close();
return;
}
@@ -241,9 +237,6 @@ void parse_fireball_tbl(const char *filename)
}
required_string("#End");
// close localization
lcl_ext_close();
}
void fireball_parse_tbl()
@@ -381,7 +374,9 @@ void fireball_render(object * obj)
MONITOR_INC( NumFireballsRend, 1 );
num = obj->instance;
memset(&p, 0, sizeof(p));
num = obj->instance;
fb = &Fireballs[num];
if ( Fireballs[num].current_bitmap < 0 )
+1
View File
@@ -58,6 +58,7 @@ void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_n
vm_vec_scale_add( &center, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
memset(verts, 0, sizeof(verts));
if (Warp_glow_bitmap >= 0) {
float r = radius;
+6 -2
View File
@@ -22,6 +22,7 @@ FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
//{{AFX_DATA_INIT(FictionViewerDlg)
m_story_file = _T("");
m_font_file = _T("");
m_voice_file = _T("");
m_fiction_music = 0;
//}}AFX_DATA_INIT
}
@@ -33,6 +34,7 @@ void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
//{{AFX_DATA_MAP(FictionViewerDlg)
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
DDX_Text(pDX, IDC_VOICE_FILE, m_voice_file);
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
//}}AFX_DATA_MAP
}
@@ -60,6 +62,7 @@ BOOL FictionViewerDlg::OnInitDialog()
// init variables
m_story_file = _T(fiction_file());
m_font_file = _T(fiction_font());
m_voice_file = _T(fiction_voice());
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
CDialog::OnInitDialog();
@@ -73,7 +76,7 @@ void FictionViewerDlg::OnOK()
// load it up
fiction_viewer_reset();
fiction_viewer_load((char *)(LPCSTR) m_story_file, (char *)(LPCSTR) m_font_file);
fiction_viewer_load((const char *)(LPCSTR)m_story_file, (const char *)(LPCSTR)m_font_file, (const char *)(LPCSTR)m_voice_file);
// set music
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
@@ -111,5 +114,6 @@ void FictionViewerDlg::OnClose()
int FictionViewerDlg::query_modified()
{
return strcmp(m_story_file, fiction_file()) || strcmp(m_font_file, fiction_font()) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
return strcmp(m_story_file, fiction_file()) || strcmp(m_font_file, fiction_font()) ||
strcmp(m_voice_file, fiction_voice()) || m_fiction_music != (Mission_music[SCORE_FICTION_VIEWER] + 1);
}
+1
View File
@@ -24,6 +24,7 @@ public:
enum { IDD = IDD_FICTION_VIEWER };
CString m_story_file;
CString m_font_file;
CString m_voice_file;
int m_fiction_music;
//}}AFX_DATA
+9
View File
@@ -233,6 +233,15 @@ void bg_bitmap_dlg::create()
m_skybox_bank = (int) fl_degrees(skybox_angles.b);
m_skybox_heading = (int) fl_degrees(skybox_angles.h);
//make sure angle values are in the 0-359 degree range
if (m_skybox_pitch < 0)
m_skybox_pitch = m_skybox_pitch + 359;
if (m_skybox_bank < 0)
m_skybox_bank = m_skybox_bank + 359;
if (m_skybox_heading < 0)
m_skybox_heading = m_skybox_heading + 359;
for(i=0; i<MAX_NEB2_BITMAPS; i++){
if(strlen(Neb2_bitmap_filenames[i]) > 0){ //-V805
((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->AddString(Neb2_bitmap_filenames[i]);
+18
View File
@@ -77,6 +77,7 @@ briefing_editor_dlg::briefing_editor_dlg(CWnd* pParent /*=NULL*/)
m_current_briefing = -1;
m_flipicon = FALSE;
m_use_wing = FALSE;
m_use_cargo = FALSE;
//}}AFX_DATA_INIT
m_voice_id = -1;
m_cur_stage = 0;
@@ -111,6 +112,7 @@ void briefing_editor_dlg::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_CUT_PREV, m_cut_prev);
DDX_Check(pDX, IDC_FLIP_ICON, m_flipicon);
DDX_Check(pDX, IDC_USE_WING_ICON, m_use_wing);
DDX_Check(pDX, IDC_USE_CARGO_ICON, m_use_cargo);
//}}AFX_DATA_MAP
DDV_MaxChars(pDX, m_voice, MAX_FILENAME_LEN - 1);
@@ -145,6 +147,7 @@ BEGIN_MESSAGE_MAP(briefing_editor_dlg, CDialog)
ON_BN_CLICKED(IDC_PASTE_VIEW, OnPasteView)
ON_BN_CLICKED(IDC_FLIP_ICON, OnFlipIcon)
ON_BN_CLICKED(IDC_USE_WING_ICON, OnWingIcon)
ON_BN_CLICKED(IDC_USE_CARGO_ICON, OnCargoIcon)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -452,6 +455,11 @@ void briefing_editor_dlg::update_data(int update)
else
ptr->icons[m_last_icon].flags &= ~BI_USE_WING_ICON;
if (m_use_cargo)
ptr->icons[m_last_icon].flags |= BI_USE_CARGO_ICON;
else
ptr->icons[m_last_icon].flags &= ~BI_USE_CARGO_ICON;
if ((ptr->icons[m_last_icon].type != m_icon_image) && !m_change_local) {
set_modified();
reset_icon_loop(m_last_stage);
@@ -555,6 +563,7 @@ void briefing_editor_dlg::update_data(int update)
m_hilight = (ptr->icons[m_cur_icon].flags & BI_HIGHLIGHT)?1:0;
m_flipicon = (ptr->icons[m_cur_icon].flags & BI_MIRROR_ICON)?1:0;
m_use_wing = (ptr->icons[m_cur_icon].flags & BI_USE_WING_ICON)?1:0;
m_use_cargo = (ptr->icons[m_cur_icon].flags & BI_USE_CARGO_ICON)?1:0;
m_icon_image = ptr->icons[m_cur_icon].type;
m_icon_team = ptr->icons[m_cur_icon].team;
m_icon_label = ptr->icons[m_cur_icon].label;
@@ -567,6 +576,7 @@ void briefing_editor_dlg::update_data(int update)
m_flipicon = FALSE;
m_hilight = FALSE;
m_use_wing = FALSE;
m_use_cargo = FALSE;
m_icon_image = -1;
m_icon_team = -1;
m_ship_type = -1;
@@ -580,8 +590,10 @@ void briefing_editor_dlg::update_data(int update)
// if so, disable the icon type box
int sip_bii_ship = (m_ship_type >= 0) ? Ship_info[m_ship_type].bii_index_ship : -1;
int sip_bii_wing = (sip_bii_ship >= 0) ? Ship_info[m_ship_type].bii_index_wing : -1;
int sip_bii_cargo = (sip_bii_ship >= 0) ? Ship_info[m_ship_type].bii_index_ship_with_cargo : -1;
GetDlgItem(IDC_USE_WING_ICON) -> ShowWindow(sip_bii_wing >= 0);
GetDlgItem(IDC_USE_CARGO_ICON) -> ShowWindow(sip_bii_cargo >= 0);
GetDlgItem(IDC_ICON_TEXT) -> EnableWindow(enable);
GetDlgItem(IDC_ICON_LABEL) -> EnableWindow(enable);
@@ -590,6 +602,7 @@ void briefing_editor_dlg::update_data(int update)
GetDlgItem(IDC_HILIGHT) -> EnableWindow(enable);
GetDlgItem(IDC_FLIP_ICON) -> EnableWindow(enable);
GetDlgItem(IDC_USE_WING_ICON) -> EnableWindow(enable);
GetDlgItem(IDC_USE_CARGO_ICON) -> EnableWindow(enable);
GetDlgItem(IDC_LOCAL) -> EnableWindow(enable);
GetDlgItem(IDC_TEAM) -> EnableWindow(enable);
GetDlgItem(IDC_ID) -> EnableWindow(enable);
@@ -1431,3 +1444,8 @@ void briefing_editor_dlg::OnWingIcon()
{
update_data(1);
}
void briefing_editor_dlg::OnCargoIcon()
{
update_data(1);
}
+2
View File
@@ -67,6 +67,7 @@ public:
int m_current_briefing;
BOOL m_flipicon;
BOOL m_use_wing;
BOOL m_use_cargo;
//}}AFX_DATA
CBitmap m_play_bm;
@@ -133,6 +134,7 @@ protected:
afx_msg void OnPasteView();
afx_msg void OnFlipIcon();
afx_msg void OnWingIcon();
afx_msg void OnCargoIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
+1 -3
View File
@@ -246,7 +246,6 @@ void campaign_editor::initialize( int init_files )
void campaign_editor::mission_selected(int num)
{
CEdit *bc_dialog, *bc_hall, *bc_persona;
char mainhalltext[10];
char personatext[10];
bc_dialog = (CEdit *) GetDlgItem(IDC_BRIEFING_CUTSCENE);
@@ -259,8 +258,7 @@ void campaign_editor::mission_selected(int num)
bc_dialog->SetWindowText(Campaign.missions[num].briefing_cutscene);
// new main hall stuff
sprintf(mainhalltext, "%s", const_cast<char*>(Campaign.missions[num].main_hall.c_str()));
bc_hall->SetWindowText(CString(mainhalltext));
bc_hall->SetWindowText(Campaign.missions[num].main_hall.c_str());
// new debriefing persona stuff
sprintf(personatext, "%d", Campaign.missions[num].debrief_persona_index);
+18 -15
View File
@@ -20,6 +20,7 @@
#include "cfile/cfile.h"
#include "sound/audiostr.h"
#include "localization/localize.h"
#include "mod_table/mod_table.h"
#ifdef _DEBUG
#undef THIS_FILE
@@ -222,21 +223,23 @@ BOOL event_editor::OnInitDialog()
}
}
// add new heads, if not already in
maybe_add_head(box, "Head-TP2");
maybe_add_head(box, "Head-VC2");
maybe_add_head(box, "Head-TP4");
maybe_add_head(box, "Head-TP5");
maybe_add_head(box, "Head-TP6");
maybe_add_head(box, "Head-TP7");
maybe_add_head(box, "Head-TP8");
maybe_add_head(box, "Head-VP2");
maybe_add_head(box, "Head-VP2");
maybe_add_head(box, "Head-CM2");
maybe_add_head(box, "Head-CM3");
maybe_add_head(box, "Head-CM4");
maybe_add_head(box, "Head-CM5");
maybe_add_head(box, "Head-BSH");
if (!Disable_hc_message_ani) {
maybe_add_head(box, "Head-TP2");
maybe_add_head(box, "Head-VC2");
maybe_add_head(box, "Head-TP4");
maybe_add_head(box, "Head-TP5");
maybe_add_head(box, "Head-TP6");
maybe_add_head(box, "Head-TP7");
maybe_add_head(box, "Head-TP8");
maybe_add_head(box, "Head-VP2");
maybe_add_head(box, "Head-VP2");
maybe_add_head(box, "Head-CM2");
maybe_add_head(box, "Head-CM3");
maybe_add_head(box, "Head-CM4");
maybe_add_head(box, "Head-CM5");
maybe_add_head(box, "Head-BSH");
}
/*
box->AddString("Head-VC"); // force it in, since Sandeep wants it and it's not used in built-in messages
+1 -1
View File
@@ -676,7 +676,7 @@ void CFREDApp::record_window_data(window_data *wndd, CWnd *wnd)
void CAboutDlg::OnBug()
{
char *path = "http://mgo.maxgaming.net/mantis/login_page.php";
char *path = "http://scp.indiegames.us/mantis/";
char buffer[MAX_PATH];
sprintf(buffer,"explorer.exe \"%s\"", path);
+28 -24
View File
@@ -171,7 +171,6 @@ BEGIN
POPUP "&Import"
BEGIN
MENUITEM "&FreeSpace 1 mission...", 33074
MENUITEM "&Weapon loadouts...", 33075
END
MENUITEM SEPARATOR
MENUITEM "&Run FreeSpace\tAlt+R", 32985
@@ -624,7 +623,7 @@ CAPTION "About FRED2"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,10,17,20,20,SS_REALSIZEIMAGE
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.7.1 OpenGL",IDC_STATIC,39,8,184,10,SS_NOPREFIX
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.7.2 OpenGL",IDC_STATIC,39,8,184,10,SS_NOPREFIX
LTEXT "Copyright © 1999 Volition, Inc. All Rights Reserved",IDC_STATIC,39,17,164,8
DEFPUSHBUTTON "OK",IDOK,229,7,48,14,WS_GROUP
LTEXT """Fred2 is the omega of all giant unwieldy pieces of code. Its big, its horrifying, and it just doesn't care. View it at your own risk."" - Dave Baranec",IDC_STATIC,39,62,238,20
@@ -880,6 +879,7 @@ BEGIN
PUSHBUTTON "Sound Environment",IDC_SOUND_ENVIRONMENT_BUTTON,158,244,140,15
CONTROL "Always Show Mission Goals In Briefing",IDC_ALWAYS_SHOW_GOALS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,180,142,10
CONTROL "Mission End to Mainhall",IDC_END_TO_MAINHALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,326,190,142,10
END
IDD_PREFERENCES DIALOG 0, 0, 333, 81
@@ -1598,7 +1598,7 @@ BEGIN
EDITTEXT IDC_EDIT1,7,7,310,271,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END
IDD_BRIEFING_EDITOR DIALOGEX 0, 0, 413, 399
IDD_BRIEFING_EDITOR DIALOGEX 0, 0, 413, 414
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Briefing Editor"
MENU IDR_PLAYER_EDIT_MENU
@@ -1622,7 +1622,7 @@ BEGIN
PUSHBUTTON "IDB_PLAY",IDC_PLAY,194,164,28,14,BS_BITMAP,WS_EX_TRANSPARENT | WS_EX_STATICEDGE
COMBOBOX IDC_BRIEFING_MUSIC,205,18,83,135,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SUBSTITUTE_BRIEFING_MUSIC,205,34,83,135,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
CONTROL "Tree1",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,190,200,205,WS_EX_CLIENTEDGE
CONTROL "Tree1",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,190,200,218,WS_EX_CLIENTEDGE
CONTROL "Draw lines between marked icons",IDC_LINES,"Button",BS_3STATE | WS_TABSTOP,233,353,122,10
EDITTEXT IDC_ICON_LABEL,269,216,108,14,ES_AUTOHSCROLL
COMBOBOX IDC_ICON_IMAGE,269,234,108,135,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
@@ -1637,7 +1637,7 @@ BEGIN
PUSHBUTTON "Propagate",IDC_PROPAGATE_ICONS,339,182,50,14,0,WS_EX_STATICEDGE
EDITTEXT IDC_ICON_TEXT,230,293,146,53,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN
LTEXT "Stage 1 of 9",IDC_STAGE_TITLE,7,7,53,8
GROUPBOX "Current Icon Info",IDC_STATIC,222,167,170,228
GROUPBOX "Current Icon Info",IDC_STATIC,222,167,170,241
LTEXT "Label",IDC_STATIC,230,219,18,8
LTEXT "Icon image",IDC_STATIC,229,237,36,8
LTEXT "Text",IDC_STATIC,7,62,15,8
@@ -1652,6 +1652,7 @@ BEGIN
LTEXT "If music pack is present",IDC_STATIC,149,31,44,17
GROUPBOX "Briefing Music",IDC_STATIC,141,7,150,44
CONTROL "Use Wing Icon",IDC_USE_WING_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,380,63,10
CONTROL "Use Cargo Icon",IDC_USE_CARGO_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,233,394,65,10
END
IDD_IGNORE_ORDERS DIALOG 0, 0, 120, 217
@@ -1833,11 +1834,12 @@ BEGIN
CONTROL "Laser Protect Ship",IDC_LASER_PROTECT_SHIP,"Button",BS_3STATE | WS_TABSTOP,12,110,80,8
CONTROL "Missile Protect Ship",IDC_MISSILE_PROTECT_SHIP,"Button",BS_3STATE | WS_TABSTOP,12,118,80,8
GROUPBOX "Turret Threats",IDC_STATIC,7,83,102,48
CONTROL "Does Not Move",IDC_IMMOBILE,"Button",BS_3STATE | WS_TABSTOP,7,274,66,10
CONTROL "Cloaked",IDC_CLOAKED,"Button",BS_3STATE | WS_TABSTOP,165,167,42,10
CONTROL "Does Not Move",IDC_IMMOBILE,"Button",BS_3STATE | WS_TABSTOP,7,274,66,10
CONTROL "Cloaked",IDC_CLOAKED,"Button",BS_3STATE | WS_TABSTOP,165,167,42,10
CONTROL "Scramble Messages",IDC_SCRAMBLE_MESSAGES,"Button",BS_3STATE | WS_TABSTOP,165,177,79,10
END
CONTROL "No Collisions",IDC_NO_COLLIDE,"Button",BS_3STATE | WS_TABSTOP,165,188,66,10
END
IDD_ADD_VARIABLE DIALOG 0, 0, 422, 102
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Add Variable"
@@ -1926,7 +1928,7 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,239,35,50,14
LTEXT "Old texture:",IDC_LABEL1,7,7,44,9
LTEXT "New texture:",IDC_LABEL2,152,7,44,9
COMBOBOX IDC_OLD_TEXTURE_LIST,7,16,137,85,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_OLD_TEXTURE_LIST,7,16,137,85,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_SPECIAL_HITPOINTS DIALOG 0, 0, 234, 85
@@ -2033,14 +2035,14 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,333,24,50,14
END
IDD_RESTRICT_PATHS DIALOG 0, 0, 141, 87
IDD_RESTRICT_PATHS DIALOG 0, 0, 241, 87
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Restrict Paths"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,84,20,50,14
PUSHBUTTON "Cancel",IDCANCEL,84,37,50,14
LISTBOX IDC_PATH_LIST,7,20,71,58,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,184,20,50,14
PUSHBUTTON "Cancel",IDCANCEL,184,37,50,14
LISTBOX IDC_PATH_LIST,7,20,171,58,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
LTEXT "Restrict departure paths to the following:",IDC_RESTRICT_PATHS_LABEL,7,7,127,11
END
@@ -2054,10 +2056,10 @@ BEGIN
COMBOBOX IDC_BACKGROUND,7,16,83,265,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_FICTION_VIEWER DIALOG 0, 0, 205, 66
IDD_FICTION_VIEWER DIALOGEX 0, 0, 205, 85
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Fiction Viewer Editor"
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK",IDOK,148,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,148,24,50,14
@@ -2065,8 +2067,10 @@ BEGIN
EDITTEXT IDC_STORY_FILE,45,7,99,14,ES_AUTOHSCROLL
RTEXT "Font File",IDC_STATIC,7,27,32,8
EDITTEXT IDC_FONT_FILE,45,24,99,14,ES_AUTOHSCROLL
RTEXT "Music",IDC_STATIC,14,43,25,8
COMBOBOX IDC_FICTION_MUSIC,45,42,99,140,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Music",IDC_STATIC,15,60,25,8
COMBOBOX IDC_FICTION_MUSIC,45,59,99,140,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Voice File",IDC_STATIC,9,43,32,8
EDITTEXT IDC_VOICE_FILE,45,40,99,14,ES_AUTOHSCROLL
END
IDD_SOUND_ENVIRONMENT DIALOGEX 0, 0, 315, 89
@@ -2099,8 +2103,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,7,1,0
PRODUCTVERSION 3,7,1,0
FILEVERSION 3,7,2,11329
PRODUCTVERSION 3,7,2,11329
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -2117,12 +2121,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Volition Inc."
VALUE "FileDescription", "Fred 2 Open"
VALUE "FileVersion", "3.7.1.0000"
VALUE "FileVersion", "3.7.2.11329"
VALUE "InternalName", "Fred 2 Open"
VALUE "LegalCopyright", "Copyright © 1998"
VALUE "OriginalFilename", "fred2.exe"
VALUE "ProductName", "Fred 2 Open"
VALUE "ProductVersion", "3.7.1"
VALUE "ProductVersion", "3.7.2"
END
END
BLOCK "VarFileInfo"
@@ -2349,7 +2353,7 @@ BEGIN
VERTGUIDE, 173
VERTGUIDE, 222
TOPMARGIN, 7
BOTTOMMARGIN, 393
BOTTOMMARGIN, 408
END
IDD_IGNORE_ORDERS, DIALOG
@@ -2694,7 +2698,7 @@ IDC_CURSOR2 CURSOR "res\\cursor2.cur"
STRINGTABLE
BEGIN
IDR_MAINFRAME "FRED2_OPEN 3.7.1 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
IDR_MAINFRAME "FRED2_OPEN 3.7.2 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
END
STRINGTABLE
-84
View File
@@ -79,7 +79,6 @@ BEGIN_MESSAGE_MAP(CFREDDoc, CDocument)
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences)
ON_COMMAND(ID_FILE_IMPORT_FSM, OnFileImportFSM)
ON_COMMAND(ID_FILE_IMPORT_WEAPONS, OnFileImportWeapons)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -1015,89 +1014,6 @@ void CFREDDoc::OnFileImportFSM()
recreate_dialogs();
}
void restore_default_weapons(char *ships_tbl);
void CFREDDoc::OnFileImportWeapons()
{
int rval;
CString ships_tbl_mfc;
char ships_tbl[MAX_PATH_LEN];
char *ships_tbl_text;
char *ships_tbl_text_raw;
char *ch;
char temp[MAX_PATH_LEN];
char error_str[1024];
// set up import dialog
CFileDialog dlg(TRUE, "tbl", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "FreeSpace Tables (*.tbl)|*.tbl|All files (*.*)|*.*||");
dlg.m_ofn.lpstrTitle = "Specify the ships.tbl with the required loadouts";
// set initial path
strcpy_s(temp, Fred_exe_dir);
if ((ch = stristr(temp, "FreeSpace2")) != NULL)
{
strcpy(ch, "FreeSpace\\Data\\Tables");
dlg.m_ofn.lpstrInitialDir = temp;
}
// get ships.tbl
if (dlg.DoModal() != IDOK)
return;
ships_tbl_mfc = dlg.GetPathName();
if (strlen(ships_tbl_mfc) > MAX_PATH_LEN - 1)
{
MessageBox(NULL, "Path name is too long", "Error", MB_OK);
return;
}
if (!strlen(ships_tbl_mfc))
return;
strcpy_s(ships_tbl, ships_tbl_mfc);
// allocate junk
ships_tbl_text = (char *) malloc(sizeof(char) * MISSION_TEXT_SIZE);
ships_tbl_text_raw = (char *) malloc(sizeof(char) * MISSION_TEXT_SIZE);
if (!ships_tbl_text || !ships_tbl_text_raw)
{
free(ships_tbl_text);
free(ships_tbl_text_raw);
Error(LOCATION, "Not enough memory to import weapons.");
return;
}
// open localization
lcl_ext_open();
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("FREDDOC: Unable to parse '%s'! Error code = %i.\n", ships_tbl, rval));
sprintf(error_str, "Could not parse file: %s", ships_tbl);
MessageBox(NULL, error_str, "Unable to import weapon loadouts!", MB_ICONERROR | MB_OK);
lcl_ext_close();
return;
}
// load the other table and convert, freeing memory after use
read_file_text(ships_tbl, CF_TYPE_ANY, ships_tbl_text, ships_tbl_text_raw);
free(ships_tbl_text_raw);
restore_default_weapons(ships_tbl_text);
free(ships_tbl_text);
// close localization
lcl_ext_close();
// we haven't saved it yet
set_modified(TRUE);
// error check and notify
if (!Fred_view_wnd->global_error_check())
Fred_view_wnd->MessageBox("Weapon loadouts successfully imported with no errors.", "Woohoo!");
}
void CFREDDoc::recreate_dialogs()
{
if(Briefing_dialog)
-1
View File
@@ -89,7 +89,6 @@ protected:
afx_msg void OnFileNew();
afx_msg void editor_init_mission();
afx_msg void OnFileImportFSM();
afx_msg void OnFileImportWeapons();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
+12 -3
View File
@@ -53,6 +53,7 @@
#include "graphics/font.h"
#include "cmdline/cmdline.h"
#include "iff_defs/iff_defs.h"
#include "mod_table/mod_table.h"
extern float flFrametime;
extern subsys_to_render Render_subsys;
@@ -141,7 +142,7 @@ color colour_yellow;
void fred_enable_htl()
{
if (!Briefing_dialog) gr_set_proj_matrix( (4.0f/9.0f) * PI * FRED_DEFAULT_HTL_FOV, gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
if (Briefing_dialog) gr_set_proj_matrix( (4.0f/9.0f) * PI * FRED_BRIEFING_HTL_FOV, gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
if (Briefing_dialog) gr_set_proj_matrix( Briefing_window_FOV, gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height, 1.0f, FRED_DEAFULT_HTL_DRAW_DIST);
gr_set_view_matrix(&Eye_position, &Eye_matrix);
}
@@ -1488,7 +1489,11 @@ void render_frame()
gr_set_font(FONT1);
light_reset();
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
if (Briefing_dialog) {
g3_set_view_matrix(&eye_pos, &eye_orient, Briefing_window_FOV);
} else {
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
}
Viewer_pos = eye_pos; // for starfield code
fred_enable_htl();
@@ -1593,7 +1598,11 @@ void render_frame()
gr_set_clip(0, 0, True_rw, True_rh);
g3_start_frame(0); // ** Accounted for
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
if (Briefing_dialog) {
g3_set_view_matrix(&eye_pos, &eye_orient, Briefing_window_FOV);
} else {
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
}
}
void game_do_frame()
+44 -2
View File
@@ -2688,6 +2688,46 @@ int CFREDView::global_error_check()
internal_error("Invalid dockee point (\"%s\" initially docked with \"%s\")", Ships[i].ship_name, Ships[ship].ship_name);
}
}
wing = Ships[i].wingnum;
bool is_in_loadout_screen = (ptr->type == OBJ_START);
if (!is_in_loadout_screen && wing >= 0) {
if ( multi && The_mission.game_type & MISSION_TYPE_MULTI_TEAMS )
{
for (n = 0; n < MAX_TVT_WINGS; n++) {
if (!strcmp(Wings[wing].name, TVT_wing_names[n])) {
is_in_loadout_screen = true;
break;
}
}
} else {
for (n = 0; n < MAX_STARTING_WINGS; n++) {
if (!strcmp(Wings[wing].name, Starting_wing_names[n])) {
is_in_loadout_screen = true;
break;
}
}
}
}
if (is_in_loadout_screen) {
int illegal = 0;
z = Ships[i].ship_info_index;
for (n = 0; n < MAX_SHIP_PRIMARY_BANKS; n++){
if (Ships[i].weapons.primary_bank_weapons[n] >= 0 && !Ship_info[z].allowed_weapons[Ships[i].weapons.primary_bank_weapons[n]]){
illegal++;
}
}
for (n = 0; n < MAX_SHIP_SECONDARY_BANKS; n++){
if (Ships[i].weapons.secondary_bank_weapons[n] >= 0 && !Ship_info[z].allowed_weapons[Ships[i].weapons.secondary_bank_weapons[n]]){
illegal++;
}
}
if (illegal && error("%d illegal weapon(s) found on ship \"%s\"", illegal, Ships[i].ship_name)) {
return 1;
}
}
}
}
@@ -3267,8 +3307,9 @@ int CFREDView::error(const char *msg, ...)
va_list args;
va_start(args, msg);
vsprintf(buf, msg, args);
vsnprintf(buf, sizeof(buf)-1, msg, args);
va_end(args);
buf[sizeof(buf)-1] = '\0';
g_err = 1;
if (MessageBox(buf, "Error", MB_OKCANCEL | MB_ICONEXCLAMATION) == IDOK)
@@ -3283,8 +3324,9 @@ int CFREDView::internal_error(const char *msg, ...)
va_list args;
va_start(args, msg);
vsprintf(buf, msg, args);
vsnprintf(buf, sizeof(buf)-1, msg, args);
va_end(args);
buf[sizeof(buf)-1] = '\0';
g_err = 1;
+1 -1
View File
@@ -540,7 +540,7 @@ void initial_status::OnOK()
if (m_team_color_setting.IsWindowEnabled() && m_team_color_setting.GetCurSel() > 0)
Ships[m_ship].team_name = Team_Names[m_team_color_setting.GetCurSel() - 1];
else
Ships[m_ship].team_name = "None";
Ships[m_ship].team_name = "none";
update_docking_info();
+12 -29
View File
@@ -64,6 +64,7 @@
#include "iff_defs/iff_defs.h"
#include "menuui/techmenu.h"
#include "missionui/fictionviewer.h"
#include "mod_table/mod_table.h"
#include <direct.h>
#include "cmdline/cmdline.h"
@@ -72,6 +73,8 @@
#define UNKNOWN_USER "Unknown"
extern void ssm_init(); // Need this to populate Ssm_info so OPF_SSM_CLASS does something. -MageKing17
int cur_wing = -1;
int cur_wing_index;
int cur_object_index = -1;
@@ -308,6 +311,9 @@ bool fred_init()
exit(1);
}
// Load game_settings.tbl
mod_table_init();
// initialize localization module. Make sure this is done AFTER initialzing OS.
// NOTE : Fred should ALWAYS run in English. Otherwise it might swap in another language
// when saving - which would cause inconsistencies when externalizing to tstrings.tbl via Exstr
@@ -393,9 +399,7 @@ bool fred_init()
hud_init_comm_orders(); // Goober5000
if (!new_alpha_colors_init()) {
old_alpha_colors_init();
}
alpha_colors_init();
gamesnd_parse_soundstbl(); // needs to be loaded after species stuff but before interface/weapon/ship stuff - taylor
mission_brief_common_init();
@@ -418,6 +422,7 @@ bool fred_init()
create_new_mission();
neb2_init(); // fullneb stuff
stars_init();
ssm_init(); // The game calls this after stars_init(), and we need Ssm_info initialized for OPF_SSM_CLASS. -MageKing17
brief_init_colors();
fred_preload_all_briefing_icons(); //phreak. This needs to be done or else the briefing icons won't show up
event_music_init();
@@ -496,8 +501,8 @@ void fix_ship_name(int ship)
int create_ship(matrix *orient, vec3d *pos, int ship_type)
{
// Save the Current Working dir to restore in a minute - fred is being stupid
char pwd[128];
getcwd(pwd, 128); // get the present working dir - probably <fs2path>[/modpapth]/data/missions/
char pwd[MAX_PATH_LEN];
getcwd(pwd, MAX_PATH_LEN); // get the present working dir - probably <fs2path>[/modpapth]/data/missions/
int obj, z1, z2;
@@ -927,8 +932,8 @@ void clear_mission()
event_music_reset_choices();
clear_texture_replacements();
// alternate ship type names
mission_parse_reset_alt();
mission_parse_reset_alt(); // alternate ship type names
mission_parse_reset_callsign();
strcpy(Cargo_names[0], "Nothing");
Num_cargo = 1;
@@ -1468,28 +1473,6 @@ int delete_ship_from_wing(int ship)
return 0;
}
// What does this do?
void add_ship_to_wing()
{
int org_object = cur_object_index;
vec3d tvec;
set_cur_object_index();
if (Objects[org_object].type == OBJ_NONE) {
vm_vec_make(&tvec, 10.0f, 10.0f, 10.0f);
create_object(&tvec);
} else {
Objects[cur_object_index] = Objects[org_object];
Objects[cur_object_index].pos.xyz.x += 3.0f;
Objects[cur_object_index].pos.xyz.y += 3.0f;
physics_init(&Objects[cur_object_index].phys_info);
Objects[cur_object_index].orient = Objects[org_object].orient;
}
set_modified();
}
// Return true if current object is valid and is in a wing.
// Else return false.
int query_object_in_wing(int obj)
-1
View File
@@ -90,7 +90,6 @@ void delete_marked();
void delete_reinforcement(int num);
int delete_ship_from_wing(int ship = cur_ship);
int find_free_wing();
void add_ship_to_wing();
int query_object_in_wing(int obj = cur_object_index);
void mark_object(int obj);
void unmark_object(int obj);
+8
View File
@@ -73,6 +73,7 @@ CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNo
m_no_autpilot = FALSE;
m_2d_mission = FALSE;
m_always_show_goals = FALSE;
m_end_to_mainhall = FALSE;
m_max_hull_repair_val = 0.0f;
m_max_subsys_repair_val = 100.0f;
m_contrail_threshold = CONTRAIL_THRESHOLD_DEFAULT;
@@ -124,6 +125,7 @@ void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_2D_MISSION, m_2d_mission);
DDX_Check(pDX, IDC_DEACTIVATE_AUTOPILOT, m_no_autpilot);
DDX_Check(pDX, IDC_ALWAYS_SHOW_GOALS, m_always_show_goals);
DDX_Check(pDX, IDC_END_TO_MAINHALL, m_end_to_mainhall);
DDX_Text(pDX, IDC_MAX_HULL_REPAIR_VAL, m_max_hull_repair_val);
DDV_MinMaxFloat(pDX, m_max_hull_repair_val, 0, 100);
DDX_Text(pDX, IDC_MAX_SUBSYS_REPAIR_VAL, m_max_subsys_repair_val);
@@ -356,6 +358,12 @@ void CMissionNotesDlg::OnOK()
The_mission.flags &= ~MISSION_FLAG_ALWAYS_SHOW_GOALS;
}
if ( m_end_to_mainhall ) {
The_mission.flags |= MISSION_FLAG_END_TO_MAINHALL;
} else {
The_mission.flags &= ~MISSION_FLAG_END_TO_MAINHALL;
}
if ( flags != The_mission.flags ){
set_modified();
}
+1
View File
@@ -64,6 +64,7 @@ public:
BOOL m_no_autpilot;
BOOL m_2d_mission;
BOOL m_always_show_goals;
BOOL m_end_to_mainhall;
float m_max_hull_repair_val;
float m_max_subsys_repair_val;
BOOL m_contrail_threshold_flag;
+103 -62
View File
@@ -133,10 +133,10 @@ int CFred_mission_save::save_mission_file(char *pathname)
err = -3;
// else if (save_briefing_info())
// err = -4;
else if (save_fiction())
err = -3;
else if (save_cutscenes())
err = -4;
else if (save_fiction())
err = -3;
else if (save_cmd_briefs())
err = -4;
else if (save_briefing())
@@ -384,13 +384,13 @@ int CFred_mission_save::save_mission_info()
fout(" %d", The_mission.num_respawns);
if ( Format_fs2_open != FSO_FORMAT_RETAIL ) {
fso_comment_push(";;FSO 3.6.11;;");
if (optional_string_fred("+Max Respawn Time:"))
parse_comments(2);
else {
fso_comment_push(";;FSO 3.6.11;;");
fout_version("\n+Max Respawn Time:");
fso_comment_pop();
}
fso_comment_pop();
fout(" %d", The_mission.max_respawn_delay);
}
@@ -561,29 +561,29 @@ int CFred_mission_save::save_mission_info()
if (period != NULL)
*period = 0;
fso_comment_push(";;FSO 3.6.0;;");
if (optional_string_fred("$Skybox Model:")) {
parse_comments(2);
fout(" %s.pof", out_str);
} else {
fso_comment_push(";;FSO 3.6.0;;");
fout_version("\n\n$Skybox Model: %s.pof", out_str);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.0;; $Skybox Model:");
}
// orientation?
if ((strlen(The_mission.skybox_model) > 0) && !vm_matrix_same(&vmd_identity_matrix, &The_mission.skybox_orientation)) {
fso_comment_push(";;FSO 3.6.14;;");
if (optional_string_fred("+Skybox Orientation:")) {
parse_comments(1);
save_matrix(The_mission.skybox_orientation);
} else {
fso_comment_push(";;FSO 3.6.14;;");
fout_version("\n+Skybox Orientation:");
save_matrix(The_mission.skybox_orientation);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.14;; +Skybox Orientation:");
}
@@ -591,14 +591,14 @@ int CFred_mission_save::save_mission_info()
// are skybox flags in use?
if (The_mission.skybox_flags != DEFAULT_NMODEL_FLAGS) {
//char out_str[4096];
fso_comment_push(";;FSO 3.6.11;;");
if (optional_string_fred("+Skybox Flags:")) {
parse_comments(1);
fout( " %d", The_mission.skybox_flags);
} else {
fso_comment_push(";;FSO 3.6.11;;");
fout_version("\n+Skybox Flags: %d", The_mission.skybox_flags);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.11;; +Skybox Flags:");
}
@@ -607,14 +607,14 @@ int CFred_mission_save::save_mission_info()
int profile_index = (The_mission.ai_profile - Ai_profiles);
Assert(profile_index >= 0 && profile_index < MAX_AI_PROFILES);
fso_comment_push(";;FSO 3.6.9;;");
if (optional_string_fred("$AI Profile:")) {
parse_comments(2);
fout(" %s", The_mission.ai_profile->profile_name);
} else {
fso_comment_push(";;FSO 3.6.9;;");
fout_version("\n\n$AI Profile: %s", The_mission.ai_profile->profile_name);
fso_comment_pop();
}
fso_comment_pop();
// sound environment (EFX/EAX) - taylor
sound_env *m_env = &The_mission.sound_environment;
@@ -714,7 +714,7 @@ int CFred_mission_save::save_cutscenes()
}
for (uint i = 0; i < The_mission.cutscenes.size(); i++) {
if ( strlen(The_mission.cutscenes[i].cutscene_name) ) {
if ( strlen(The_mission.cutscenes[i].filename) ) {
// determine the name of this cutscene type
switch (The_mission.cutscenes[i].type) {
case MOVIE_PRE_FICTION:
@@ -742,10 +742,10 @@ int CFred_mission_save::save_cutscenes()
if (optional_string_fred(type)) {
parse_comments();
fout(" %s", The_mission.cutscenes[i].cutscene_name);
fout(" %s", The_mission.cutscenes[i].filename);
}
else {
fout_version("%s %s\n", type, The_mission.cutscenes[i].cutscene_name);
fout_version("%s %s\n", type, The_mission.cutscenes[i].filename);
}
required_string_fred("+formula:");
@@ -795,6 +795,18 @@ int CFred_mission_save::save_fiction()
}
else
optional_string_fred("$Font:");
// save voice
if (strlen(fiction_voice()) > 0) //-V805
{
if (optional_string_fred("$Voice:"))
parse_comments();
else
fout("\n$Voice:");
fout(" %s", fiction_voice());
}
else
optional_string_fred("$Voice:");
}
else
{
@@ -1172,6 +1184,13 @@ int CFred_mission_save::save_players()
int var_idx;
int used_pool[MAX_WEAPON_TYPES];
if (optional_string_fred("#Alternate Types:")) { // Make sure the parser doesn't get out of sync
required_string_fred("#end");
}
if (optional_string_fred("#Callsigns:")) {
required_string_fred("#end");
}
// write out alternate name list
if(Mission_alt_type_count > 0){
fout("\n\n#Alternate Types:\n");
@@ -1730,6 +1749,8 @@ int CFred_mission_save::save_objects()
fout(" \"weapons-locked\"");
if (shipp->flags2 & SF2_SCRAMBLE_MESSAGES)
fout(" \"scramble-messages\"");
if (!(objp->flags & OF_COLLIDES))
fout(" \"no-collide\"");
fout(" )");
}
// -----------------------------------------------------------
@@ -1749,6 +1770,7 @@ int CFred_mission_save::save_objects()
// special explosions
if (Format_fs2_open != FSO_FORMAT_RETAIL) {
if (shipp->use_special_explosion) {
fso_comment_push(";;FSO 3.6.13;;");
if (optional_string_fred("$Special Explosion:", "$Name:")) {
parse_comments();
@@ -1774,7 +1796,7 @@ int CFred_mission_save::save_objects()
fout(" %d", shipp->special_exp_shockwave_speed);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:");
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:", "$Name:");
}
if (shipp->special_exp_deathroll_time > 0) {
@@ -1783,11 +1805,10 @@ int CFred_mission_save::save_objects()
fout(" %d", shipp->special_exp_deathroll_time);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Exp Death Roll Time:");
bypass_comment(";;FSO 3.6.13;; +Special Exp Death Roll Time:", "$Name:");
}
}
else {
fso_comment_push(";;FSO 3.6.13;;");
fout_version("\n$Special Explosion:");
fout_version("\n+Special Exp Damage:");
@@ -1812,12 +1833,12 @@ int CFred_mission_save::save_objects()
fout(" %d", shipp->special_exp_deathroll_time);
}
fso_comment_pop();
}
fso_comment_pop();
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:");
bypass_comment(";;FSO 3.6.13;; +Special Exp Death Roll Time:");
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:", "$Name:");
bypass_comment(";;FSO 3.6.13;; +Special Exp Death Roll Time:", "$Name:");
}
}
// retail format special explosions
@@ -1845,33 +1866,33 @@ int CFred_mission_save::save_objects()
if (Format_fs2_open != FSO_FORMAT_RETAIL)
{
if (shipp->special_hitpoints) {
fso_comment_push(";;FSO 3.6.13;;");
if (optional_string_fred("+Special Hitpoints:", "$Name:")) {
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.13;;");
fout_version("\n+Special Hitpoints:");
fso_comment_pop();
}
fso_comment_pop();
fout(" %d", shipp->special_hitpoints);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Hitpoints:");
bypass_comment(";;FSO 3.6.13;; +Special Hitpoints:", "$Name:");
}
if (shipp->special_shield >= 0) {
fso_comment_push(";;FSO 3.6.13;;");
if (optional_string_fred("+Special Shield Points:", "$Name:")) {
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.13;;");
fout_version("\n+Special Shield Points:");
fso_comment_pop();
}
fso_comment_pop();
fout(" %d", shipp->special_shield);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Shield Points:");
bypass_comment(";;FSO 3.6.13;; +Special Shield Points:", "$Name:");
}
}
// -----------------------------------------------------------
@@ -1970,16 +1991,16 @@ int CFred_mission_save::save_objects()
// always write out the score to ensure backwards compatibility. If the score is the same as the value
// in the table write out a flag to tell the game to simply use whatever is in the table instead
if (Ship_info[shipp->ship_info_index].score == shipp->score ) {
fso_comment_push(";;FSO 3.6.10;;");
if ( optional_string_fred("+Use Table Score:", "$Name:") ) {
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.10;;");
fout_version("\n+Use Table Score:");
fso_comment_pop();
}
fso_comment_pop();
}
else {
bypass_comment(";;FSO 3.6.10;; +Use Table Score:");
bypass_comment(";;FSO 3.6.10;; +Use Table Score:", "$Name:");
}
if (optional_string_fred("+Score:", "$Name:"))
@@ -1991,18 +2012,18 @@ int CFred_mission_save::save_objects()
if (Format_fs2_open != FSO_FORMAT_RETAIL && shipp->assist_score_pct != 0) {
fso_comment_push(";;FSO 3.6.10;;");
if ( optional_string_fred("+Assist Score Percentage:") ) {
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.10;;");
fout_version("\n+Assist Score Percentage:");
fso_comment_pop();
}
fso_comment_pop();
fout(" %f", shipp->assist_score_pct);
}
else {
bypass_comment(";;FSO 3.6.10;; +Assist Score Percentage:");
bypass_comment(";;FSO 3.6.10;; +Assist Score Percentage:", "$Name:");
}
// deal with the persona for this ship as well.
@@ -2018,6 +2039,7 @@ int CFred_mission_save::save_objects()
// Goober5000 - deal with texture replacement ----------------
if (!Fred_texture_replacements.empty()) {
bool needs_header = true;
fso_comment_push(";;FSO 3.6.8;;");
for (SCP_vector<texture_replace>::iterator ii = Fred_texture_replacements.begin(); ii != Fred_texture_replacements.end(); ++ii) {
if ( !stricmp(shipp->ship_name, ii->ship_name) ) {
@@ -2025,7 +2047,6 @@ int CFred_mission_save::save_objects()
if (optional_string_fred("$Texture Replace:")) {
parse_comments(1);
} else {
fso_comment_push(";;FSO 3.6.8;;");
fout_version("\n$Texture Replace:");
}
@@ -2051,7 +2072,7 @@ int CFred_mission_save::save_objects()
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.8;; $Texture Replace:");
bypass_comment(";;FSO 3.6.8;; $Texture Replace:", "$Name:");
}
// end of texture replacement -------------------------------
@@ -2772,11 +2793,16 @@ int CFred_mission_save::save_matrix(matrix &m)
// Goober5000 - move past the comment without copying it to the output file
// (used for special FSO comment tags)
void CFred_mission_save::bypass_comment(char *comment)
void CFred_mission_save::bypass_comment(const char *comment, const char *end)
{
char *ch = strstr(raw_ptr, comment);
if (ch != NULL)
{
if (end != NULL) {
char *ep = strstr(raw_ptr, end);
if (ep != NULL && ep < ch)
return;
}
char *writep = ch;
char *readp = strchr(writep, '\n');
@@ -2798,6 +2824,7 @@ void CFred_mission_save::parse_comments(int newlines)
{
char *comment_start = NULL;
int state = 0, same_line = 0, first_comment = 1, tab = 0, flag = 0;
bool version_added = false;
if (newlines < 0) {
newlines = -newlines;
@@ -2811,12 +2838,13 @@ void CFred_mission_save::parse_comments(int newlines)
while (newlines-- > 0)
fout("\n");
if (tab)
if (tab && token_found)
fout_version("\t%s", token_found);
else if (token_found)
fout_version("%s", token_found);
else if (tab)
fout("\t");
if (token_found)
fout("%s", token_found);
return;
}
@@ -2829,12 +2857,19 @@ void CFred_mission_save::parse_comments(int newlines)
fout("\n");
if (tab) {
fout("\t");
fout_version("\t");
fout("%s", token_found);
} else {
fout("%s", token_found);
fout_version("%s", token_found);
}
// If you have a bunch of lines that all start with the same token (like, say, "+Subsystem:"),
// this makes it so it won't just repeatedly match the first one. -MageKing17
raw_ptr++;
if (version_added)
fso_comment_pop();
return;
}
@@ -2858,9 +2893,9 @@ void CFred_mission_save::parse_comments(int newlines)
s_num = 3;
}
if ( (s_num == 3) && (major <= FS_VERSION_MAJOR) && (minor <= FS_VERSION_MINOR) && (build <= FS_VERSION_BUILD) ) {
if ( (s_num == 3) && ((major < FS_VERSION_MAJOR) || ((major == FS_VERSION_MAJOR) && ((minor < FS_VERSION_MINOR) || ((minor == FS_VERSION_MINOR) && (build <= FS_VERSION_BUILD))))) ) {
state = 3;
} else if ( (s_num == 4) && (major <= FS_VERSION_MAJOR) && (minor <= FS_VERSION_MINOR) && (build <= FS_VERSION_BUILD) && (revis <= FS_VERSION_REVIS) ) {
} else if ( (s_num == 4) && ((major < FS_VERSION_MAJOR) || ((major == FS_VERSION_MAJOR) && ((minor < FS_VERSION_MINOR) || ((minor == FS_VERSION_MINOR) && ((build < FS_VERSION_BUILD) || ((build == FS_VERSION_BUILD) && (revis <= FS_VERSION_REVIS))))))) ) {
state = 3;
} else {
state = 4;
@@ -2926,7 +2961,10 @@ void CFred_mission_save::parse_comments(int newlines)
if ( (*raw_ptr == ';') && (raw_ptr[1] == ';') && (state == 3) ) {
state = raw_ptr[2];
raw_ptr[2] = 0;
fso_comment_pop();
if (version_added)
fso_comment_pop();
else
version_added = true;
fso_comment_push(comment_start);
raw_ptr[2] = (char)state;
state = first_comment = flag = 0;
@@ -2937,6 +2975,9 @@ void CFred_mission_save::parse_comments(int newlines)
raw_ptr++;
}
if (version_added)
fso_comment_pop();
return;
}
@@ -3339,13 +3380,13 @@ int CFred_mission_save::save_events()
}
if (Format_fs2_open != FSO_FORMAT_RETAIL && Mission_events[i].trigger_count != 1 ) {
fso_comment_push(";;FSO 3.6.11;;");
if ( optional_string_fred("+Trigger Count:", "$Formula:")){
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.11;;");
fout_version("\n+Trigger Count:");
fso_comment_pop();
}
fso_comment_pop();
fout(" %d", Mission_events[i].trigger_count);
}
@@ -3410,13 +3451,13 @@ int CFred_mission_save::save_events()
}
if (Format_fs2_open != FSO_FORMAT_RETAIL && Mission_events[i].mission_log_flags != 0 ) {
fso_comment_push(";;FSO 3.6.11;;");
if ( optional_string_fred("+Event Log Flags: (", "$Formula:")){
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.11;;");
fout_version("\n+Event Log Flags: (");
fso_comment_pop();
}
fso_comment_pop();
for (j = 0; j < MAX_MISSION_EVENT_LOG_FLAGS ; j++) {
add_flag = 1 << j;
@@ -3566,10 +3607,10 @@ int CFred_mission_save::save_bitmaps()
bool tag = (i < Num_backgrounds - 1);
background_t *background = &Backgrounds[i];
fso_comment_push(";;FSO 3.6.9;;");
if (optional_string_fred("$Bitmap List:")) {
parse_comments(2);
} else {
fso_comment_push(";;FSO 3.6.9;;");
fout_version("\n\n$Bitmap List:");
}
@@ -3635,14 +3676,14 @@ int CFred_mission_save::save_bitmaps()
// taylor's environment map thingy
if (strlen(The_mission.envmap_name) > 0) { //-V805
fso_comment_push(";;FSO 3.6.9;;");
if (optional_string_fred("$Environment Map:")) {
parse_comments(2);
fout(" %s", The_mission.envmap_name);
} else {
fso_comment_push(";;FSO 3.6.9;;");
fout_version("\n\n$Environment Map: %s", The_mission.envmap_name);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.9;; $Environment Map:");
}
@@ -3761,14 +3802,14 @@ int CFred_mission_save::save_music()
// Goober5000 - save using the special comment prefix
if (stricmp(The_mission.substitute_event_music_name, "None")) {
fso_comment_push(";;FSO 3.6.9;;");
if (optional_string_fred("$Substitute Event Music:")) {
parse_comments(1);
fout(" %s", The_mission.substitute_event_music_name);
} else {
fso_comment_push(";;FSO 3.6.9;;");
fout_version("\n$Substitute Event Music: %s", The_mission.substitute_event_music_name);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.9;; $Substitute Event Music:");
}
@@ -3782,14 +3823,14 @@ int CFred_mission_save::save_music()
// Goober5000 - save using the special comment prefix
if (stricmp(The_mission.substitute_briefing_music_name, "None")) {
fso_comment_push(";;FSO 3.6.9;;");
if (optional_string_fred("$Substitute Briefing Music:")) {
parse_comments(1);
fout(" %s", The_mission.substitute_briefing_music_name);
} else {
fso_comment_push(";;FSO 3.6.9;;");
fout_version("\n$Substitute Briefing Music: %s", The_mission.substitute_briefing_music_name);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.9;; $Substitute Briefing Music:");
}
@@ -3825,14 +3866,14 @@ int CFred_mission_save::save_music()
// Goober5000 - save using the special comment prefix
if (mission_has_fiction() && Mission_music[SCORE_FICTION_VIEWER] >= 0) {
fso_comment_push(";;FSO 3.6.11;;");
if (optional_string_fred("$Fiction Viewer Music:")) {
parse_comments(1);
fout(" %s", Spooled_music[Mission_music[SCORE_FICTION_VIEWER]].name);
} else {
fso_comment_push(";;FSO 3.6.11;;");
fout_version("\n$Fiction Viewer Music: %s", Spooled_music[Mission_music[SCORE_FICTION_VIEWER]].name);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.11;; $Fiction Viewer Music:");
}
@@ -4029,14 +4070,14 @@ int CFred_mission_save::save_campaign_file(char *pathname)
}
if ( Campaign.missions[m].debrief_persona_index > 0 ) {
fso_comment_push(";;FSO 3.6.8;;");
if (optional_string_fred("+Debriefing Persona Index:")) {
parse_comments(1);
fout(" %d", Campaign.missions[m].debrief_persona_index);
} else {
fso_comment_push(";;FSO 3.6.8;;");
fout_version("\n+Debriefing Persona Index: %d", Campaign.missions[m].debrief_persona_index);
fso_comment_pop();
}
fso_comment_pop();
} else {
bypass_comment(";;FSO 3.6.8;; +Debriefing Persona Index:");
}
@@ -4215,10 +4256,10 @@ void CFred_mission_save::fso_comment_push(char *ver)
elem1 = elem2 = 3;
}
if ( (elem1 == 3) && ((major > in_major) || (minor > in_minor) || (build > in_build)) ) {
if ( (elem1 == 3) && ((major > in_major) || ((major == in_major) && ((minor > in_minor) || ((minor == in_minor) && (build > in_build))))) ) {
// the push'd version is older than our current version, so just push a copy of the previous version
fso_ver_comment.push_back( before );
} else if ( (elem1 == 4) && ((major > in_major) || (minor > in_minor) || (build > in_build) || (revis > in_revis)) ) {
} else if ( (elem1 == 4) && ((major > in_major) || ((major == in_major) && ((minor > in_minor) || ((minor == in_minor) && ((build > in_build) || ((build == in_build) || (revis > in_revis))))))) ) {
// the push'd version is older than our current version, so just push a copy of the previous version
fso_ver_comment.push_back( before );
} else {
+1 -1
View File
@@ -80,7 +80,7 @@ public:
void fso_comment_pop(bool pop_all = false);
// Goober5000
void bypass_comment(char *comment);
void bypass_comment(const char *comment, const char *end = NULL);
};
#endif
+2
View File
@@ -65,7 +65,9 @@ BEGIN_MESSAGE_MAP(player_start_editor, CDialog)
//{{AFX_MSG_MAP(player_start_editor)
ON_WM_INITMENU()
ON_LBN_SELCHANGE(IDC_SHIP_LIST, OnSelchangeShipList)
ON_CLBN_CHKCHANGE(IDC_SHIP_LIST, OnSelchangeShipList)
ON_LBN_SELCHANGE(IDC_WEAPON_LIST, OnSelchangeWeaponList)
ON_CLBN_CHKCHANGE(IDC_SHIP_LIST, OnSelchangeWeaponList)
ON_EN_UPDATE(IDC_SHIP_POOL, OnUpdateShipPool)
ON_EN_UPDATE(IDC_WEAPON_POOL, OnUpdateWeaponPool)
ON_LBN_SELCHANGE(IDC_SHIP_VARIABLES_LIST, OnSelchangeShipVariablesList)
+7 -2
View File
@@ -1060,6 +1060,8 @@
#define IDC_2D_MISSION2 1549
#define IDC_ALWAYS_SHOW_GOALS 1549
#define IDC_LABEL2 1550
#define IDC_ALWAYS_SHOW_GOALS2 1550
#define IDC_END_TO_MAINHALL 1550
#define IDC_NEW_TEXTURE 1551
#define IDC_TEXTURES 1552
#define IDC_OLD_TEXTURE_LIST 1553
@@ -1115,6 +1117,7 @@
#define IDC_USE_WING_ICON 1579
#define IDC_DISABLE_BUILTIN_COMMAND_MSGS 1580
#define IDC_LBL_OTHER_SUFFIX 1580
#define IDC_USE_CARGO_ICON 1580
#define IDC_PRIMARIES_LOCKED 1581
#define IDC_EXPORT 1581
#define IDC_SECONDARIES_LOCKED 1582
@@ -1151,6 +1154,8 @@
#define IDC_FONT_FILE 1619
#define IDC_FICTION_MUSIC 1620
#define IDC_SOUND_ENVIRONMENT_LABEL 1621
#define IDC_FONT_FILE2 1621
#define IDC_VOICE_FILE 1621
#define IDC_SOUND_ENVIRONMENT_VOLUME_LABEL 1622
#define IDC_SOUND_ENVIRONENT_DAMPING_LABEL 1623
#define IDC_SOUND_ENVIRONMENT_DECAY_LABEL 1624
@@ -1174,6 +1179,7 @@
#define IDC_MISSION_LOG_LAST_REPEAT 1640
#define IDC_MISSION_LOG_1ST_TRIGGER 1641
#define IDC_MISSION_LOG_LAST_TRIGGER 1642
#define IDC_NO_COLLIDE 1643
#define ID_FILE_MISSIONNOTES 32771
#define ID_DUPLICATE 32774
#define ID_VIEW_ROTATE 32775
@@ -1438,7 +1444,6 @@
#define ID_FORMAT_FS1_RETAIL 33072
#define ID_EDITORS_SET_GLOBAL_SHIP_FLAGS 33073
#define ID_FILE_IMPORT_FSM 33074
#define ID_FILE_IMPORT_WEAPONS 33075
#define ID_VIEW_LIGHTING 33079
#define ID_EDITORS_VOICE 33080
#define ID_SHOW_IFF_0 33081
@@ -1467,7 +1472,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 320
#define _APS_NEXT_COMMAND_VALUE 33098
#define _APS_NEXT_CONTROL_VALUE 1643
#define _APS_NEXT_CONTROL_VALUE 1644
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif
+86 -39
View File
@@ -719,6 +719,12 @@ void sexp_tree::right_clicked(int mode)
type = tree_nodes[first_arg].type;
}
}
// Goober5000 - certain types accept both integers and a list of strings
if (op_type == OPF_GAME_SND || op_type == OPF_WEAPON_BANK_NUMBER)
{
type = SEXPT_NUMBER | SEXPT_STRING;
}
if ( (type & SEXPT_STRING) || (type & SEXPT_NUMBER) ) {
@@ -741,7 +747,8 @@ void sexp_tree::right_clicked(int mode)
if ( Sexp_variables[idx].type & SEXP_VARIABLE_STRING ) {
flag &= ~MF_GRAYED;
}
} else if ( type & SEXPT_NUMBER ) {
}
if ( type & SEXPT_NUMBER ) {
if ( Sexp_variables[idx].type & SEXP_VARIABLE_NUMBER ) {
flag &= ~MF_GRAYED;
}
@@ -1099,15 +1106,20 @@ void sexp_tree::right_clicked(int mode)
} else if (type == OPF_NULL) { // takes operator that doesn't return a value
replace_type = OPR_NULL;
// Goober5000
} else if (type == OPF_FLEXIBLE_ARGUMENT) {
replace_type = OPR_FLEXIBLE_ARGUMENT;
} else if (type == OPF_AI_GOAL) {
replace_type = OPR_AI_GOAL;
}
// Goober5000
else if (type == OPF_FLEXIBLE_ARGUMENT) {
replace_type = OPR_FLEXIBLE_ARGUMENT;
}
// Goober5000
else if (type == OPF_GAME_SND || type == OPF_WEAPON_BANK_NUMBER) {
// enable number even though we are also going to default to string
menu.EnableMenuItem(ID_REPLACE_NUMBER, MF_ENABLED);
}
// default to string
if (replace_type == OPR_STRING) {
menu.EnableMenuItem(ID_REPLACE_STRING, MF_ENABLED);
@@ -2203,7 +2215,8 @@ int sexp_tree::add_default_operator(int op, int argnum)
(argnum == 1 && Operators[op].value == OP_INT_TO_STRING) ||
(argnum == 3 && Operators[op].value == OP_STRING_GET_SUBSTRING) ||
(argnum == 4 && Operators[op].value == OP_STRING_SET_SUBSTRING) ||
(argnum == 1 && Operators[op].value == OP_COPY_VARIABLE_FROM_INDEX))
(argnum == 1 && Operators[op].value == OP_COPY_VARIABLE_FROM_INDEX) ||
(argnum == 1 && Operators[op].value == OP_SCRIPT_EVAL_STRING))
{
int sexp_var_index = get_index_sexp_variable_name(item.text);
@@ -2319,9 +2332,6 @@ int sexp_tree::get_default_value(sexp_list_item *item, char *text_buf, int op, i
case 7:
temp = 100;
break;
case 10:
temp = SND_SHIP_EXPLODE_1;
break;
case 11:
temp = (int)EMP_DEFAULT_INTENSITY;
break;
@@ -2350,12 +2360,6 @@ int sexp_tree::get_default_value(sexp_list_item *item, char *text_buf, int op, i
case 7:
temp = 10;
break;
case 8:
temp = SND_CAPITAL_WARP_IN;
break;
case 9:
temp = SND_CAPITAL_WARP_OUT;
break;
default:
temp = 0;
break;
@@ -2418,6 +2422,32 @@ int sexp_tree::get_default_value(sexp_list_item *item, char *text_buf, int op, i
}
return 0;
// Goober5000 - special cases that used to be numbers but are now hybrids
case OPF_GAME_SND:
int sound_index = -1;
if ( (Operators[op].value == OP_EXPLOSION_EFFECT) )
{
sound_index = SND_SHIP_EXPLODE_1;
}
else if ( (Operators[op].value == OP_WARP_EFFECT) )
{
sound_index = (i == 8) ? SND_CAPITAL_WARP_IN : SND_CAPITAL_WARP_OUT;
}
if (sound_index >= 0)
{
game_snd *snd = &Snds[sound_index];
if (can_construe_as_integer(snd->name.c_str()))
item->set_data(snd->name.c_str(), (SEXPT_NUMBER | SEXPT_VALID));
else
item->set_data(snd->name.c_str(), (SEXPT_STRING | SEXPT_VALID));
return 0;
}
// if no hardcoded default, just use the listing default
break;
}
list = get_listing_opf(type, index, i);
@@ -2634,6 +2664,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
case OPF_FLEXIBLE_ARGUMENT:
case OPF_ANYTHING:
case OPF_SKYBOX_MODEL_NAME:
case OPF_SKYBOX_FLAGS:
case OPF_SHIP_OR_NONE:
case OPF_SUBSYSTEM_OR_NONE:
case OPF_SHIP_WING_POINT_OR_NONE:
@@ -2660,6 +2691,9 @@ int sexp_tree::query_default_argument_available(int op, int i)
case OPF_ANIMATION_TYPE:
case OPF_SHIP_FLAG:
case OPF_NEBULA_PATTERN:
case OPF_NAV_POINT:
case OPF_TEAM_COLOR:
case OPF_GAME_SND:
return 1;
case OPF_SHIP:
@@ -2698,10 +2732,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
return 0;
case OPF_PERSONA:
if (Num_personas)
return 1;
return 0;
return (Num_personas > 0) ? 1 : 0;
case OPF_POINT:
case OPF_WAYPOINT_PATH:
@@ -2763,29 +2794,13 @@ int sexp_tree::query_default_argument_available(int op, int i)
return 0;
case OPF_VARIABLE_NAME:
if (sexp_variable_count() > 0) {
return 1;
} else {
return 0;
}
case OPF_NAV_POINT:
return 1;
return (sexp_variable_count() > 0) ? 1 : 0;
case OPF_SSM_CLASS:
if (Ssm_info_count > 0)
return 1;
else
return 0;
return (Ssm_info_count > 0) ? 1 : 0;
case OPF_MISSION_MOOD:
if (Builtin_moods.empty())
return 0;
else
return 1;
case OPF_TEAM_COLOR:
return 1;
return Builtin_moods.empty() ? 0 : 1;
default:
Int3();
@@ -4347,6 +4362,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
list = get_listing_opf_skybox_model();
break;
case OPF_SKYBOX_FLAGS:
list = get_listing_opf_skybox_flags();
break;
case OPF_BACKGROUND_BITMAP:
list = get_listing_opf_background_bitmap();
break;
@@ -4447,6 +4466,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
list = get_listing_opf_nebula_patterns();
break;
case OPF_GAME_SND:
list = get_listing_opf_game_snds();
break;
default:
Int3(); // unknown OPF code
list = NULL;
@@ -5791,6 +5814,17 @@ sexp_list_item *sexp_tree::get_listing_opf_skybox_model()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_skybox_flags()
{
sexp_list_item head;
int i;
for (i = 0; i < Num_skybox_flags; ++i) {
head.add_data(Skybox_flags[i]);
}
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_background_bitmap()
{
sexp_list_item head;
@@ -5987,7 +6021,20 @@ sexp_list_item *sexp_tree::get_listing_opf_nebula_patterns()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_game_snds()
{
sexp_list_item head;
head.add_data(SEXP_NONE_STRING);
for (SCP_vector<game_snd>::iterator iter = Snds.begin(); iter != Snds.end(); ++iter) {
if (!can_construe_as_integer(iter->name.c_str())) {
head.add_data(iter->name.c_str());
}
}
return head.next;
}
// Deletes sexp_variable from sexp_tree.
// resets tree to not include given variable, and resets text and type
+2
View File
@@ -236,6 +236,7 @@ public:
sexp_list_item *get_listing_opf_variable_names();
sexp_list_item *get_listing_opf_variable_type();
sexp_list_item *get_listing_opf_skybox_model();
sexp_list_item *get_listing_opf_skybox_flags();
sexp_list_item *get_listing_opf_background_bitmap();
sexp_list_item *get_listing_opf_sun_bitmap();
sexp_list_item *get_listing_opf_nebula_storm_type();
@@ -275,6 +276,7 @@ public:
sexp_list_item *get_listing_opf_ship_flags();
sexp_list_item *get_listing_opf_team_colors();
sexp_list_item *get_listing_opf_nebula_patterns();
sexp_list_item *get_listing_opf_game_snds();
int m_mode;
int item_index;
+16 -24
View File
@@ -2037,7 +2037,7 @@ void CShipEditorDlg::OnSpecialExp()
// alternate ship name stuff
void CShipEditorDlg::ship_alt_name_init(int base_ship)
{
int idx;
int idx, sel_idx;
CComboBox *ptr = (CComboBox*)GetDlgItem(IDC_SHIP_ALT);
if(ptr == NULL){
Int3();
@@ -2054,21 +2054,17 @@ void CShipEditorDlg::ship_alt_name_init(int base_ship)
// reset the combobox and add all relevant strings
ptr->ResetContent();
ptr->AddString("<none>");
sel_idx = (base_ship < 0 || !strlen(Fred_alt_names[base_ship])) ? -1 : -2;
for(idx=0; idx<Mission_alt_type_count; idx++){
ptr->AddString(Mission_alt_types[idx]);
if (sel_idx == -2 && !strcmp(Mission_alt_types[idx], Fred_alt_names[base_ship])) {
sel_idx = idx;
}
}
Assertion(sel_idx >= -1, "Alt name exists but can't be found in Mission_alt_types; get a coder!\n");
// "none"
if(base_ship < 0){
ptr->SetCurSel(0);
}
// otherwise look his stuff up
if(strlen(Fred_alt_names[base_ship])){
ptr->SelectString(0, Fred_alt_names[base_ship]);
} else {
ptr->SetCurSel(0);
}
sel_idx += 1;
ptr->SetCurSel(sel_idx);
}
void CShipEditorDlg::ship_alt_name_close(int base_ship)
@@ -2137,7 +2133,7 @@ void CShipEditorDlg::ship_alt_name_close(int base_ship)
// callsign stuff
void CShipEditorDlg::ship_callsign_init(int base_ship)
{
int idx;
int idx, sel_idx;
CComboBox *ptr = (CComboBox*)GetDlgItem(IDC_SHIP_CALLSIGN);
if(ptr == NULL){
Int3();
@@ -2154,21 +2150,17 @@ void CShipEditorDlg::ship_callsign_init(int base_ship)
// reset the combobox and add all relevant strings
ptr->ResetContent();
ptr->AddString("<none>");
sel_idx = (base_ship < 0 || !strlen(Fred_callsigns[base_ship])) ? -1 : -2;
for(idx=0; idx<Mission_callsign_count; idx++){
ptr->AddString(Mission_callsigns[idx]);
if (sel_idx == -2 && !strcmp(Mission_callsigns[idx], Fred_callsigns[base_ship])) {
sel_idx = idx;
}
}
Assertion(sel_idx >= -1, "Callsign exists but can't be found in Mission_callsigns; get a coder!\n");
// "none"
if(base_ship < 0){
ptr->SetCurSel(0);
}
// otherwise look his stuff up
if(strlen(Fred_callsigns[base_ship])){
ptr->SelectString(0, Fred_callsigns[base_ship]);
} else {
ptr->SetCurSel(0);
}
sel_idx += 1;
ptr->SetCurSel(sel_idx);
}
void CShipEditorDlg::ship_callsign_close(int base_ship)
+31 -1
View File
@@ -74,6 +74,7 @@ void ship_flags_dlg::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_HIDE_SHIP_NAME, m_hide_ship_name);
DDX_Control(pDX, IDC_DISABLE_ETS, m_disable_ets);
DDX_Control(pDX, IDC_CLOAKED, m_cloaked);
DDX_Control(pDX, IDC_NO_COLLIDE, m_no_collide);
DDX_Control(pDX, IDC_SET_CLASS_DYNAMICALLY, m_set_class_dynamically);
DDX_Control(pDX, IDC_SCRAMBLE_MESSAGES, m_scramble_messages);
//}}AFX_DATA_MAP
@@ -140,6 +141,7 @@ BEGIN_MESSAGE_MAP(ship_flags_dlg, CDialog)
ON_BN_CLICKED(IDC_DISABLE_ETS, OnDisableETS)
ON_BN_CLICKED(IDC_CLOAKED, OnCloaked)
ON_BN_CLICKED(IDC_SCRAMBLE_MESSAGES, OnScrambleMessages)
ON_BN_CLICKED(IDC_NO_COLLIDE, OnNoCollide)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
@@ -161,7 +163,7 @@ BOOL ship_flags_dlg::OnInitDialog()
int toggle_subsystem_scanning = 0, scannable = 0, kamikaze = 0, no_dynamic = 0, red_alert_carry = 0;
int special_warpin = 0, disable_messages = 0, guardian = 0, vaporize = 0, stealth = 0, friendly_stealth_invisible = 0;
int no_death_scream = 0, always_death_scream = 0, scramble_messages = 0;
int nav_carry = 0, nav_needslink = 0, hide_ship_name = 0, set_class_dynamically = 0, no_ets = 0, cloaked = 0;
int nav_carry = 0, nav_needslink = 0, hide_ship_name = 0, set_class_dynamically = 0, no_ets = 0, cloaked = 0, no_collide = 0;
object *objp;
ship *shipp;
@@ -210,6 +212,7 @@ BOOL ship_flags_dlg::OnInitDialog()
no_ets = (shipp->flags2 & SF2_NO_ETS) ? 1 : 0;
cloaked = (shipp->flags2 & SF2_CLOAKED) ? 1 : 0;
scramble_messages = (shipp->flags2 & SF2_SCRAMBLE_MESSAGES) ? 1 : 0;
no_collide = (objp->flags & OF_COLLIDES) ? 0 : 1;
destroy_before_mission = (shipp->flags & SF_KILL_BEFORE_MISSION) ? 1 : 0;
m_destroy_value.init(shipp->final_death_time);
@@ -270,6 +273,7 @@ BOOL ship_flags_dlg::OnInitDialog()
no_ets = tristate_set(shipp->flags2 & SF2_NO_ETS, no_ets);
cloaked = tristate_set(shipp->flags2 & SF2_CLOAKED, cloaked);
scramble_messages = tristate_set(shipp->flags2 & SF2_SCRAMBLE_MESSAGES, scramble_messages);
no_collide = tristate_set(!(objp->flags & OF_COLLIDES), no_collide);
// check the final death time and set the internal variable according to whether or not
// the final_death_time is set. Also, the value in the edit box must be set if all the
@@ -344,6 +348,7 @@ BOOL ship_flags_dlg::OnInitDialog()
m_disable_ets.SetCheck(no_ets);
m_cloaked.SetCheck(cloaked);
m_scramble_messages.SetCheck(scramble_messages);
m_no_collide.SetCheck(no_collide);
m_kdamage.setup(IDC_KDAMAGE, this);
m_destroy_value.setup(IDC_DESTROY_VALUE, this);
@@ -961,6 +966,22 @@ void ship_flags_dlg::update_ship(int shipnum)
break;
}
switch (m_no_collide.GetCheck()) {
case 1:
if ( objp->flags & OF_COLLIDES )
set_modified();
objp->flags &= ~OF_COLLIDES;
break;
case 0:
if (!(objp->flags & OF_COLLIDES))
set_modified();
objp->flags |= OF_COLLIDES;
break;
}
switch (m_guardian.GetCheck()) {
case 1:
if ( !(shipp->ship_guardian_threshold) )
@@ -1410,3 +1431,12 @@ void ship_flags_dlg::OnScrambleMessages()
m_scramble_messages.SetCheck(1);
}
}
void ship_flags_dlg::OnNoCollide()
{
if (m_no_collide.GetCheck() == 1) {
m_no_collide.SetCheck(0);
} else {
m_no_collide.SetCheck(1);
}
}
+2
View File
@@ -65,6 +65,7 @@ public:
CButton m_hide_ship_name;
CButton m_disable_ets;
CButton m_cloaked;
CButton m_no_collide;
CButton m_set_class_dynamically;
CButton m_scramble_messages;
@@ -126,6 +127,7 @@ protected:
afx_msg void OnDisableETS();
afx_msg void OnCloaked();
afx_msg void OnScrambleMessages();
afx_msg void OnNoCollide();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
+15 -9
View File
@@ -126,13 +126,17 @@ void CShipTexturesDlg::OnOK()
{
if (!stricmp(ii->ship_name, Ships[self_ship].ship_name))
{
end--;
do {
end--;
} while (end != ii && !stricmp(end->ship_name, Ships[self_ship].ship_name));
if (end == ii)
break;
texture_set(&(*ii), &(*end));
}
}
Fred_texture_replacements.erase(end);
if (end != Fred_texture_replacements.end())
Fred_texture_replacements.erase(end, Fred_texture_replacements.end());
// now put the new entries on the end of the list
for (i=0; i<texture_count; i++)
@@ -215,20 +219,22 @@ BOOL CShipTexturesDlg::OnInitDialog()
// make old texture lowercase
strlwr(texture_file);
// now add it to the box
z = box->AddString(texture_file);
// and add it to the field as well
// add it to the field
strcpy_s(old_texture_name[texture_count], texture_file);
// increment
texture_count++;
// sort
sort_textures();
}
}
// now sort the filenames
sort_textures();
// and add them to the box
for (i=0; i<texture_count; i++) {
z = box->AddString(old_texture_name[i]);
}
// now look for new textures
for (SCP_vector<texture_replace>::iterator ii = Fred_texture_replacements.begin(); ii != Fred_texture_replacements.end(); ++ii)
{
+5 -6
View File
@@ -52,8 +52,7 @@ void text_view_dlg::set(int ship_class)
{
char line[256], line2[256], file_text[82];
int i, j, n, found = 0, comment = 0, num_files = 0;
char tbl_file_arr[MAX_TBL_PARTS][MAX_FILENAME_LEN];
char *tbl_file_names[MAX_TBL_PARTS];
SCP_vector<SCP_string> tbl_file_names;
CFILE *fp;
if (ship_class < 0)
@@ -112,12 +111,12 @@ void text_view_dlg::set(int ship_class)
// done with ships.tbl, so now check all modular ship tables...
num_files = cf_get_file_list_preallocated(MAX_TBL_PARTS, tbl_file_arr, tbl_file_names, CF_TYPE_TABLES, NOX("*-shp.tbm"), CF_SORT_REVERSE);
num_files = cf_get_file_list(tbl_file_names, CF_TYPE_TABLES, NOX("*-shp.tbm"), CF_SORT_REVERSE);
for (n = 0; n < num_files; n++){
strcat(tbl_file_names[n], ".tbm");
tbl_file_names[n] += ".tbm";
fp = cfopen(tbl_file_names[n], "r");
fp = cfopen(tbl_file_names[n].c_str(), "r");
Assert(fp);
memset( line, 0, sizeof(line) );
@@ -160,7 +159,7 @@ void text_view_dlg::set(int ship_class)
if (!stricmp(line2 + i, Ship_info[ship_class].name)) {
memset( file_text, 0, sizeof(file_text) );
snprintf(file_text, sizeof(file_text)-1, "-- %s -------------------------------\r\n", tbl_file_names[n]);
snprintf(file_text, sizeof(file_text)-1, "-- %s -------------------------------\r\n", tbl_file_names[n].c_str());
m_edit += file_text;
found = 1;
}
+1 -1
View File
@@ -389,7 +389,7 @@ void VoiceActingManager::OnGenerateFileNames()
// notify user that we are done and how many filenames were changed
char message[128] = { '\0' };
snprintf(message, sizeof(message), "File name generation complete. Modified %u messages.", modified_filenames);
snprintf(message, sizeof(message)-1, "File name generation complete. Modified %u messages.", modified_filenames);
MessageBox(message, "Woohoo!");
}
-105
View File
@@ -512,108 +512,3 @@ int get_free_objnum(void)
return -1;
}
// Create a wing.
// wing_type is the type of wing from the Wing_formations array to create.
// leader_index is the index in Objects of the leader object. This object must
// have a position and an orientation.
// *wingmen is a list of indices of existing ships to be added to the wing.
// The wingmen list is terminated by -1.
// max_size is the maximum number of ships to add to the wing
// fill_flag is set if more ships are to be added to fill out the wing to max_size
void create_wing(int wing_type, int leader_index, int *wingmen, int max_size, int fill_flag)
{
int num_placed, num_vectors, cur_vec_index;
object *lobjp = &Objects[leader_index];
formation *wingp;
object *parent;
int wing_list[MAX_OBJECTS];
matrix rotmat;
initialize_wings();
Assert((wing_type >= 0) && (wing_type < MAX_WING_FORMATIONS));
Assert(Wing_formations[wing_type].num_vectors > 0);
Assert(Wing_formations[wing_type].num_vectors < MAX_WING_VECTORS);
Assert(Objects[leader_index].type != OBJ_NONE);
Assert(max_size < MAX_SHIPS_PER_WING);
num_placed = 0;
wingp = &Wing_formations[wing_type];
num_vectors = wingp->num_vectors;
cur_vec_index = 0;
parent = lobjp;
vm_copy_transpose_matrix(&rotmat, &lobjp->orient);
while (num_placed < max_size) {
vec3d wvec;
int curobj;
if (*wingmen == -1) {
if (!fill_flag)
break;
else {
curobj = get_free_objnum();
Assert(curobj != -1);
Objects[curobj].type = lobjp->type;
Assert(Wings[cur_wing].wave_count < MAX_SHIPS_PER_WING);
// JEH Wings[cur_wing].ship_list[Wings[cur_wing].count] = curobj;
Wings[cur_wing].wave_count++;
}
} else
curobj = *wingmen++;
Objects[curobj] = *lobjp;
vm_vec_rotate(&wvec, &wingp->offsets[cur_vec_index], &rotmat);
cur_vec_index = (cur_vec_index + 1) % num_vectors;
if (num_placed < num_vectors)
parent = lobjp;
else
parent = &Objects[wing_list[num_placed - num_vectors]];
wing_list[num_placed] = curobj;
vm_vec_add(&Objects[curobj].pos, &parent->pos, &wvec);
num_placed++;
}
}
// Create a wing.
// cur_object_index becomes the leader.
// If count == -1, then all objects of wing cur_wing get added to the wing.
// If count == +n, then n objects are added to the wing.
void test_form_wing(int count)
{
int i, wingmen[MAX_OBJECTS];
int j, fill_flag;
j = 0;
Assert(cur_object_index != -1);
Assert(Objects[cur_object_index].type != OBJ_NONE);
Assert(get_wingnum(cur_object_index) != -1);
get_wingnum(cur_object_index);
wingmen[0] = -1;
for (i=1; i<MAX_OBJECTS; i++)
if ((get_wingnum(i) == cur_wing) && (Objects[i].type != OBJ_NONE))
if (i != cur_object_index)
wingmen[j++] = i;
wingmen[j] = -1;
fill_flag = 0;
if (count > 0) {
fill_flag = 1;
j += count;
}
set_wingnum(cur_object_index, cur_wing);
create_wing(0, cur_object_index, wingmen, j, fill_flag);
}
File diff suppressed because it is too large. Load diff
+1
View File
@@ -37,6 +37,7 @@ extern float flRealframetime;
extern float flFrametime;
extern fix Missiontime;
extern int Last_frame_timestamp; // A timestamp for when the previous frame ended
extern fix Skybox_timestamp; // A timestamp for animated skyboxes -MageKing17
// 0 - 4
extern int Game_skill_level;
+4 -4
View File
@@ -336,8 +336,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,7,1,0000
PRODUCTVERSION 3,7,1,0000
FILEVERSION 3,7,2,11329
PRODUCTVERSION 3,7,2,11329
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -354,12 +354,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Volition Inc."
VALUE "FileDescription", "FreeSpace 2 Open"
VALUE "FileVersion", "3.7.1.0000"
VALUE "FileVersion", "3.7.2.11329"
VALUE "InternalName", "FreeSpace 2 Open"
VALUE "LegalCopyright", "Copyright © 1998"
VALUE "OriginalFilename", "fs2.exe"
VALUE "ProductName", "FreeSpace 2 Open"
VALUE "ProductVersion", "3.7.1"
VALUE "ProductVersion", "3.7.2"
END
END
BLOCK "VarFileInfo"
+3 -3
View File
@@ -249,7 +249,7 @@ int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create,
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total <= sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
@@ -361,7 +361,7 @@ int FS2NetD_GetBanList(SCP_vector<SCP_string> &mask_list, bool do_send)
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total <= sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
@@ -435,7 +435,7 @@ int FS2NetD_GetMissionsList(SCP_vector<file_record> &m_list, bool do_send)
}
// make sure that we get the entire packet
while ( (rc_total < (uint)buffer_size) && (rc_total <= sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) {
if ( FS2NetD_DataReady() ) {
rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total);
File diff suppressed because it is too large. Load diff
+21 -28
View File
@@ -16,44 +16,37 @@
// Help overlays
//
// Adding a help overlay: 1) Add a #define that uniquely identifies your help overlay
// 2) Increment MAX_HELP_OVERLAYS
// 3) Add the filename for the help overlay to Help_overlays[] array in ContextHelp.cpp
//
#define MAX_HELP_OVERLAYS 16 // Must be kept current
#define MAX_HELP_OVERLAYS 30
#define SS_OVERLAY 0 // ship selection help
#define WL_OVERLAY 1 // weapons loadout help
#define BR_OVERLAY 2 // briefing help
#define MH_OVERLAY 3 // main hall help
#define BARRACKS_OVERLAY 4 // barracks help
#define CONTROL_CONFIG_OVERLAY 5 // control config help
#define DEBRIEFING_OVERLAY 6 // debriefing help
#define MULTI_CREATE_OVERLAY 7 // multi create game help
#define MULTI_START_OVERLAY 8 // multi start game help overlay
#define MULTI_JOIN_OVERLAY 9 // join game help overlay
#define MH2_OVERLAY 10 // main hall 2 help overlay
#define HOTKEY_OVERLAY 11 // hotkey assignment help overlay
#define CAMPAIGN_ROOM_OVERLAY 12 // campaign room help overlay
#define SIM_ROOM_OVERLAY 13 // sim room help overlay
#define TECH_ROOM_OVERLAY 14 // tech room (general) help overlay
#define CMD_BRIEF_OVERLAY 15 // command briefing help overlay
//#define FS2OX_OVERLAY 16 // Chat help overlay
#define SS_OVERLAY "ship" // ship selection help
#define WL_OVERLAY "weapon" // weapons loadout help
#define BR_OVERLAY "briefing" // briefing help
#define MH_OVERLAY "main" // main hall help
#define BARRACKS_OVERLAY "barracks" // barracks help
#define CONTROL_CONFIG_OVERLAY "control" // control config help
#define DEBRIEFING_OVERLAY "debrief" // debriefing help
#define MULTI_CREATE_OVERLAY "multicreate" // multi create game help
#define MULTI_START_OVERLAY "multistart" // multi start game help overlay
#define MULTI_JOIN_OVERLAY "multijoin" // join game help overlay
#define MH2_OVERLAY "main2" // main hall 2 help overlay
#define HOTKEY_OVERLAY "hotkey" // hotkey assignment help overlay
#define CAMPAIGN_ROOM_OVERLAY "campaign" // campaign room help overlay
#define SIM_ROOM_OVERLAY "simulator" // sim room help overlay
#define TECH_ROOM_OVERLAY "tech" // tech room (general) help overlay
#define CMD_BRIEF_OVERLAY "command" // command briefing help overlay
// other help overlay constants
#define HELP_MAX_ITEM 50 // max number of screen elements per element type per overlay
#define HELP_PADDING 1 //
#define HELP_MAX_NAME_LENGTH 32 // max string length for overlay name
#define HELP_MAX_STRING_LENGTH 128 // max string length for text overlay element
#define HELP_MAX_PLINE_VERTICES 21 // good for 20 segments, can prolly reduce this (FIXME)
#define HELP_PLINE_THICKNESS 2
#define HELP_OVERLAY_FILENAME "help.tbl"
// help overlay calls
int help_overlay_get_index(const char* overlay_name);
int help_overlay_active(int overlay_id);
void help_overlay_set_state(int overlay_id, int state);
void help_overlay_load(int overlay_id);
void help_overlay_unload(int overlay_id);
void help_overlay_maybe_blit(int overlay_id);
void help_overlay_set_state(int overlay_id, int resolution_index, int state);
void help_overlay_maybe_blit(int overlay_id, int resolution_index);
void context_help_init(); // called once at game startup
void context_help_grey_screen(); // call to grey out a screen (normally when applying a help overlay)
+10 -10
View File
@@ -169,16 +169,16 @@ void gameplay_help_blit_control_line(int x, int y, int id)
strcpy_s(buf, XSTR( "no binding", 130));
}
gr_string(x,y,buf);
gr_string(x,y,buf,GR_RESIZE_MENU);
// gr_string(x+KEY_DESCRIPTION_OFFSET,y,ci->text);
gr_string(x+KEY_DESCRIPTION_OFFSET, y, XSTR(ci->text, CONTROL_CONFIG_XSTR + id));
// gr_string(x+KEY_DESCRIPTION_OFFSET,y,ci->text,GR_RESIZE_MENU);
gr_string(x+KEY_DESCRIPTION_OFFSET, y, XSTR(ci->text, CONTROL_CONFIG_XSTR + id), GR_RESIZE_MENU);
}
void gameplay_help_blit_control_line_raw(int x, int y, const char *control_text, const char *control_description)
{
gr_string(x,y,control_text);
gr_string(x+KEY_DESCRIPTION_OFFSET,y,control_description);
gr_string(x,y,control_text,GR_RESIZE_MENU);
gr_string(x+KEY_DESCRIPTION_OFFSET,y,control_description,GR_RESIZE_MENU);
}
// game_play_help_set_title() will display the title for the help screen and
@@ -189,9 +189,9 @@ void gameplay_help_set_title(const char *title)
char buf[128];
gr_set_color_fast(&Color_bright);
gr_printf(0x8000,sy,title);
gr_printf_menu(0x8000,sy,title);
sprintf(buf, XSTR( "Page %d of %d", 132), Current_help_page+1, Gp_last_screen+1);
gr_printf(0x8000,sy+gr_get_font_height()+2,buf);
gr_printf_menu(0x8000,sy+gr_get_font_height()+2,buf);
gr_set_color_fast(&Color_normal);
}
@@ -364,7 +364,7 @@ void gameplay_help_draw_text()
y_offset += separation;
gr_set_color_fast(&Color_bright);
gr_printf(0x8000,y_offset,XSTR( "Function Keys", 134));
gr_printf_menu(0x8000,y_offset,XSTR( "Function Keys", 134));
gr_set_color_fast(&Color_normal);
y_offset += separation;
@@ -755,7 +755,7 @@ void gameplay_help_draw_text()
// ingame messaging
gr_set_color_fast(&Color_bright);
gr_printf(0x8000,y_offset,XSTR( "Ingame messaging keys (tap for text, hold for voice)", 168));
gr_printf_menu(0x8000,y_offset,XSTR( "Ingame messaging keys (tap for text, hold for voice)", 168));
gr_set_color_fast(&Color_normal);
y_offset += separation;
@@ -804,7 +804,7 @@ void gameplay_help_do_frame(float frametime)
GR_MAYBE_CLEAR_RES(Background_bitmap);
if (Background_bitmap >= 0) {
gr_set_bitmap(Background_bitmap);
gr_bitmap(0, 0);
gr_bitmap(0, 0, GR_RESIZE_MENU);
}
Ui_window.draw();
+4 -8
View File
@@ -788,6 +788,9 @@ int event_music_enemy_arrival()
else {
next_pattern = SONG_EARV_1;
}
if ( Current_pattern < 0 )
return 0;
if ( Current_pattern == next_pattern )
return 0; // already playing
@@ -1125,7 +1128,7 @@ int event_music_player_respawn_as_observer()
bool parse_soundtrack_line(int strack_idx, int pattern_idx)
{
char fname[MAX_FILENAME_LEN];
char line_buf[128];
char line_buf[MAX_PATH_LEN];
char *token;
int count = 0;
@@ -1377,12 +1380,8 @@ void event_music_parse_musictbl(const char *filename)
if ((rval = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", filename, rval));
lcl_ext_close();
} else {
// open localization
lcl_ext_open();
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
@@ -1401,9 +1400,6 @@ void event_music_parse_musictbl(const char *filename)
}
}
}
// close localization
lcl_ext_close();
}
}
-6
View File
@@ -777,16 +777,10 @@ void parse_sound_table(const char* filename)
*/
void gamesnd_parse_soundstbl()
{
// open localization
lcl_ext_open();
parse_sound_table("sounds.tbl");
parse_modular_table("*-snd.tbm", parse_sound_table);
// close localization
lcl_ext_close();
// if we are missing any species then report
if (missingFlybySounds.size() > 0)
{
+474 -124
View File
@@ -15,10 +15,19 @@
SCP_map<SCP_string, team_color> Team_Colors;
SCP_vector<SCP_string> Team_Names;
SCP_map<char, color*> Tagged_Colors;
SCP_map<char, color> Custom_Colors;
SCP_vector<char> Color_Tags;
// -----------------------------------------------------------------------------------
// ALPHA DEFINES/VARS
//
color Color_text_normal, Color_text_subselected, Color_text_selected;
color Color_text_error, Color_text_error_hi, Color_text_active, Color_text_active_hi;
color Color_text_heading, Color_more_indicator, Color_more_bright, Color_bright, Color_normal;
color Color_briefing_grid;
color Color_blue, Color_bright_blue, Color_green, Color_bright_green;
color Color_black, Color_grey, Color_silver, Color_white, Color_bright_white;
color Color_violet_gray, Color_violet, Color_pink, Color_light_pink;
@@ -26,6 +35,172 @@ color Color_dim_red, Color_red, Color_bright_red, Color_yellow, Color_bright_yel
color Color_ui_light_green, Color_ui_green;
color Color_ui_light_pink, Color_ui_pink;
color Brief_color_red, Brief_color_green, Brief_color_legacy_neutral;
char default_fiction_viewer_color = 'w';
char default_command_briefing_color = 'w';
char default_briefing_color = 'w';
char default_redalert_briefing_color = 'w';
char default_debriefing_color = 'w';
char default_recommendation_color = 'r';
char default_loop_briefing_color = 'w';
color *COLOR_LIST[TOTAL_COLORS] = {
&Color_blue,
&Color_bright_blue,
&Color_green,
&Color_bright_green,
&Color_black,
&Color_grey,
&Color_silver,
&Color_white,
&Color_bright_white,
&Color_violet_gray,
&Color_violet,
&Color_dim_red,
&Color_red,
&Color_bright_red,
&Color_pink,
&Color_light_pink,
&Color_yellow,
&Color_bright_yellow,
&Color_ui_light_green,
&Color_ui_green,
&Color_ui_light_pink,
&Color_ui_pink,
};
const char *COLOR_NAMES[TOTAL_COLORS] = {
"Blue",
"Bright Blue",
"Green",
"Bright Green",
"Black",
"Grey",
"Silver",
"White",
"Bright White",
"Violet Gray",
"Violet",
"Dim Red",
"Red",
"Bright Red",
"Pink",
"Light Pink",
"Yellow",
"Bright Yellow",
"UI Light Green",
"UI Green",
"UI Light Pink",
"UI Pink"
};
const int rgba_defaults[TOTAL_COLORS][4] = {
{93, 93, 128, 255},
{185, 185, 255, 255},
{0, 120, 0, 255},
{50, 190, 50, 255},
{0, 0, 0, 255},
{65, 65, 65, 255},
{160, 160, 160, 255},
{105, 105, 105, 255},
{255, 255, 255 ,255},
{160, 144, 160, 255},
{192, 104, 192, 255},
{80, 6, 6, 255},
{126, 6, 6, 255},
{200, 0, 0, 255},
{185, 150, 150, 255},
{230, 190, 190, 255},
{255, 255, 122, 255},
{255, 255, 0, 255},
{161, 184, 161, 255},
{190, 228, 190, 255},
{184, 161, 161, 255},
{228, 190, 190, 255}
};
color *interface_colors[INTERFACE_COLORS] = {
&Color_text_normal,
&Color_text_subselected,
&Color_text_selected,
&Color_text_error,
&Color_text_error_hi,
&Color_text_active,
&Color_text_active_hi,
&Color_text_heading,
&Color_more_indicator,
&Color_more_bright,
&Color_bright,
&Color_normal,
&Color_briefing_grid,
};
const int interface_defaults[INTERFACE_COLORS] = {
7, //"White"
0, //"Blue"
1, //"Bright Blue"
12, //"Red"
13, //"Bright Red"
8, //"Bright White"
8, //"Bright White"
9, //"Violet Gray"
12, //"Red"
13, //"Bright Red"
1, //"Bright Blue"
7, //"White"
5, //"Grey"
};
#define DEFAULT_TAGS 20
const char DEFAULT_TAG_LIST[DEFAULT_TAGS] = {
'w',
'W',
'r',
'g',
'y',
'b',
'f',
'h',
'n',
'B',
'G',
'R',
'Y',
'k',
'e',
'E',
'v',
'V',
'p',
'P',
};
color* DEFAULT_TAG_COLORS[DEFAULT_TAGS] = {
&Color_white,
&Color_bright_white,
&Color_red,
&Color_green,
&Color_yellow,
&Color_blue,
&Brief_color_green,
&Brief_color_red,
&Brief_color_legacy_neutral,
&Color_bright_blue,
&Color_bright_green,
&Color_bright_red,
&Color_bright_yellow,
&Color_black,
&Color_grey,
&Color_silver,
&Color_violet_gray,
&Color_violet,
&Color_pink,
&Color_light_pink,
};
// netplayer colors
color *Color_netplayer[NETPLAYER_COLORS] = {
@@ -52,68 +227,68 @@ color *Color_netplayer[NETPLAYER_COLORS] = {
};
void parse_colors(const char *filename);
void parse_everything_else(const char *filename); // needs a better name
// -----------------------------------------------------------------------------------
// ALPHA FUNCTIONS
//
/**
* CommanderDJ: initialise alpha colors based on colors.tbl
* \return 1 if successful, 0 if init fails for any reason
* Made modular and given a wider range of features by MageKing17
*/
int new_alpha_colors_init()
void alpha_colors_init()
{
int err_code;
if ((err_code = setjmp(parse_abort)) != 0)
{
mprintf(("Unable to parse 'colors.tbl'! Error code = %d.\n", err_code));
return 0;
// Set our default colors.
int i;
for (i = 0; i < TOTAL_COLORS; i++) {
gr_init_alphacolor(COLOR_LIST[i], rgba_defaults[i][0], rgba_defaults[i][1], rgba_defaults[i][2], rgba_defaults[i][3]);
}
if (cf_exists_full("colors.tbl", CF_TYPE_TABLES))
{
read_file_text("colors.tbl", CF_TYPE_TABLES);
mprintf(("TABLES => Starting parse of 'colors.tbl'...\n"));
if (cf_exists_full("colors.tbl", CF_TYPE_TABLES)) {
mprintf(("TABLES => Starting parse of 'colors.tbl' (checking '#Start Colors' section only)...\n"));
parse_colors("colors.tbl");
}
else
{
//colors.tbl doesn't exist
mprintf(("TABLES => Unable to find 'colors.tbl'. Initialising colors with default values.\n"));
return 0;
parse_modular_table(NOX("*-clr.tbm"), parse_colors);
// Set defaults for interface colors and color tags (must be done after the above because they're generally just copies of above-defined colors).
for (i = 0; i < INTERFACE_COLORS; i++) {
memcpy(interface_colors[i], COLOR_LIST[interface_defaults[i]], sizeof(color));
}
for (i = 0; i < DEFAULT_TAGS; i++) {
Tagged_Colors[DEFAULT_TAG_LIST[i]] = DEFAULT_TAG_COLORS[i];
Color_Tags.push_back(DEFAULT_TAG_LIST[i]);
}
if (cf_exists_full("colors.tbl", CF_TYPE_TABLES)) {
mprintf(("TABLES => Starting parse of 'colors.tbl' (skipping '#Start Colors' section)...\n"));
parse_everything_else("colors.tbl");
}
parse_modular_table(NOX("*-clr.tbm"), parse_everything_else);
}
void parse_colors(const char *filename)
{
Assertion(filename != NULL, "parse_colors() called on NULL; get a coder!\n");
read_file_text(filename, CF_TYPE_TABLES);
int err_code;
if ((err_code = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %d.\n", filename, err_code));
return;
}
reset_parse();
// we search for the colors based on their order of definition above
// if the color isn't found, we just use default values
if (required_string("#Start Colors"))
if (optional_string("#Start Colors"))
{
// vars for holding rgba values
int rgba[4] = {0,0,0,0};
color *colors[TOTAL_COLORS] = {
&Color_blue,
&Color_bright_blue,
&Color_green,
&Color_bright_green,
&Color_black,
&Color_grey,
&Color_silver,
&Color_white,
&Color_bright_white,
&Color_violet_gray,
&Color_violet,
&Color_dim_red,
&Color_red,
&Color_bright_red,
&Color_pink,
&Color_light_pink,
&Color_yellow,
&Color_bright_yellow,
&Color_ui_light_green,
&Color_ui_green,
&Color_ui_light_pink,
&Color_ui_pink,
};
int i, j;
char* color_names[TOTAL_COLORS] = {
"$Blue:",
@@ -140,77 +315,75 @@ int new_alpha_colors_init()
"$UI Pink:"
};
int rgba_defaults[TOTAL_COLORS][4] = {
{93, 93, 128, 255},
{185, 185, 255, 255},
{0, 120, 0, 255},
{50, 190, 50, 255},
{0, 0, 0, 255},
{65, 65, 65, 255},
{160, 160, 160, 255},
{105, 105, 105, 255},
{255, 255, 255 ,255},
{160, 144, 160, 255},
{192, 104, 192, 255},
{80, 6, 6, 255},
{126, 6, 6, 255},
{200, 0, 0, 255},
{185, 150, 150, 255},
{230, 190, 190, 255},
{255, 255, 122, 255},
{255, 255, 0, 255},
{161, 184, 161, 255},
{190, 228, 190, 255},
{184, 161, 161, 255},
{228, 190, 190, 255}
};
// now for each color, check if it's corresponding string is there
for (int i=0; i<TOTAL_COLORS; i++)
{
if (optional_string(color_names[i]))
{
for (i = 0; i < TOTAL_COLORS; i++) {
if (optional_string(color_names[i])) {
// if so, get its rgba values and initialise it using them
mprintf(("'%s' has been redefined.\n", color_names[i]));
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
for (int j=0; j<4; j++)
{
if (rgba[j] < 0)
{
Warning(LOCATION, "RGBA value for '%s' in colors.tbl too low (%d), capping to 0.", color_names[i], rgba[j]);
rgba[j] = 0;
//if (check_for_string("(")) {
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
for (j = 0; j < 4; j++) {
if (rgba[j] < 0) {
Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
rgba[j] = 0;
} else if (rgba[j] > 255) {
Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
rgba[j] = 255;
}
}
else if (rgba[j] > 255)
{
Warning(LOCATION, "RGBA value for '%s' in colors.tbl too high (%d), capping to 255.", color_names[i], rgba[j]);
rgba[j] = 255;
}
}
gr_init_alphacolor(colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
//} else {
// stuff_hex_list(rgba, 4);
//}
gr_init_alphacolor(COLOR_LIST[i], rgba[0], rgba[1], rgba[2], rgba[3]);
}
// otherwise use its defaults
else
gr_init_alphacolor(colors[i], rgba_defaults[i][0], rgba_defaults[i][1], rgba_defaults[i][2], rgba_defaults[i][3]);
}
required_string("#End");
}
}
void parse_everything_else(const char *filename)
{
Assertion(filename != NULL, "parse_everything_else() called on NULL; get a coder!\n");
read_file_text(filename, CF_TYPE_TABLES);
int err_code;
if ((err_code = setjmp(parse_abort)) != 0) {
mprintf(("TABLES: Unable to parse '%s'! Error code = %d.\n", filename, err_code));
return;
}
reset_parse();
int rgba[4] = {0,0,0,0};
// reusable temp vars
int i, j;
SCP_string temp;
if (optional_string("#Start Colors")) {
// Skip this section; we already parsed it in every file.
skip_to_string("#End", NULL);
}
//Team coloring
if (optional_string("#Team Colors")) {
while (required_string_either("#End", "$Team Name:")) {
required_string("$Team Name:"); // required to move the parse pointer forward
char temp[NAME_LENGTH];
SCP_string temp2;
team_color temp_color;
stuff_string(temp, F_NAME, NAME_LENGTH);
temp2 = SCP_string(temp);
char temp2[NAME_LENGTH];
stuff_string(temp2, F_NAME, NAME_LENGTH);
temp = temp2;
if (!stricmp(temp2, "none")) {
Warning(LOCATION, "Team color in '%s' defined with a name of '%s'; this won't be usable due to 'None' being used for a lack of a team color by the engine.\n", filename, temp2);
}
if (required_string("$Team Stripe Color:")) {
int rgb[3];
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
for (int i = 0; i < 3; i++) {
for (i = 0; i < 3; i++) {
CLAMP(rgb[i], 0, 255);
}
@@ -222,7 +395,7 @@ int new_alpha_colors_init()
if (required_string("$Team Base Color:")) {
int rgb[3];
stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
for (int i = 0; i < 3; i++) {
for (i = 0; i < 3; i++) {
CLAMP(rgb[i], 0, 255);
}
@@ -231,46 +404,223 @@ int new_alpha_colors_init()
temp_color.base.b = rgb[2] / 255.0f;
}
Team_Colors[temp2] = temp_color;
Team_Names.push_back(temp2);
if (Team_Colors.find(temp) == Team_Colors.end()) { // Only push to the vector if the team isn't already defined.
Team_Names.push_back(temp);
}
Team_Colors[temp] = temp_color;
}
required_string("#End");
}
return 1;
}
// Previously-hardcoded interface colors
if (optional_string("#Interface Colors")) {
char *color_names[INTERFACE_COLORS] = {
"$Text Normal:",
"$Text Subselected:",
"$Text Selected:",
"$Text Error:",
"$Text Error Highlighted:",
"$Text Active:",
"$Text Active Highlighted:",
"$Text Heading:",
"$More Indicator:",
"$Bright More Indicator:",
"$Bright:",
"$Normal:",
"$Briefing Grid:",
};
// initialize all alpha colors (call at startup)
void old_alpha_colors_init()
{
// See the variable declarations above for color usage
gr_init_alphacolor( &Color_blue, 93, 93, 128, 255 );
gr_init_alphacolor( &Color_bright_blue, 185, 185, 255, 255 );
// now for each color, check if its corresponding string is there
for (i = 0; i < INTERFACE_COLORS; i++) {
if (optional_string(color_names[i])) {
// if so, get its rgba values and initialise it using them
mprintf(("'%s' has been redefined.\n", color_names[i]));
if ( check_for_string("(") ) {
// If we have a list of integers, use them.
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
for (j = 0; j < 4; j++) {
if (rgba[j] < 0)
{
Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
rgba[j] = 0;
}
else if (rgba[j] > 255)
{
Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
rgba[j] = 255;
}
}
gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
//} else if (check_for_string("#")) {
// stuff_hex_list(rgba, 4);
// gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
} else {
// We have a string; it should be the name of a color to use.
stuff_string(temp, F_NAME);
for (j = 0; j < TOTAL_COLORS; j++) {
if ( !temp.compare(COLOR_NAMES[j]) ) {
break;
}
}
if ( j == TOTAL_COLORS ) {
Warning(LOCATION, "Unknown color '%s' in %s, for definition of '%s'; using default ('%s').\n", temp.c_str(), filename, color_names[i], COLOR_NAMES[interface_defaults[i]]);
} else {
Assertion(j >= 0 && j < TOTAL_COLORS, "Attempting to copy nonexistant color (%d out of 0-%d)!\n", j, TOTAL_COLORS-1);
memcpy(interface_colors[i], COLOR_LIST[j], sizeof(color));
}
}
}
}
required_string("#End");
}
gr_init_alphacolor( &Color_green, 0, 120, 0, 255 );
gr_init_alphacolor( &Color_bright_green, 50, 190, 50, 255 );
// Text color tags; for briefings, command briefings, debriefings, and the fiction viewer
if (optional_string("#Color Tags")) {
while (required_string_either("$Tag:", "#End") < 1) {
required_string("$Tag:");
color temp_color;
char tag;
gr_init_alphacolor( &Color_black, 0, 0, 0, 255 );
gr_init_alphacolor( &Color_grey, 65, 65, 65, 255 );
gr_init_alphacolor( &Color_silver, 160, 160, 160, 255 );
gr_init_alphacolor( &Color_white, 105, 105, 105, 255 );
gr_init_alphacolor( &Color_bright_white, 255, 255, 255, 255 );
stuff_string(temp, F_RAW);
if (temp[0] == '$') {
if (temp[1] == '\0') {
Error(LOCATION, "%s - found a '$Tag:' entry with a solitary '$'.\n", filename);
}
tag = temp[1];
if (temp[2] != '\0') {
Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
}
} else if (temp[0] == '\0') {
Error(LOCATION, "%s - found a '$Tag:' entry with no tag.\n", filename);
} else {
tag = temp[0];
if (temp[1] != '\0') {
Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
}
}
gr_init_alphacolor( &Color_violet_gray, 160, 144, 160, 255 );
gr_init_alphacolor( &Color_violet, 192, 104, 192, 255 );
if (Tagged_Colors.find(tag) == Tagged_Colors.end()) { // Only push the tag to our list of tags if it's actually new, not just a redefinition.
Color_Tags.push_back(tag);
}
gr_init_alphacolor( &Color_dim_red, 80, 6, 6, 255 );
gr_init_alphacolor( &Color_red, 126, 6, 6, 255 );
gr_init_alphacolor( &Color_bright_red, 200, 0, 0, 255 );
switch(required_string_one_of(4, "+Color:", "+Friendly", "+Hostile", "+Neutral")) {
case 0: // +Color
required_string("+Color:");
gr_init_alphacolor( &Color_pink, 185, 150, 150, 255 );
gr_init_alphacolor( &Color_light_pink, 230, 190, 190, 255 );
rgba[0] = rgba[1] = rgba[2] = 0;
rgba[3] = 255; // Odds are pretty high you want it to have full alpha...
gr_init_alphacolor( &Color_yellow, 255, 255, 122, 255 );
gr_init_alphacolor( &Color_bright_yellow, 255, 255, 0, 255 );
if ( check_for_string("(") ) {
stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
for (j = 0; j < 4; j++) {
if (rgba[j] < 0)
{
Warning(LOCATION, "RGBA value for '$%c' in %s too low (%d), capping to 0.\n", tag, filename, rgba[j]);
rgba[j] = 0;
}
else if (rgba[j] > 255)
{
Warning(LOCATION, "RGBA value for '$%c' in %s too high (%d), capping to 255.\n", tag, filename, rgba[j]);
rgba[j] = 255;
}
}
gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
Custom_Colors[tag] = temp_color;
Tagged_Colors[tag] = &Custom_Colors[tag];
//} else if ( check_for_string ("#") ) {
// stuff_hex_list(rgba, 4);
// gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
// Custom_Colors[tag] = temp_color;
// Tagged_Colors[tag] = &Custom_Colors[tag];
} else {
// We have a string; it should be the name of a color to use.
stuff_string(temp, F_NAME);
for (j = 0; j < TOTAL_COLORS; j++) {
if ( !temp.compare(COLOR_NAMES[j]) ) {
break;
}
}
if ( j == TOTAL_COLORS ) {
Error(LOCATION, "Unknown color '%s' in %s, for definition of tag '$%c'.\n", temp.c_str(), filename, tag);
}
Tagged_Colors[tag] = COLOR_LIST[j];
}
break;
case 1: // +Friendly
required_string("+Friendly");
Tagged_Colors[tag] = &Brief_color_green;
break;
case 2: // +Hostile
required_string("+Hostile");
Tagged_Colors[tag] = &Brief_color_red;
break;
case 3: // +Neutral
required_string("+Neutral");
Tagged_Colors[tag] = &Brief_color_legacy_neutral;
break;
case -1:
// -noparseerrors is set
if (Tagged_Colors.find(tag) == Tagged_Colors.end()) { // It was a new color, but since we haven't actually defined it...
Color_Tags.pop_back();
}
break;
default:
Assertion(false, "MageKing17 made a coding error somewhere, and you should laugh at him (and report this error).\n");
break;
}
}
gr_init_alphacolor( &Color_ui_light_green, 161, 184, 161, 255 );
gr_init_alphacolor( &Color_ui_green, 190, 228, 190, 255 );
required_string("#End");
}
Assertion(Color_Tags.size() == Tagged_Colors.size(), "Color_Tags and Tagged_Colors size mismatch; get a coder!\n");
gr_init_alphacolor( &Color_ui_light_pink, 184, 161, 161, 255 );
gr_init_alphacolor( &Color_ui_pink, 228, 190, 190, 255 );
if (optional_string("#Default Text Colors")) {
char* color_names[MAX_DEFAULT_TEXT_COLORS] = {
"$Fiction Viewer:",
"$Command Briefing:",
"$Briefing:",
"$Redalert Briefing:",
"$Debriefing:",
"$Recommendation:",
"$Loop Briefing:",
};
char *color_value[MAX_DEFAULT_TEXT_COLORS] = {
&default_fiction_viewer_color,
&default_command_briefing_color,
&default_briefing_color,
&default_redalert_briefing_color,
&default_debriefing_color,
&default_recommendation_color,
&default_loop_briefing_color,
};
for (i = 0; i < MAX_DEFAULT_TEXT_COLORS; i++) {
if ( optional_string(color_names[i]) ) {
stuff_string(temp, F_RAW);
if (temp[0] == '$') {
if (temp[1] == '\0') {
Error(LOCATION, "%s - default text color '%s' entry with a solitary '$'.\n", filename, color_names[i]);
}
*color_value[i] = temp[1];
if (temp[2] != '\0') {
Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
}
} else if (temp[0] == '\0') {
Error(LOCATION, "%s - default text color '%s' entry with no tag.\n", filename, color_names[i]);
} else {
*color_value[i] = temp[0];
if (temp[1] != '\0') {
Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
}
}
if (Tagged_Colors.find(*color_value[i]) == Tagged_Colors.end()) {
// Just mprintf() this information instead of complaining with a Warning(); the tag might be defined in a later-loading TBM, and if it isn't, nothing too terrible will happen.
mprintf(("%s - default text color '%s' set to non-existant tag '$%c'.\n", filename, color_names[i], *color_value[i]));
}
}
}
required_string("#End");
}
}
+21 -23
View File
@@ -21,26 +21,12 @@
// Colors for UI
// See FreeSpace.cpp for usage
// The following colors are for text drawing:
// normal text
#define Color_text_normal Color_white
// text highlighted while down still down on a line
#define Color_text_subselected Color_blue
// text highlighted as the selected line
#define Color_text_selected Color_bright_blue
// text that indicates an error
#define Color_text_error Color_red
// text that indicates an error, and line is selected or subselected
#define Color_text_error_hi Color_bright_red
// text that indicates line is active item
#define Color_text_active Color_bright_white
// text that indicates line is active item, and line is selected or subselected
#define Color_text_active_hi Color_bright_white
// text drawn as a heading for a section or title, etc
#define Color_text_heading Color_violet_gray
#define INTERFACE_COLORS 13
extern color Color_text_normal, Color_text_subselected, Color_text_selected;
extern color Color_text_error, Color_text_error_hi, Color_text_active, Color_text_active_hi;
extern color Color_text_heading, Color_more_indicator, Color_more_bright, Color_bright, Color_normal;
extern color Color_briefing_grid;
#define Color_bright Color_bright_blue
#define Color_normal Color_white
#define TOTAL_COLORS 22
extern color Color_blue, Color_bright_blue, Color_green, Color_bright_green;
extern color Color_black, Color_grey, Color_silver, Color_white, Color_bright_white;
@@ -50,6 +36,9 @@ extern color Color_dim_red, Color_red, Color_bright_red, Color_yellow, Color_bri
extern color Color_ui_light_green, Color_ui_green;
extern color Color_ui_light_pink, Color_ui_pink;
// briefing hostile/friendly/neutral colors
extern color Brief_color_red, Brief_color_green, Brief_color_legacy_neutral;
// netplayer colors
#define NETPLAYER_COLORS 20
extern color *Color_netplayer[NETPLAYER_COLORS];
@@ -58,14 +47,23 @@ extern color *Color_netplayer[NETPLAYER_COLORS];
extern SCP_map<SCP_string, team_color> Team_Colors;
extern SCP_vector<SCP_string> Team_Names;
extern SCP_map<char, color*> Tagged_Colors;
extern SCP_vector<char> Color_Tags;
#define MAX_DEFAULT_TEXT_COLORS 7
extern char default_fiction_viewer_color;
extern char default_command_briefing_color;
extern char default_briefing_color;
extern char default_redalert_briefing_color;
extern char default_debriefing_color;
extern char default_recommendation_color;
extern char default_loop_briefing_color;
// -----------------------------------------------------------------------------------
// ALPHA FUNCTIONS
//
//initialize alpha colors based on colors.tbl
int new_alpha_colors_init();
//initialize alpha colors based on hardcoded values
void old_alpha_colors_init();
void alpha_colors_init();
#endif
+3 -3
View File
@@ -1428,7 +1428,7 @@ char *Default_main_fragment_shader =
" vec3 envReflectNM = envReflect + envOffset;\n"
" vec4 envColour = textureCube(sEnvmap, envReflectNM);\n"
" #endif\n"
" normal.b = sqrt(1.0 - dot(normal.rg, normal.rg));\n"
" normal.b = 1.0;\n"
" normal = tbnMatrix * normal;\n"
" float norm = length(normal);\n"
" // prevent breaking of normal maps\n"
@@ -1543,12 +1543,12 @@ char *Default_main_fragment_shader =
" #endif\n"
" #ifdef FLAG_ANIMATED\n"
" if (effect_num == 0) {\n"
" float shinefactor = 1.0/(1.0 + pow((fract(abs(gl_TexCoord[0].x))-anim_timer) * 1000.0, 2.0)) * 1000.0;\n"
" float shinefactor = 1.0/(1.0 + pow(abs((fract(abs(gl_TexCoord[0].x))-anim_timer) * 1000.0), 2.0)) * 1000.0;\n"
" gl_FragColor.rgb = fragmentColor.rgb + vec3(shinefactor);\n"
" gl_FragColor.a = fragmentColor.a * clamp(shinefactor * (fract(abs(gl_TexCoord[0].x))-anim_timer) * -10000.0,0.0,1.0);\n"
" }\n"
" if (effect_num == 1) {\n"
" float shinefactor = 1.0/(1.0 + pow((position.y-anim_timer), 2.0));\n"
" float shinefactor = 1.0/(1.0 + pow(abs(position.y-anim_timer), 2.0));\n"
" gl_FragColor.rgb = fragmentColor.rgb + vec3(shinefactor);\n"
" #ifdef FLAG_LIGHT\n"
" gl_FragColor.a = fragmentColor.a;\n"
+1 -1
View File
@@ -125,7 +125,7 @@ void profile_end(char* name)
samples[i].open_profiles--;
// count all parents and find the immediate parent
while(samples[inner].valid && inner < (int)samples.size()) {
while(inner < (int)samples.size() && samples[inner].valid) {
if(samples[inner].open_profiles > 0) {
// found a parent (any open profiles are parents)
num_parents++;
+2 -108
View File
@@ -311,6 +311,7 @@ const float PI2 = (PI*2.0f);
// half values
const float PI_2 = (PI/2.0f);
const int RAND_MAX_2 = (RAND_MAX/2);
const float RAND_MAX_1f = (1.0f / RAND_MAX);
#define ANG_TO_RAD(x) ((x)*PI/180)
@@ -318,113 +319,6 @@ const int RAND_MAX_2 = (RAND_MAX/2);
extern int Fred_running; // Is Fred running, or FreeSpace?
//======================================================================================
//====== D E B U G C O N S O L E S T U F F ========================
//======================================================================================
// Here is a a sample command to toggle something that would
// be called by doing "toggle it" from the debug console command window/
/*
DCF(toggle_it,"description")
{
if (Dc_command) {
This_var = !This_var;
}
if (Dc_help) {
dc_printf( "Usage: sample\nToggles This_var on/off.\n" );
}
if (Dc_status) {
dc_printf( "The status is %d.\n", This_var );
}
*/
class debug_command {
public:
char *name;
char *help;
void (*func)();
debug_command(char *name,char *help,void (*func)()); // constructor
};
#define DCF(function_name,help_text) \
void dcf_##function_name(); \
debug_command dc_##function_name(#function_name,help_text,dcf_##function_name); \
void dcf_##function_name()
// Starts the debug console
extern void debug_console( void (*func)() = NULL );
// The next three variables tell your function what to do. It should
// only change something if the dc_command is set. A minimal function
// needs to process the dc_command. Usually, these will be called in
// these combinations:
// dc_command=true, dc_status=true means process it and show status
// dc_help=true means show help only
// dc_status=true means show status only
// I would recommend doing this in each function:
// if (dc_command) { process command }
// if (dc_help) { print out help }
// if (dc_status) { print out status }
// with the last two being optional
extern int Dc_command; // If this is set, then process the command
extern int Dc_help; // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
extern int Dc_status; // If this is set, then print out the current status of the command.
void dc_get_arg(uint flags); // Gets the next argument. If it doesn't match the flags, this function will print an error and not return.
extern char *Dc_arg; // The (lowercased) string value of the argument retrieved from dc_arg
extern char *Dc_arg_org; // Dc_arg before it got converted to lowercase
extern uint Dc_arg_type; // The type of dc_arg.
extern char *Dc_command_line; // The rest of the command line, from the end of the last processed arg on.
extern int Dc_arg_int; // If Dc_arg_type & ARG_INT or ARG_HEX is set, then this is the value
extern ubyte Dc_arg_ubyte; // If Dc_arg_type & ARG_UBYTE is set, then this is the value
extern float Dc_arg_float; // If Dc_arg_type & ARG_FLOAT is set, then this is the value
// Outputs text to the console
void dc_printf( char *format, ... );
// Each dc_arg_type can have one or more of these flags set.
// This is because some things can fit into two categories.
// Like 1 can be an integer, a float, a string, or a true boolean
// value.
#define ARG_NONE (1<<0) // no argument
#define ARG_ANY 0xFFFFFFFF // Anything.
#define ARG_STRING (1<<1) // any valid string
#define ARG_QUOTE (1<<2) // a quoted string
#define ARG_INT (1<<3) // a valid integer
#define ARG_FLOAT (1<<4) // a valid floating point number
// some specific commonly used predefined types. Can add up to (1<<31)
#define ARG_HEX (1<<5) // a valid hexadecimal integer. Note that ARG_INT will always be set also in this case.
#define ARG_TRUE (1<<6) // on, true, non-zero number
#define ARG_FALSE (1<<7) // off, false, zero
#define ARG_PLUS (1<<8) // Plus sign
#define ARG_MINUS (1<<9) // Minus sign
#define ARG_COMMA (1<<10) // a comma
#define ARG_UBYTE (1<<11) // a valid ubyte
// A shortcut for boolean only variables.
// Example:
// DCF_BOOL( lighting, Show_lighting )
//
#define DCF_BOOL( function_name, bool_variable ) \
void dcf_##function_name(); \
debug_command dc_##function_name(#function_name,"Toggles "#bool_variable,dcf_##function_name ); \
void dcf_##function_name() { \
if ( Dc_command ) { \
dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE); \
if ( Dc_arg_type & ARG_TRUE ) bool_variable = 1; \
else if ( Dc_arg_type & ARG_FALSE ) bool_variable = 0; \
else if ( Dc_arg_type & ARG_NONE ) bool_variable ^= 1; \
} \
if ( Dc_help ) dc_printf( "Usage: %s [bool]\nSets %s to true or false. If nothing passed, then toggles it.\n", #function_name, #bool_variable ); \
if ( Dc_status ) dc_printf( "%s is %s\n", #function_name, (bool_variable?"TRUE":"FALSE") ); \
}
//======================================================================================
//======================================================================================
//======================================================================================
@@ -435,7 +329,7 @@ void dc_printf( char *format, ... );
// Some constants for stuff
#define MAX_FILENAME_LEN 32 // Length for filenames, ie "title.pcx"
#define MAX_PATH_LEN 128 // Length for pathnames, ie "c:\bitmaps\title.pcx"
#define MAX_PATH_LEN 256 // Length for pathnames, ie "c:\bitmaps\title.pcx"
// contants and defined for byteswapping routines (useful for mac)
+7 -12
View File
@@ -22,11 +22,6 @@
#if !defined(NO_SAFE_STRINGS) && ( !defined( _MSC_VER ) || ( defined( _MSC_VER ) && _MSC_VER >= 1400 /* && !defined(NDEBUG) */ ))
/* We don't have this here - no standard library stuff included */
#ifndef NULL
#define NULL 0
#endif
/* An implementation of strcpy_s
* We're not going to actually fully behave like the MS debug version.
*/
@@ -39,14 +34,14 @@ errno_t scp_strcpy_s( const char* file, int line, char* strDest, size_t sizeInBy
if ( !strDest || !strSource )
{
if ( strDest )
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( EINVAL );
return EINVAL;
}
if ( sizeInBytes == 0 )
{
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
@@ -58,7 +53,7 @@ errno_t scp_strcpy_s( const char* file, int line, char* strDest, size_t sizeInBy
if ( bufferLeft == 0 )
{
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
@@ -75,14 +70,14 @@ errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBy
if ( !strDest || !strSource )
{
if ( strDest )
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( EINVAL );
return EINVAL;
}
if ( bufferLeft == 0 )
{
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
@@ -98,7 +93,7 @@ errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBy
if ( bufferLeft == 0 )
{
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
@@ -108,7 +103,7 @@ errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBy
if ( bufferLeft == 0 )
{
*strDest = NULL;
*strDest = '\0';
__safe_strings_error_handler( ERANGE );
return ERANGE;
}
+119 -101
View File
@@ -8,7 +8,7 @@
*/
#include "debugconsole/console.h"
#include "globalincs/pstypes.h"
#include "globalincs/systemvars.h"
#include "io/timer.h"
@@ -17,6 +17,7 @@
fix Missiontime;
fix Skybox_timestamp;
fix Frametime;
int Framecount=0;
@@ -245,76 +246,79 @@ monitor::monitor( char *_name )
int Monitor_inited = 0;
char Monitor_filename[128];
char Monitor_filename[MAX_PATH_LEN];
fix monitor_last_time = -1;
DCF(monitor,"Monitors game performace")
DCF(monitor,"Monitors game performace by saving to file")
{
if ( Dc_command ) {
dc_get_arg(ARG_STRING|ARG_NONE);
if ( Dc_arg_type == ARG_NONE ) {
if ( Monitor_inited ) {
Monitor_inited = 0;
SCP_string filename;
if (dc_optional_string_either("help", "--help")) {
dc_printf("Usage: monitor [filename]\n");
dc_printf("Outputs monitoring info to [filename]. No filename turns it off\n" );
return;
}
if (dc_maybe_stuff_string_white(filename)) {
if ( Monitor_inited ) {
dc_printf( "Monitor already on\n" );
} else {
Monitor_inited = 1;
strcpy_s(Monitor_filename, filename.c_str());
// Reset them all
int i;
for (i=0; i<Num_monitors; i++ ) {
Monitor[i]->value = 0;
Monitor[i]->sum = 0;
Monitor[i]->cnt = 0;
Monitor[i]->min = 0;
Monitor[i]->max = 0;
}
FILE *fp = fopen( Monitor_filename, "wt" );
if ( fp ) {
for (i=0; i<Num_monitors; i++ ) {
if ( i > 0 ) {
fprintf( fp, "\t" );
}
fprintf( fp, "%s", Monitor[i]->name );
}
fprintf( fp, "\n" );
fclose(fp);
}
dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
monitor_last_time = -1;
}
} else {
// Turn off monitoring
if ( Monitor_inited ) {
Monitor_inited = 0;
/*
FILE *fp = fopen( Monitor_filename, "at" );
if ( fp ) {
fprintf( fp, "\n\n" );
fprintf( fp, "Name\tMin\tMax\tAvg\n" );
for (int i=0; i<Num_monitors; i++ ) {
if ( Monitor[i]->cnt > 0 ) {
fprintf( fp, "%s\t%d\t%d\t%d\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max, Monitor[i]->sum / Monitor[i]->cnt );
} else {
fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
}
FILE *fp = fopen( Monitor_filename, "at" );
if ( fp ) {
fprintf( fp, "\n\n" );
fprintf( fp, "Name\tMin\tMax\tAvg\n" );
for (int i=0; i<Num_monitors; i++ ) {
if ( Monitor[i]->cnt > 0 ) {
fprintf( fp, "%s\t%d\t%d\t%d\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max, Monitor[i]->sum / Monitor[i]->cnt );
} else {
fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
}
fclose(fp);
}
fclose(fp);
}
*/
dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
} else {
dc_printf( "Monitor isn't on\n" );
}
dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
} else {
if ( Monitor_inited ) {
dc_printf( "Monitor already on\n" );
} else {
Monitor_inited = 1;
strcpy_s( Monitor_filename, Dc_arg );
// Reset them all
int i;
for (i=0; i<Num_monitors; i++ ) {
Monitor[i]->value = 0;
Monitor[i]->sum = 0;
Monitor[i]->cnt = 0;
Monitor[i]->min = 0;
Monitor[i]->max = 0;
}
FILE *fp = fopen( Monitor_filename, "wt" );
if ( fp ) {
for (i=0; i<Num_monitors; i++ ) {
if ( i > 0 ) {
fprintf( fp, "\t" );
}
fprintf( fp, "%s", Monitor[i]->name );
}
fprintf( fp, "\n" );
fclose(fp);
}
dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
monitor_last_time = -1;
}
dc_printf( "Monitor isn't on\n" );
}
}
if ( Dc_help ) {
dc_printf( "Usage: monitor filename\nOutputs monitoring info to filename. No filename turns it off\n" );
}
}
@@ -508,44 +512,41 @@ int current_detail_level()
#ifndef NDEBUG
DCF(detail_level,"Change the detail level")
{
if ( Dc_command ) {
dc_get_arg(ARG_INT|ARG_NONE);
if ( Dc_arg_type & ARG_NONE ) {
Game_detail_level = 0;
dc_printf( "Detail level reset\n" );
}
if ( Dc_arg_type & ARG_INT ) {
Game_detail_level = Dc_arg_int;
}
int value;
if (dc_optional_string_either("help", "--help")) {
dc_printf( "Usage: detail_level [n]\n");
dc_printf("[n] -- is detail level.\n");
dc_printf("\t0 is 'normal' detail,\n");
dc_printf("\tnegative values are lower, and\n");
dc_printf("\tpositive values are higher.\n\n");
dc_printf("No parameter resets it to default.\n");
return;
}
if ( Dc_help )
dc_printf( "Usage: detail_level [n]\nn is detail level. 0 normal, - lower, + higher, -2 to 2 usually\nNo parameter resets it to default.\n" );
if ( Dc_status )
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
dc_printf("Detail level set to %d\n", Game_detail_level);
return;
}
if (dc_maybe_stuff_int(&value)) {
Game_detail_level = value;
dc_printf("Detail level set to %i\n", Game_detail_level);
} else {
Game_detail_level = 0;
dc_printf("Detail level reset\n");
}
}
DCF(detail, "Turns on/off parts of the game for speed testing" )
{
if ( Dc_command ) {
dc_get_arg(ARG_INT|ARG_NONE);
if ( Dc_arg_type & ARG_NONE ) {
if ( Game_detail_flags == DETAIL_DEFAULT ) {
Game_detail_flags = DETAIL_FLAG_CLEAR;
dc_printf( "Detail flags set lowest (except has screen clear)\n" );
} else {
Game_detail_flags = DETAIL_DEFAULT;
dc_printf( "Detail flags set highest\n" );
}
}
if ( Dc_arg_type & ARG_INT ) {
Game_detail_flags ^= Dc_arg_int;
}
}
int value;
if ( Dc_help ) {
dc_printf( "Usage: detail [n]\nn is detail bit to toggle.\n" );
if (dc_optional_string_either("help", "--help")) {
dc_printf( "Usage: detail [n]\n");
dc_printf("[n] is detail bit to toggle:\n" );
dc_printf( " 1: draw the stars\n" );
dc_printf( " 2: draw the nebulas\n" );
dc_printf( " 4: draw the motion debris\n" );
@@ -555,21 +556,38 @@ DCF(detail, "Turns on/off parts of the game for speed testing" )
dc_printf( " 64: clear screen background after each frame\n" );
dc_printf( " 128: draw hud stuff\n" );
dc_printf( " 256: draw fireballs\n" );
dc_printf( " 512: do collision detection\n" );
dc_printf( " 512: do collision detection\n\n" );
dc_printf("No argument will toggle between highest/lowest detail settings\n");
return;
}
if ( Dc_status ) {
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
dc_printf("Detail flags set to 0x%08x\n", Game_detail_flags);
dc_printf( " 1: draw the stars: %s\n", (Game_detail_flags&1?"on":"off") );
dc_printf( " 2: draw the nebulas: %s\n", (Game_detail_flags&2?"on":"off") );
dc_printf( " 4: draw the motion debris: %s\n", (Game_detail_flags&4?"on":"off") );
dc_printf( " 8: draw planets: %s\n", (Game_detail_flags&8?"on":"off") );
dc_printf( " 16: draw models not as blobs: %s\n", (Game_detail_flags&16?"on":"off") );
dc_printf( " 32: draw lasers not as pixels: %s\n", (Game_detail_flags&32?"on":"off") );
dc_printf( " 64: clear screen background after each frame: %s\n", (Game_detail_flags&64?"on":"off") );
dc_printf( " 128: draw hud stuff: %s\n", (Game_detail_flags&128?"on":"off") );
dc_printf( " 256: draw fireballs: %s\n", (Game_detail_flags&256?"on":"off") );
dc_printf( " 512: do collision detection: %s\n", (Game_detail_flags&512?"on":"off") );
dc_printf( " 1: draw the stars: %s\n", ((Game_detail_flags & 1) ? "on" : "off"));
dc_printf( " 2: draw the nebulas: %s\n", ((Game_detail_flags & 2)?"on" : "off"));
dc_printf( " 4: draw the motion debris: %s\n", ((Game_detail_flags & 4) ? "on" : "off"));
dc_printf( " 8: draw planets: %s\n", ((Game_detail_flags & 8) ? "on" : "off"));
dc_printf( " 16: draw models not as blobs: %s\n", ((Game_detail_flags & 16) ? "on" : "off"));
dc_printf( " 32: draw lasers not as pixels: %s\n", ((Game_detail_flags & 32) ? "on" : "off"));
dc_printf( " 64: clear screen background after each frame: %s\n", ((Game_detail_flags & 64) ? "on" : "off"));
dc_printf( " 128: draw hud stuff: %s\n", ((Game_detail_flags & 128) ? "on" : "off"));
dc_printf( " 256: draw fireballs: %s\n", ((Game_detail_flags & 256) ? "on" : "off"));
dc_printf( " 512: do collision detection: %s\n", ((Game_detail_flags & 512) ? "on" : "off"));
return;
}
if (dc_maybe_stuff_int(&value)) {
Game_detail_flags ^= value;
} else {
if (Game_detail_flags == DETAIL_DEFAULT) {
Game_detail_flags = DETAIL_FLAG_CLEAR;
dc_printf( "Detail flags set lowest (except has screen clear)\n" );
} else {
Game_detail_flags = DETAIL_DEFAULT;
dc_printf( "Detail flags set highest\n" );
}
}
}
#endif
+1
View File
@@ -80,6 +80,7 @@ typedef struct vci {
} vci;
extern fix Missiontime;
extern fix Skybox_timestamp;
extern fix Frametime;
extern int Framecount;
+3 -2
View File
@@ -34,8 +34,9 @@
#define FS_VERSION_MAJOR 3 // major version
#define FS_VERSION_MINOR 7 // increase by 1 for minor revs
#define FS_VERSION_BUILD 1 // bugfix release
#define FS_VERSION_REVIS 0000 // SVN revision
#define FS_VERSION_BUILD 2 // bugfix release
#define FS_VERSION_REVIS 11329 // SVN revision
//#define FS_VERSION_IDENT NOX("custom") // special build release identifier, must be a string (don't define unless it's supposed to be used!!)
#define VERSION_LOC_FNAME "version.nfo"
#define MOTD_LOC_FNAME "motd.txt"
+18 -6
View File
@@ -8,6 +8,7 @@
#include <map>
#include <string>
#include <queue>
#include <deque>
#if defined __GNUC__
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
@@ -21,12 +22,19 @@
#endif // __GNUC__
#if ! defined __GNUC__
#include <hash_map>
#if defined(_MSC_VER) && _MSC_VER < 1400
#define SCP_hash_map std::hash_map
#else
#define SCP_hash_map stdext::hash_map
#endif
#if defined(_MSC_VER)
#if _MSC_VER < 1900
#include <hash_map>
#if _MSC_VER < 1400
#define SCP_hash_map std::hash_map
#else
#define SCP_hash_map stdext::hash_map
#endif
#else
#include <unordered_map>
#define SCP_hash_map std::unordered_map
#endif
#endif
#endif // ! defined __GNUC__
#if defined(_MSC_VER) && _MSC_VER >= 1400 || !defined(_MSC_VER)
@@ -127,6 +135,9 @@ class SCP_multimap : public std::multimap<T, U, std::less<T>, SCP_vm_allocator<s
template< typename T >
class SCP_queue : public std::queue< T, std::deque< T, SCP_vm_allocator< T > > > { };
template< typename T >
class SCP_deque : public std::deque< T, SCP_vm_allocator< T > > { };
template <class T1, class T2>
bool operator==(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw()
{
@@ -145,6 +156,7 @@ bool operator!=(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw(
#define SCP_map std::map
#define SCP_multimap std::multimap
#define SCP_queue std::queue
#define SCP_deque std::deque
#define SCP_vector std::vector
#define SCP_list std::list
+38 -27
View File
@@ -33,6 +33,7 @@
#include "cmdline/cmdline.h"
#include "parse/lua.h"
#include "parse/parselo.h"
#include "debugconsole/console.h"
#if defined( SHOW_CALL_STACK ) && defined( PDB_DEBUGGING )
# include "globalincs/mspdb_callstack.h"
@@ -151,15 +152,20 @@ size_t DumpBuffer :: Size() const
void DumpBuffer :: Printf( const char* format, ... )
{
va_list argPtr ;
int pos = current - buffer;
int max = BUFFER_SIZE - pos;
// protect against obvious buffer overflow
if( current - buffer < BUFFER_SIZE )
{
va_list argPtr ;
va_start( argPtr, format ) ;
int count = vsprintf( current, format, argPtr ) ;
va_end( argPtr ) ;
current += count ;
}
if (pos >= BUFFER_SIZE)
return;
va_start( argPtr, format ) ;
vsnprintf( current, max-1, format, argPtr ) ;
va_end( argPtr ) ;
current[max-1] = '\0';
current += strlen(current);
}
@@ -973,11 +979,13 @@ void _cdecl WinAssert(char * text, char * filename, int linenum )
void _cdecl WinAssert(char * text, char * filename, int linenum, const char * format, ... )
{
int val;
va_list args;
memset( AssertText1, 0, sizeof(AssertText1) );
memset( AssertText2, 0, sizeof(AssertText2) );
va_start(args, format);
vsprintf(AssertText2, format, args);
vsnprintf(AssertText2, sizeof(AssertText2)-1, format, args);
va_end(args);
// this stuff migt be really useful for solving bug reports and user errors. We should output it!
@@ -994,7 +1002,7 @@ void _cdecl WinAssert(char * text, char * filename, int linenum, const char * fo
gr_activate(0);
filename = strrchr(filename, '\\')+1;
sprintf( AssertText1, "Assert: %s\r\nFile: %s\r\nLine: %d\r\n%s\r\n", text, filename, linenum, AssertText2 );
snprintf( AssertText1, sizeof(AssertText1)-1, "Assert: %s\r\nFile: %s\r\nLine: %d\r\n%s\r\n", text, filename, linenum, AssertText2 );
#if defined( SHOW_CALL_STACK ) && defined( PDB_DEBUGGING )
/* Dump the callstack */
@@ -1068,15 +1076,6 @@ void LuaError(struct lua_State *L, char *format, ...)
gr_activate(0);
/*
va_start(args, format);
vsprintf(AssertText1,format,args);
va_end(args);
*/
//filename = strrchr(filename, '\\')+1;
//sprintf(AssertText2,"LuaError: %s\r\nFile: %s\r\nLine: %d\r\n", AssertText1, filename, line );
dumpBuffer.Clear();
//WMC - if format is set to NULL, assume this is acting as an
//error handler for Lua.
@@ -1088,10 +1087,15 @@ void LuaError(struct lua_State *L, char *format, ...)
else
{
va_list args;
memset(AssertText1, 0, sizeof(AssertText1));
memset(AssertText2, 0, sizeof(AssertText2));
va_start(args, format);
vsprintf(AssertText1,format,args);
dumpBuffer.Printf(AssertText1);
vsnprintf(AssertText1, sizeof(AssertText1)-1, format,args);
va_end(args);
dumpBuffer.Printf(AssertText1);
}
dumpBuffer.Printf( "\r\n" );
@@ -1192,12 +1196,15 @@ void _cdecl Error( const char * filename, int line, const char * format, ... )
int val;
va_list args;
memset( AssertText1, 0, sizeof(AssertText1) );
memset( AssertText2, 0, sizeof(AssertText2) );
va_start(args, format);
vsprintf(AssertText1, format, args);
vsnprintf(AssertText1, sizeof(AssertText1)-1, format, args);
va_end(args);
filename = strrchr(filename, '\\')+1;
sprintf(AssertText2, "Error: %s\r\nFile: %s\r\nLine: %d\r\n", AssertText1, filename, line);
snprintf(AssertText2, sizeof(AssertText2)-1, "Error: %s\r\nFile: %s\r\nLine: %d\r\n", AssertText1, filename, line);
mprintf(("ERROR: %s\r\nFile: %s\r\nLine: %d\r\n", AssertText1, filename, line));
Messagebox_active = true;
@@ -1265,9 +1272,13 @@ void _cdecl WarningEx( char *filename, int line, const char *format, ... )
if (Cmdline_extra_warn) {
char msg[sizeof(AssertText1)];
va_list args;
memset(msg, 0, sizeof(msg));
va_start(args, format);
vsprintf(msg, format, args);
vsnprintf(msg, sizeof(msg)-1, format, args);
va_end(args);
Warning(filename, line, msg);
}
#endif
@@ -1289,7 +1300,7 @@ void _cdecl Warning( char *filename, int line, const char *format, ... )
memset( AssertText2, 0, sizeof(AssertText2) );
va_start(args, format);
vsprintf(AssertText1, format, args);
vsnprintf(AssertText1, sizeof(AssertText1) - 1, format, args);
va_end(args);
slen = strlen(AssertText1);
@@ -1522,7 +1533,7 @@ void windebug_memwatch_init()
#endif
int Watch_malloc = 0;
DCF_BOOL(watch_malloc, Watch_malloc )
DCF_BOOL(watch_malloc, Watch_malloc );
// Returns 0 if not enough RAM.
int vm_init(int min_heap_size)
+382 -113
View File
@@ -31,6 +31,8 @@
#include "parse/scripting.h"
#include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
#include "io/keycontrol.h" // m!m
#include "debugconsole/console.h"
#include "debugconsole/console.h"
#if defined(SCP_UNIX) && !defined(__APPLE__)
@@ -88,75 +90,178 @@ float Max_draw_distance = Default_max_draw_distance;
static int GL_cursor_nframes = 0;
// Pre-computed screen resize vars
static float Gr_full_resize_X = 1.0f, Gr_full_resize_Y = 1.0f;
static float Gr_resize_X = 1.0f, Gr_resize_Y = 1.0f;
static float Gr_unsize_X = 1.0f, Gr_unsize_Y = 1.0f;
static float Gr_menu_offset_X = 0.0f, Gr_menu_offset_Y = 0.0f;
static float Gr_menu_zoomed_offset_X = 0.0f, Gr_menu_zoomed_offset_Y = 0.0f;
float Gr_save_full_resize_X = 1.0f, Gr_save_full_resize_Y = 1.0f;
float Gr_save_resize_X = 1.0f, Gr_save_resize_Y = 1.0f;
float Gr_save_unsize_X = 1.0f, Gr_save_unsize_Y = 1.0f;
float Gr_save_menu_offset_X = 0.0f, Gr_save_menu_offset_Y = 0.0f;
float Gr_save_menu_zoomed_offset_X = 0.0f, Gr_save_menu_zoomed_offset_Y = 0.0f;
bool Save_custom_screen_size;
void gr_set_screen_scale(int w, int h)
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, bool force_stretch)
{
Gr_resize_X = (float)gr_screen.max_w / (float)w;
Gr_resize_Y = (float)gr_screen.max_h / (float)h;
bool do_zoom = zoom_w > 0 && zoom_h > 0 && (zoom_w != w || zoom_h != h);
Gr_unsize_X = (float)w / (float)gr_screen.max_w;
Gr_unsize_Y = (float)h / (float)gr_screen.max_h;
Gr_full_resize_X = (float)max_w / (float)w;
Gr_full_resize_Y = (float)max_h / (float)h;
Save_custom_screen_size = gr_screen.custom_size;
if (do_zoom) {
float aspect_quotient = ((float)max_w / (float)max_h) / ((float)zoom_w / (float)zoom_h);
gr_screen.custom_size = true;
}
Gr_resize_X = (float)max_w / (float)zoom_w / ((aspect_quotient > 1.0f) ? aspect_quotient : 1.0f);
Gr_resize_Y = (float)max_h / (float)zoom_h * ((aspect_quotient < 1.0f) ? aspect_quotient : 1.0f);
void gr_set_screen_scale(int w, int h, int max_w, int max_h)
{
Gr_resize_X = (float)max_w / (float)w;
Gr_resize_Y = (float)max_h / (float)h;
Gr_menu_offset_X = (max_w - w * Gr_resize_X) / 2.0f;
Gr_menu_offset_Y = (max_h - h * Gr_resize_Y) / 2.0f;
Gr_unsize_X = (float)w / (float)max_w;
Gr_unsize_Y = (float)h / (float)max_h;
Gr_menu_zoomed_offset_X = (Gr_menu_offset_X >= 0.0f) ? Gr_menu_offset_X : 0.0f;
Gr_menu_zoomed_offset_Y = (Gr_menu_offset_Y >= 0.0f) ? Gr_menu_offset_Y : 0.0f;
Save_custom_screen_size = gr_screen.custom_size;
if (force_stretch || Cmdline_stretch_menu) {
if (Gr_menu_offset_X > 0.0f) {
Gr_resize_X = Gr_full_resize_X;
Gr_menu_offset_X = Gr_menu_zoomed_offset_X = 0.0f;
}
if (Gr_menu_offset_Y > 0.0f) {
Gr_resize_Y = Gr_full_resize_Y;
Gr_menu_offset_Y = Gr_menu_zoomed_offset_Y = 0.0f;
}
}
} else {
if (force_stretch || Cmdline_stretch_menu) {
Gr_resize_X = Gr_full_resize_X;
Gr_resize_Y = Gr_full_resize_Y;
gr_screen.custom_size = true;
Gr_menu_offset_X = Gr_menu_zoomed_offset_X = 0.0f;
Gr_menu_offset_Y = Gr_menu_zoomed_offset_Y = 0.0f;
} else {
float aspect_quotient = ((float)max_w / (float)max_h) / ((float)w / (float)h);
Gr_resize_X = Gr_full_resize_X / ((aspect_quotient > 1.0f) ? aspect_quotient : 1.0f);
Gr_resize_Y = Gr_full_resize_Y * ((aspect_quotient < 1.0f) ? aspect_quotient : 1.0f);
Gr_menu_offset_X = Gr_menu_zoomed_offset_X = (aspect_quotient > 1.0f) ? ((max_w - w * Gr_resize_X) / 2.0f) : 0.0f;
Gr_menu_offset_Y = Gr_menu_zoomed_offset_Y = (aspect_quotient < 1.0f) ? ((max_h - h * Gr_resize_Y) / 2.0f) : 0.0f;
}
}
gr_screen.custom_size = (w != max_w || h != max_h);
if (gr_screen.rendering_to_texture == -1) {
gr_screen.max_w_unscaled = w;
gr_screen.max_h_unscaled = h;
if (do_zoom) {
gr_screen.max_w_unscaled_zoomed = gr_screen.max_w_unscaled + fl2i(Gr_menu_offset_X * 2.0f / Gr_resize_X);
gr_screen.max_h_unscaled_zoomed = gr_screen.max_h_unscaled + fl2i(Gr_menu_offset_Y * 2.0f / Gr_resize_Y);
if (gr_screen.max_w_unscaled_zoomed > gr_screen.max_w_unscaled) {
gr_screen.max_w_unscaled_zoomed = gr_screen.max_w_unscaled;
}
if (gr_screen.max_h_unscaled_zoomed > gr_screen.max_h_unscaled) {
gr_screen.max_h_unscaled_zoomed = gr_screen.max_h_unscaled;
}
} else {
gr_screen.max_w_unscaled_zoomed = gr_screen.max_w_unscaled;
gr_screen.max_h_unscaled_zoomed = gr_screen.max_h_unscaled;
}
}
}
void gr_reset_screen_scale()
{
Gr_full_resize_X = Gr_save_full_resize_X;
Gr_full_resize_Y = Gr_save_full_resize_Y;
Gr_resize_X = Gr_save_resize_X;
Gr_resize_Y = Gr_save_resize_Y;
Gr_unsize_X = Gr_save_unsize_X;
Gr_unsize_Y = Gr_save_unsize_Y;
Gr_menu_offset_X = Gr_save_menu_offset_X;
Gr_menu_offset_Y = Gr_save_menu_offset_Y;
Gr_menu_zoomed_offset_X = Gr_save_menu_zoomed_offset_X;
Gr_menu_zoomed_offset_Y = Gr_save_menu_zoomed_offset_Y;
gr_screen.custom_size = Save_custom_screen_size;
if (gr_screen.rendering_to_texture == -1) {
gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = (gr_screen.res == GR_1024) ? 1024 : 640;
gr_screen.max_h_unscaled = gr_screen.max_h_unscaled_zoomed = (gr_screen.res == GR_1024) ? 768 : 480;
}
}
/**
* This function is to be called if you wish to scale GR_1024 or GR_640 x and y positions or
* lengths in order to keep the correctly scaled to nonstandard resolutions
*
* @param x X value (width to be scaled), can be NULL
* @param y Y value (height to be scaled), can be NULL
* @param x X value, can be NULL
* @param y Y value, can be NULL
* @param w width, can be NULL
* @param h height, can be NULL
* @param resize_mode
* @return always true unless error
*/
bool gr_resize_screen_pos(int *x, int *y)
bool gr_resize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
{
if ( !gr_screen.custom_size && (gr_screen.rendering_to_texture == -1) ) {
if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
return false;
}
float xy_tmp = 0.0f;
if ( x && (*x != 0) ) {
xy_tmp = (*x) * Gr_resize_X;
(*x) = fl2i(xy_tmp);
if ( x ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*x) * Gr_full_resize_X;
break;
case GR_RESIZE_MENU:
xy_tmp = (*x) * Gr_resize_X + Gr_menu_offset_X;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = (*x) * Gr_resize_X + Gr_menu_zoomed_offset_X;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*x) * Gr_resize_X;
break;
}
(*x) = fl2ir(xy_tmp);
}
if ( y && (*y != 0) ) {
xy_tmp = (*y) * Gr_resize_Y;
(*y) = fl2i(xy_tmp);
if ( y ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*y) * Gr_full_resize_Y;
break;
case GR_RESIZE_MENU:
xy_tmp = (*y) * Gr_resize_Y + Gr_menu_offset_Y;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = (*y) * Gr_resize_Y + Gr_menu_zoomed_offset_Y;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*y) * Gr_resize_Y;
break;
}
(*y) = fl2ir(xy_tmp);
}
if ( w ) {
xy_tmp = (*w) * ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_X : Gr_resize_X);
(*w) = fl2ir(xy_tmp);
}
if ( h ) {
xy_tmp = (*h) * ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_Y : Gr_resize_Y);
(*h) = fl2ir(xy_tmp);
}
return true;
@@ -164,26 +269,71 @@ bool gr_resize_screen_pos(int *x, int *y)
/**
*
* @param x X value (width to be unscaled), can be NULL
* @param y Y value (height to be unscaled), can be NULL
* @param x X value, can be NULL
* @param y Y value, can be NULL
* @param w width, can be NULL
* @param h height, can be NULL
* @param resize_mode
* @return always true unless error
*/
bool gr_unsize_screen_pos(int *x, int *y)
bool gr_unsize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
{
if ( !gr_screen.custom_size && (gr_screen.rendering_to_texture == -1) ) {
if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
return false;
}
float xy_tmp = 0.0f;
if ( x && (*x != 0) ) {
xy_tmp = (*x) * Gr_unsize_X;
(*x) = fl2i(xy_tmp);
if ( x ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*x) / Gr_full_resize_X;
break;
case GR_RESIZE_MENU:
xy_tmp = ((*x) - Gr_menu_offset_X) / Gr_resize_X;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = ((*x) - Gr_menu_zoomed_offset_X) / Gr_resize_X;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*x) / Gr_resize_X;
break;
}
(*x) = fl2ir(xy_tmp);
}
if ( y && (*y != 0) ) {
xy_tmp = (*y) * Gr_unsize_Y;
(*y) = fl2i(xy_tmp);
if ( y ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*y) / Gr_full_resize_Y;
break;
case GR_RESIZE_MENU:
xy_tmp = ((*y) - Gr_menu_offset_Y) / Gr_resize_Y;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = ((*y) - Gr_menu_zoomed_offset_Y) / Gr_resize_Y;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*y) / Gr_resize_Y;
break;
}
(*y) = fl2ir(xy_tmp);
}
if ( w ) {
xy_tmp = (*w) / ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_X : Gr_resize_X);
(*w) = fl2ir(xy_tmp);
}
if ( h ) {
xy_tmp = (*h) / ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_Y : Gr_resize_Y);
(*h) = fl2ir(xy_tmp);
}
return true;
@@ -193,42 +343,144 @@ bool gr_unsize_screen_pos(int *x, int *y)
* This function is to be called if you wish to scale GR_1024 or GR_640 x and y positions or
* lengths in order to keep the correctly scaled to nonstandard resolutions
*
* @param x X value (width to be scaled), can be NULL
* @param y Y value (height to be scaled), can be NULL
* @param x X value, can be NULL
* @param y Y value, can be NULL
* @param w width, can be NULL
* @param h height, can be NULL
* @param resize_mode
* @return always true unless error
*/
bool gr_resize_screen_posf(float *x, float *y)
bool gr_resize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
{
if ( !gr_screen.custom_size && (gr_screen.rendering_to_texture == -1) ) {
if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
return false;
}
if ( x && (*x != 0) )
(*x) *= Gr_resize_X;
float xy_tmp = 0.0f;
if ( y && (*y != 0) )
(*y) *= Gr_resize_Y;
if ( x ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*x) * Gr_full_resize_X;
break;
case GR_RESIZE_MENU:
xy_tmp = (*x) * Gr_resize_X + Gr_menu_offset_X;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = (*x) * Gr_resize_X + Gr_menu_zoomed_offset_X;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*x) * Gr_resize_X;
break;
}
(*x) = xy_tmp;
}
if ( y ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*y) * Gr_full_resize_Y;
break;
case GR_RESIZE_MENU:
xy_tmp = (*y) * Gr_resize_Y + Gr_menu_offset_Y;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = (*y) * Gr_resize_Y + Gr_menu_zoomed_offset_Y;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*y) * Gr_resize_Y;
break;
}
(*y) = xy_tmp;
}
if ( w ) {
xy_tmp = (*w) * ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_X : Gr_resize_X);
(*w) = xy_tmp;
}
if ( h ) {
xy_tmp = (*h) * ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_Y : Gr_resize_Y);
(*h) = xy_tmp;
}
return true;
}
/**
*
* @param x X value (width to be unscaled), can be NULL
* @param y Y value (height to be unscaled), can be NULL
* @param x X value, can be NULL
* @param y Y value, can be NULL
* @param w width, can be NULL
* @param h height, can be NULL
* @param resize_mode
* @return always true unless error
*/
bool gr_unsize_screen_posf(float *x, float *y)
bool gr_unsize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
{
if ( !gr_screen.custom_size && (gr_screen.rendering_to_texture == -1) ) {
if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
return false;
}
if ( x && (*x != 0) )
(*x) *= Gr_unsize_X;
float xy_tmp = 0.0f;
if ( y && (*y != 0) )
(*y) *= Gr_unsize_Y;
if ( x ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*x) / Gr_full_resize_X;
break;
case GR_RESIZE_MENU:
xy_tmp = ((*x) - Gr_menu_offset_X) / Gr_resize_X;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = ((*x) - Gr_menu_zoomed_offset_X) / Gr_resize_X;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*x) / Gr_resize_X;
break;
}
(*x) = xy_tmp;
}
if ( y ) {
switch (resize_mode) {
case GR_RESIZE_FULL:
xy_tmp = (*y) / Gr_full_resize_Y;
break;
case GR_RESIZE_MENU:
xy_tmp = ((*y) - Gr_menu_offset_Y) / Gr_resize_Y;
break;
case GR_RESIZE_MENU_ZOOMED:
xy_tmp = ((*y) - Gr_menu_zoomed_offset_Y) / Gr_resize_Y;
break;
case GR_RESIZE_MENU_NO_OFFSET:
xy_tmp = (*y) / Gr_resize_Y;
break;
}
(*y) = xy_tmp;
}
if ( w ) {
xy_tmp = (*w) / ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_X : Gr_resize_X);
(*w) = xy_tmp;
}
if ( h ) {
xy_tmp = (*h) / ((resize_mode == GR_RESIZE_FULL) ? Gr_full_resize_Y : Gr_resize_Y);
(*h) = xy_tmp;
}
return true;
}
@@ -266,12 +518,9 @@ DCF(clear_color, "set clear color r, g, b")
{
ubyte r, g, b;
dc_get_arg(ARG_UBYTE);
r = Dc_arg_ubyte;
dc_get_arg(ARG_UBYTE);
g = Dc_arg_ubyte;
dc_get_arg(ARG_UBYTE);
b = Dc_arg_ubyte;
dc_stuff_ubyte(&r);
dc_stuff_ubyte(&g);
dc_stuff_ubyte(&b);
// set the color
gr_set_clear_color(r, g, b);
@@ -340,8 +589,8 @@ void gr_screen_resize(int width, int height)
return;
}
gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = width;
gr_screen.save_max_h = gr_screen.max_h = gr_screen.max_h_unscaled = height;
gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = width;
gr_screen.save_max_h = gr_screen.max_h = gr_screen.max_h_unscaled = gr_screen.max_h_unscaled_zoomed = height;
gr_screen.offset_x = gr_screen.offset_x_unscaled = 0;
gr_screen.offset_y = gr_screen.offset_y_unscaled = 0;
@@ -356,12 +605,15 @@ void gr_screen_resize(int width, int height)
if (gr_screen.custom_size) {
gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
gr_unsize_screen_pos( &gr_screen.max_w_unscaled_zoomed, &gr_screen.max_h_unscaled_zoomed );
gr_unsize_screen_pos( &gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled );
gr_unsize_screen_pos( &gr_screen.clip_width_unscaled, &gr_screen.clip_height_unscaled );
}
gr_screen.save_max_w_unscaled = gr_screen.max_w_unscaled;
gr_screen.save_max_h_unscaled = gr_screen.max_h_unscaled;
gr_screen.save_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
gr_screen.save_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;
if (gr_screen.mode == GR_OPENGL) {
extern void opengl_setup_viewport();
@@ -382,7 +634,7 @@ static bool gr_init_sub(int mode, int width, int height, int depth)
gr_screen.custom_size = true;
}
if ( (width >= 1024) && (height >= 600) ) {
if ( (width >= GR_1024_THRESHOLD_WIDTH) && (height >= GR_1024_THRESHOLD_HEIGHT) ) {
res = GR_1024;
} else {
res = GR_640;
@@ -394,12 +646,30 @@ static bool gr_init_sub(int mode, int width, int height, int depth)
mode = GR_OPENGL;
}
Gr_save_resize_X = Gr_resize_X = (float)width / ((res == GR_1024) ? 1024.0f : 640.0f);
Gr_save_resize_Y = Gr_resize_Y = (float)height / ((res == GR_1024) ? 768.0f : 480.0f);
Save_custom_screen_size = gr_screen.custom_size;
Gr_save_unsize_X = Gr_unsize_X = ((res == GR_1024) ? 1024.0f : 640.0f) / (float)width;
Gr_save_unsize_Y = Gr_unsize_Y = ((res == GR_1024) ? 768.0f : 480.0f) / (float)height;
Gr_save_full_resize_X = Gr_full_resize_X = (float)width / ((res == GR_1024) ? 1024.0f : 640.0f);
Gr_save_full_resize_Y = Gr_full_resize_Y = (float)height / ((res == GR_1024) ? 768.0f : 480.0f);
if (gr_screen.custom_size && !Cmdline_stretch_menu) {
float aspect_quotient = ((float)width / (float)height) / (4.0f / 3.0f);
Gr_save_resize_X = Gr_resize_X = Gr_full_resize_X / ((aspect_quotient > 1.0f) ? aspect_quotient : 1.0f);
Gr_save_resize_Y = Gr_resize_Y = Gr_full_resize_Y * ((aspect_quotient < 1.0f) ? aspect_quotient : 1.0f);
Gr_save_menu_offset_X = Gr_menu_offset_X = (aspect_quotient > 1.0f) ? ((width - width / aspect_quotient) / 2.0f) : 0.0f;
Gr_save_menu_offset_Y = Gr_menu_offset_Y = (aspect_quotient < 1.0f) ? ((height - height * aspect_quotient) / 2.0f) : 0.0f;
} else {
Gr_save_resize_X = Gr_resize_X = Gr_full_resize_X;
Gr_save_resize_Y = Gr_resize_Y = Gr_full_resize_Y;
Gr_save_menu_offset_X = Gr_menu_offset_X = 0.0f;
Gr_save_menu_offset_Y = Gr_menu_offset_Y = 0.0f;
}
Gr_save_menu_zoomed_offset_X = Gr_menu_zoomed_offset_X = Gr_menu_offset_X;
Gr_save_menu_zoomed_offset_Y = Gr_menu_zoomed_offset_Y = Gr_menu_offset_Y;
gr_screen.signature = Gr_signature++;
gr_screen.bits_per_pixel = depth;
@@ -411,8 +681,8 @@ static bool gr_init_sub(int mode, int width, int height, int depth)
gr_screen.res = res;
gr_screen.aspect = 1.0f; // Normal PC screen
gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = width;
gr_screen.save_max_h = gr_screen.max_h = gr_screen.max_h_unscaled = height;
gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = width;
gr_screen.save_max_h = gr_screen.max_h = gr_screen.max_h_unscaled = gr_screen.max_h_unscaled_zoomed = height;
gr_screen.offset_x = gr_screen.offset_x_unscaled = 0;
gr_screen.offset_y = gr_screen.offset_y_unscaled = 0;
@@ -429,12 +699,15 @@ static bool gr_init_sub(int mode, int width, int height, int depth)
if (gr_screen.custom_size) {
gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
gr_unsize_screen_pos( &gr_screen.max_w_unscaled_zoomed, &gr_screen.max_h_unscaled_zoomed );
gr_unsize_screen_pos( &gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled );
gr_unsize_screen_pos( &gr_screen.clip_width_unscaled, &gr_screen.clip_height_unscaled );
}
gr_screen.save_max_w_unscaled = gr_screen.max_w_unscaled;
gr_screen.save_max_h_unscaled = gr_screen.max_h_unscaled;
gr_screen.save_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
gr_screen.save_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;
#ifdef WIN32
// FRED doesn't need this
@@ -831,7 +1104,7 @@ int gr_get_cursor_bitmap()
}
// new bitmap functions
void gr_bitmap(int _x, int _y, bool allow_scaling)
void gr_bitmap(int _x, int _y, int resize_mode)
{
int _w, _h;
float x, y, w, h;
@@ -849,9 +1122,8 @@ void gr_bitmap(int _x, int _y, bool allow_scaling)
h = i2fl(_h);
// I will tidy this up later - RT
if ( allow_scaling && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_posf(&x, &y);
gr_resize_screen_posf(&w, &h);
if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_posf(&x, &y, &w, &h, resize_mode);
}
memset(verts, 0, sizeof(verts));
@@ -885,7 +1157,7 @@ void gr_bitmap(int _x, int _y, bool allow_scaling)
gr_zbuffer_set(saved_zbuffer_mode);
}
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, bool allow_scaling)
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode)
{
float x, y, w, h;
vertex verts[4];
@@ -900,9 +1172,8 @@ void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u
h = i2fl(_h);
// I will tidy this up later - RT
if ( allow_scaling && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_posf(&x, &y);
gr_resize_screen_posf(&w, &h);
if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_posf(&x, &y, &w, &h, resize_mode);
}
memset(verts, 0, sizeof(verts));
@@ -937,16 +1208,15 @@ void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u
}
// NEW new bitmap functions -Bobboau
void gr_bitmap_list(bitmap_2d_list* list, int n_bm, bool allow_scaling)
void gr_bitmap_list(bitmap_2d_list* list, int n_bm, int resize_mode)
{
for (int i = 0; i < n_bm; i++) {
bitmap_2d_list *l = &list[i];
bm_get_info(gr_screen.current_bitmap, &l->w, &l->h, NULL, NULL, NULL);
if ( allow_scaling && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_pos(&l->x, &l->y);
gr_resize_screen_pos(&l->w, &l->h);
if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_pos(&l->x, &l->y, &l->w, &l->h, resize_mode);
}
}
@@ -955,7 +1225,7 @@ void gr_bitmap_list(bitmap_2d_list* list, int n_bm, bool allow_scaling)
// _->NEW<-_ NEW new bitmap functions -Bobboau
//takes a list of rectangles that have assosiated rectangles in a texture
void gr_bitmap_list(bitmap_rect_list* list, int n_bm, bool allow_scaling)
void gr_bitmap_list(bitmap_rect_list* list, int n_bm, int resize_mode)
{
for(int i = 0; i < n_bm; i++) {
bitmap_2d_list *l = &list[i].screen_rect;
@@ -965,9 +1235,8 @@ void gr_bitmap_list(bitmap_rect_list* list, int n_bm, bool allow_scaling)
bm_get_info(gr_screen.current_bitmap, &l->w, &l->h, NULL, NULL, NULL);
}
if ( allow_scaling && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_pos(&l->x, &l->y);
gr_resize_screen_pos(&l->w, &l->h);
if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
gr_resize_screen_pos(&l->x, &l->y, &l->w, &l->h, resize_mode);
}
}
@@ -1003,7 +1272,7 @@ void gr_pline_helper(vec3d *out, vec3d *in1, vec3d *in2, int thickness)
* is no more than 90 degrees away from a previous section.
* Moreover, it is _really_ intended for use with 45 degree angles.
*/
void gr_pline_special(vec3d **pts, int num_pts, int thickness,bool resize)
void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode)
{
vec3d s1, s2, e1, e2, dir;
vec3d last_e1, last_e2;
@@ -1012,6 +1281,8 @@ void gr_pline_special(vec3d **pts, int num_pts, int thickness,bool resize)
int saved_zbuffer_mode, idx;
int started_frame = 0;
int num_pts = pts->size();
// if we have less than 2 pts, bail
if(num_pts < 2) {
return;
@@ -1036,11 +1307,11 @@ void gr_pline_special(vec3d **pts, int num_pts, int thickness,bool resize)
int j;
for(idx=0; idx<num_pts-1; idx++) {
// get the start and endpoints
s1 = *pts[idx]; // start 1 (on the line)
gr_pline_helper(&s2, pts[idx], pts[idx+1], thickness); // start 2
e1 = *pts[idx+1]; // end 1 (on the line)
vm_vec_sub(&dir, pts[idx+1], pts[idx]);
vm_vec_add(&e2, &s2, &dir); // end 2
s1 = pts->at(idx); // start 1 (on the line)
e1 = pts->at(idx+1); // end 1 (on the line)
gr_pline_helper(&s2, &s1, &e1, thickness); // start 2
vm_vec_sub(&dir, &e1, &s1);
vm_vec_add(&e2, &s2, &dir); // end 2
// stuff coords
v[0].screen.xyw.x = (float)ceil(s1.xyz.x);
@@ -1088,9 +1359,9 @@ void gr_pline_special(vec3d **pts, int num_pts, int thickness,bool resize)
v[3].b = gr_screen.current_color.blue;
//We could really do this better...but oh well. _WMC
if(resize) {
if(resize_mode != GR_RESIZE_NONE) {
for(j=0;j<4;j++) {
gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y);
gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y,NULL,NULL,resize_mode);
}
}
@@ -1135,9 +1406,9 @@ void gr_pline_special(vec3d **pts, int num_pts, int thickness,bool resize)
v[2].b = gr_screen.current_color.blue;
//Inefficiency or flexibility? you be the judge -WMC
if(resize) {
if(resize_mode != GR_RESIZE_NONE) {
for(j=0;j<3;j++) {
gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y);
gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y,NULL,NULL,resize_mode);
}
}
@@ -1430,19 +1701,19 @@ poly_list& poly_list::operator = (poly_list &other_list)
return *this;
}
void gr_shield_icon(coord2d coords[6], bool resize)
void gr_shield_icon(coord2d coords[6], int resize_mode)
{
if (gr_screen.mode == GR_STUB) {
return;
}
if (resize) {
gr_resize_screen_pos(&coords[0].x, &coords[0].y);
gr_resize_screen_pos(&coords[1].x, &coords[1].y);
gr_resize_screen_pos(&coords[2].x, &coords[2].y);
gr_resize_screen_pos(&coords[3].x, &coords[3].y);
gr_resize_screen_pos(&coords[4].x, &coords[4].y);
gr_resize_screen_pos(&coords[5].x, &coords[5].y);
if (resize_mode != GR_RESIZE_NONE) {
gr_resize_screen_pos(&coords[0].x, &coords[0].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[1].x, &coords[1].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[2].x, &coords[2].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[3].x, &coords[3].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[4].x, &coords[4].y, NULL, NULL, resize_mode);
gr_resize_screen_pos(&coords[5].x, &coords[5].y, NULL, NULL, resize_mode);
}
g3_draw_2d_shield_icon(coords,
@@ -1452,15 +1723,14 @@ void gr_shield_icon(coord2d coords[6], bool resize)
gr_screen.current_color.alpha);
}
void gr_rect(int x, int y, int w, int h, bool resize)
void gr_rect(int x, int y, int w, int h, int resize_mode)
{
if (gr_screen.mode == GR_STUB) {
return;
}
if (resize) {
gr_resize_screen_pos(&x, &y);
gr_resize_screen_pos(&w, &h);
if (resize_mode != GR_RESIZE_NONE) {
gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
}
g3_draw_2d_rect(x, y, w, h,
@@ -1470,7 +1740,7 @@ void gr_rect(int x, int y, int w, int h, bool resize)
gr_screen.current_color.alpha);
}
void gr_shade(int x, int y, int w, int h, bool resize)
void gr_shade(int x, int y, int w, int h, int resize_mode)
{
int r, g, b, a;
@@ -1478,9 +1748,8 @@ void gr_shade(int x, int y, int w, int h, bool resize)
return;
}
if (resize) {
gr_resize_screen_pos(&x, &y);
gr_resize_screen_pos(&w, &h);
if (resize_mode != GR_RESIZE_NONE) {
gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
}
r = (int)gr_screen.current_shader.r;
+120 -55
View File
@@ -177,12 +177,63 @@ public:
i_last = j;
}
// Constructor
buffer_data(int n_vrts) :
flags(0), texture(-1), n_verts(n_vrts), index_offset(0),
i_first(1), i_last(0)
{
index = new(std::nothrow) uint[n_verts];
}
// Copy-constructor
buffer_data(const buffer_data& other)
{
index = new(std::nothrow) uint[other.n_verts];
for (size_t i=0; i < (size_t) other.n_verts; i++)
{
index[i] = other.index[i];
}
flags = other.flags;
texture = other.texture;
n_verts = other.n_verts;
i_first = other.i_first;
i_last = other.i_last;
index_offset = other.index_offset;
}
// Copy-assignment operator
buffer_data& operator=(const buffer_data& rhs)
{
if (this != &rhs)
{
delete [] index;
index = new(std::nothrow) uint[rhs.n_verts];
for (size_t i=0; i < (size_t) rhs.n_verts; i++)
{
index[i] = rhs.index[i];
}
flags = rhs.flags;
texture = rhs.texture;
n_verts = rhs.n_verts;
i_first = rhs.i_first;
i_last = rhs.i_last;
index_offset = rhs.index_offset;
}
return *this;
}
// Destructor
~buffer_data()
{
release();
}
private:
uint *index;
@@ -245,9 +296,11 @@ struct light;
typedef struct screen {
uint signature; // changes when mode or palette or width or height changes
int max_w, max_h; // Width and height
int max_w_unscaled, max_h_unscaled; // Width and height, should be 1024x768 or 640x480 in non-standard resolutions
int max_w_unscaled, max_h_unscaled;
int max_w_unscaled_zoomed, max_h_unscaled_zoomed;
int save_max_w, save_max_h; // Width and height
int save_max_w_unscaled, save_max_h_unscaled;
int save_max_w_unscaled_zoomed, save_max_h_unscaled_zoomed;
int res; // GR_640 or GR_1024
int mode; // What mode gr_init was called with.
float aspect, clip_aspect; // Aspect ratio, aspect of clip_width/clip_height
@@ -255,9 +308,9 @@ typedef struct screen {
int bits_per_pixel; // How many bits per pixel it is. (7,8,15,16,24,32)
int bytes_per_pixel; // How many bytes per pixel (1,2,3,4)
int offset_x, offset_y; // The offsets into the screen
int offset_x_unscaled, offset_y_unscaled; // Offsets into the screen, in 1024x768 or 640x480 dimensions
int offset_x_unscaled, offset_y_unscaled; // Offsets into the screen, in unscaled dimensions
int clip_width, clip_height;
int clip_width_unscaled, clip_height_unscaled; // Height and width of clip aread, in 1024x768 or 640x480 dimensions
int clip_width_unscaled, clip_height_unscaled; // Height and width of clip aread, in unscaled dimensions
// center of clip area
float clip_center_x, clip_center_y;
@@ -267,7 +320,7 @@ typedef struct screen {
// actually always 0, but it's nice to have the code work with
// arbitrary clipping regions.
int clip_left, clip_right, clip_top, clip_bottom;
// same as above except in 1024x768 or 640x480 dimensions
// same as above except in unscaled dimensions
int clip_left_unscaled, clip_right_unscaled, clip_top_unscaled, clip_bottom_unscaled;
int current_alphablend_mode; // See GR_ALPHABLEND defines above
@@ -308,7 +361,7 @@ typedef struct screen {
void (*gf_flash_alpha)(int r, int g, int b, int a);
// sets the clipping region
void (*gf_set_clip)(int x, int y, int w, int h, bool resize);
void (*gf_set_clip)(int x, int y, int w, int h, int resize_mode);
// resets the clipping region to entire screen
void (*gf_reset_clip)();
@@ -316,24 +369,24 @@ typedef struct screen {
// clears entire clipping region to current color
void (*gf_clear)();
// void (*gf_bitmap)(int x, int y, bool resize);
void (*gf_bitmap_ex)(int x, int y, int w, int h, int sx, int sy, bool resize);
// void (*gf_bitmap)(int x, int y, int resize_mode);
void (*gf_bitmap_ex)(int x, int y, int w, int h, int sx, int sy, int resize_mode);
void (*gf_aabitmap)(int x, int y, bool resize, bool mirror);
void (*gf_aabitmap_ex)(int x, int y, int w, int h, int sx, int sy, bool resize, bool mirror);
void (*gf_aabitmap)(int x, int y, int resize_mode, bool mirror);
void (*gf_aabitmap_ex)(int x, int y, int w, int h, int sx, int sy, int resize_mode, bool mirror);
void (*gf_string)(int x, int y, const char * text,bool resize);
void (*gf_string)(int x, int y, const char * text,int resize_mode);
// Draw a gradient line... x1,y1 is bright, x2,y2 is transparent.
void (*gf_gradient)(int x1, int y1, int x2, int y2, bool resize);
void (*gf_gradient)(int x1, int y1, int x2, int y2, int resize_mode);
void (*gf_circle)(int x, int y, int r, bool resize);
void (*gf_unfilled_circle)(int x, int y, int r, bool resize);
void (*gf_arc)(int x, int y, float r, float angle_start, float angle_end, bool fill, bool resize);
void (*gf_curve)(int x, int y, int r, int direction);
void (*gf_circle)(int x, int y, int r, int resize_mode);
void (*gf_unfilled_circle)(int x, int y, int r, int resize_mode);
void (*gf_arc)(int x, int y, float r, float angle_start, float angle_end, bool fill, int resize_mode);
void (*gf_curve)(int x, int y, int r, int direction, int resize_mode);
// Integer line. Used to draw a fast but pixely line.
void (*gf_line)(int x1, int y1, int x2, int y2, bool resize);
void (*gf_line)(int x1, int y1, int x2, int y2, int resize_mode);
// Draws an antialiased line is the current color is an
// alphacolor, otherwise just draws a fast line. This
@@ -342,7 +395,7 @@ typedef struct screen {
// not this if you have two 3d points.
void (*gf_aaline)(vertex *v1, vertex *v2);
void (*gf_pixel)( int x, int y, bool resize );
void (*gf_pixel)( int x, int y, int resize_mode );
// Scales current bitmap between va and vb with clipping
void (*gf_scaler)(vertex *va, vertex *vb, bool bw_bitmap );
@@ -424,7 +477,7 @@ typedef struct screen {
int (*gf_set_color_buffer)(int mode);
// cross fade
void (*gf_cross_fade)(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct);
void (*gf_cross_fade)(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct, int resize_mode);
// set a texture into cache. for sectioned bitmaps, pass in sx and sy to set that particular section of the bitmap
int (*gf_tcache_set)(int bitmap_id, int bitmap_type, float *u_scale, float *v_scale, int stage);
@@ -548,6 +601,9 @@ typedef struct screen {
#define GR_640 0 // 640 x 480
#define GR_1024 1 // 1024 x 768
#define GR_1024_THRESHOLD_WIDTH 1024
#define GR_1024_THRESHOLD_HEIGHT 600
extern const char *Resolution_prefixes[GR_NUM_RESOLUTIONS];
extern bool gr_init(int d_mode = GR_DEFAULT, int d_width = GR_DEFAULT, int d_height = GR_DEFAULT, int d_depth = GR_DEFAULT);
@@ -570,19 +626,28 @@ extern screen gr_screen;
#define GR_STENCIL_READ 1
#define GR_STENCIL_WRITE 2
void gr_set_screen_scale(int x, int y);
void gr_set_screen_scale(int x, int y, int max_x, int max_y);
#define GR_RESIZE_NONE 0
#define GR_RESIZE_FULL 1
#define GR_RESIZE_MENU 2
#define GR_RESIZE_MENU_ZOOMED 3
#define GR_RESIZE_MENU_NO_OFFSET 4
void gr_set_screen_scale(int x, int y, int zoom_x = -1, int zoom_y = -1, int max_x = gr_screen.max_w, int max_y = gr_screen.max_h, bool force_stretch = false);
void gr_reset_screen_scale();
bool gr_unsize_screen_pos(int *x, int *y);
bool gr_resize_screen_pos(int *x, int *y);
bool gr_unsize_screen_posf(float *x, float *y);
bool gr_resize_screen_posf(float *x, float *y);
bool gr_unsize_screen_pos(int *x, int *y, int *w = NULL, int *h = NULL, int resize_mode = GR_RESIZE_FULL);
bool gr_resize_screen_pos(int *x, int *y, int *w = NULL, int *h = NULL, int resize_mode = GR_RESIZE_FULL);
bool gr_unsize_screen_posf(float *x, float *y, float *w = NULL, float *h = NULL, int resize_mode = GR_RESIZE_FULL);
bool gr_resize_screen_posf(float *x, float *y, float *w = NULL, float *h = NULL, int resize_mode = GR_RESIZE_FULL);
// Does formatted printing. This calls gr_string after formatting,
// so if you don't need to format the string, then call gr_string
// directly.
extern void _cdecl gr_printf( int x, int y, const char * format, ... );
// same as above but doesn't resize for non-standard resolutions
// same as gr_printf but positions text correctly in menus
extern void _cdecl gr_printf_menu( int x, int y, const char * format, ... );
// same as gr_printf_menu but accounts for menu zooming
extern void _cdecl gr_printf_menu_zoomed( int x, int y, const char * format, ... );
// same as gr_printf but doesn't resize for non-standard resolutions
extern void _cdecl gr_printf_no_resize( int x, int y, const char * format, ... );
// Returns the size of the string in pixels in w and h
@@ -620,66 +685,66 @@ extern void gr_activate(int active);
void gr_flip();
//#define gr_set_clip GR_CALL(gr_screen.gf_set_clip)
__inline void gr_set_clip(int x, int y, int w, int h, bool resize=true)
__inline void gr_set_clip(int x, int y, int w, int h, int resize_mode=GR_RESIZE_FULL)
{
(*gr_screen.gf_set_clip)(x,y,w,h,resize);
(*gr_screen.gf_set_clip)(x,y,w,h,resize_mode);
}
#define gr_reset_clip GR_CALL(gr_screen.gf_reset_clip)
void gr_set_bitmap(int bitmap_num, int alphablend = GR_ALPHABLEND_NONE, int bitbltmode = GR_BITBLT_MODE_NORMAL, float alpha = 1.0f);
#define gr_clear GR_CALL(gr_screen.gf_clear)
__inline void gr_aabitmap(int x, int y, bool resize = true, bool mirror = false)
__inline void gr_aabitmap(int x, int y, int resize_mode = GR_RESIZE_FULL, bool mirror = false)
{
(*gr_screen.gf_aabitmap)(x,y,resize,mirror);
(*gr_screen.gf_aabitmap)(x,y,resize_mode,mirror);
}
__inline void gr_aabitmap_ex(int x, int y, int w, int h, int sx, int sy, bool resize = true, bool mirror = false)
__inline void gr_aabitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode = GR_RESIZE_FULL, bool mirror = false)
{
(*gr_screen.gf_aabitmap_ex)(x,y,w,h,sx,sy,resize,mirror);
(*gr_screen.gf_aabitmap_ex)(x,y,w,h,sx,sy,resize_mode,mirror);
}
__inline void gr_bitmap_ex(int x, int y, int w, int h, int sx, int sy, bool resize = true)
__inline void gr_bitmap_ex(int x, int y, int w, int h, int sx, int sy, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_bitmap_ex)(x, y, w, h, sx, sy, resize);
(*gr_screen.gf_bitmap_ex)(x, y, w, h, sx, sy, resize_mode);
}
void gr_shield_icon(coord2d coords[6], const bool resize = true);
void gr_rect(int x, int y, int w, int h, bool resize = true);
void gr_shade(int x, int y, int w, int h, bool resize = true);
void gr_shield_icon(coord2d coords[6], const int resize_mode = GR_RESIZE_FULL);
void gr_rect(int x, int y, int w, int h, int resize_mode = GR_RESIZE_FULL);
void gr_shade(int x, int y, int w, int h, int resize_mode = GR_RESIZE_FULL);
__inline void gr_string(int x, int y, const char* string, bool resize = true)
__inline void gr_string(int x, int y, const char* string, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_string)(x,y,string,resize);
(*gr_screen.gf_string)(x,y,string,resize_mode);
}
__inline void gr_circle(int xc, int yc, int d, bool resize = true)
__inline void gr_circle(int xc, int yc, int d, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_circle)(xc,yc,d,resize);
(*gr_screen.gf_circle)(xc,yc,d,resize_mode);
}
__inline void gr_unfilled_circle(int xc, int yc, int d, bool resize = true)
__inline void gr_unfilled_circle(int xc, int yc, int d, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_unfilled_circle)(xc,yc,d,resize);
(*gr_screen.gf_unfilled_circle)(xc,yc,d,resize_mode);
}
__inline void gr_arc(int xc, int yc, float r, float angle_start, float angle_end, bool fill, bool resize = true)
__inline void gr_arc(int xc, int yc, float r, float angle_start, float angle_end, bool fill, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_arc)(xc,yc,r,angle_start,angle_end,fill,resize);
(*gr_screen.gf_arc)(xc,yc,r,angle_start,angle_end,fill,resize_mode);
}
#define gr_curve GR_CALL(gr_screen.gf_curve)
__inline void gr_line(int x1, int y1, int x2, int y2, bool resize = true)
__inline void gr_line(int x1, int y1, int x2, int y2, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_line)(x1, y1, x2, y2, resize);
(*gr_screen.gf_line)(x1, y1, x2, y2, resize_mode);
}
#define gr_aaline GR_CALL(gr_screen.gf_aaline)
__inline void gr_pixel(int x, int y, bool resize = true)
__inline void gr_pixel(int x, int y, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_pixel)(x, y, resize);
(*gr_screen.gf_pixel)(x, y, resize_mode);
}
#define gr_scaler GR_CALL(gr_screen.gf_scaler)
#define gr_aascaler GR_CALL(gr_screen.gf_aascaler)
@@ -687,9 +752,9 @@ __inline void gr_pixel(int x, int y, bool resize = true)
#define gr_render GR_CALL(gr_screen.gf_render)
#define gr_render_effect GR_CALL(gr_screen.gf_render_effect)
__inline void gr_gradient(int x1, int y1, int x2, int y2, bool resize = true)
__inline void gr_gradient(int x1, int y1, int x2, int y2, int resize_mode = GR_RESIZE_FULL)
{
(*gr_screen.gf_gradient)(x1, y1, x2, y2, resize);
(*gr_screen.gf_gradient)(x1, y1, x2, y2, resize_mode);
}
#define gr_fade_in GR_CALL(gr_screen.gf_fade_in)
@@ -852,10 +917,10 @@ void gr_create_shader(shader *shade, ubyte r, ubyte g, ubyte b, ubyte c);
void gr_set_shader(shader *shade);
// new bitmap functions
void gr_bitmap(int x, int y, bool resize = true);
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, bool resize = true);
void gr_bitmap_list(bitmap_2d_list* list, int n_bm, bool allow_scaling);
void gr_bitmap_list(bitmap_rect_list* list, int n_bm, bool allow_scaling);
void gr_bitmap(int x, int y, int resize_mode = GR_RESIZE_FULL);
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode = GR_RESIZE_FULL);
void gr_bitmap_list(bitmap_2d_list* list, int n_bm, int resize_mode);
void gr_bitmap_list(bitmap_rect_list* list, int n_bm, int resize_mode);
// texture update functions
ubyte* gr_opengl_get_texture_update_pointer(int bitmap_handle);
@@ -864,7 +929,7 @@ void gr_opengl_update_texture(int bitmap_handle, int bpp, ubyte* data, int width
// special function for drawing polylines. this function is specifically intended for
// polylines where each section is no more than 90 degrees away from a previous section.
// Moreover, it is _really_ intended for use with 45 degree angles.
void gr_pline_special(vec3d **pts, int num_pts, int thickness,bool resize=true);
void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode=GR_RESIZE_FULL);
#define VB_FLAG_POSITION (1<<0)
#define VB_FLAG_RHW (1<<1) //incompatable with the next normal
+115 -20
View File
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include "graphics/2d.h"
#include "cfile/cfile.h"
@@ -110,7 +111,7 @@ int get_char_width(ubyte c1,ubyte c2,int *width,int *spacing)
}
// NOTE: this returns an unscaled size for non-standard resolutions
int get_centered_x(const char *s)
int get_centered_x(const char *s, bool scaled)
{
int w,w2,s2;
@@ -119,31 +120,31 @@ int get_centered_x(const char *s)
w += s2;
}
return ((gr_screen.clip_width_unscaled - w) / 2);
return (((scaled ? gr_screen.clip_width : gr_screen.clip_width_unscaled) - w) / 2);
}
/**
* Draws a character centered on x
*/
void gr_char_centered(int x, int y, char chr)
void gr_char_centered(int x, int y, char chr, ubyte sc1, int resize_mode)
{
char str[2];
int w, sc;
int w;
sc = Lcl_special_chars;
if (chr == '1')
chr = (char)(sc + 1);
chr = (char)sc1;
str[0] = chr;
str[1] = 0;
gr_get_string_size(&w, NULL, str);
gr_string(x - w / 2, y, str);
gr_string(x - w / 2, y, str, resize_mode);
}
void gr_print_timestamp(int x, int y, fix timestamp)
void gr_print_timestamp(int x, int y, fix timestamp, int resize_mode)
{
char h[2], m[3], s[3];
int w, c;
int w, c, font_num;
ubyte sc;
int time = (int)f2fl(timestamp); // convert to seconds
@@ -155,19 +156,32 @@ void gr_print_timestamp(int x, int y, fix timestamp)
gr_get_string_size(&w, NULL, "0");
gr_get_string_size(&c, NULL, ":");
gr_string(x + w, y, ":");
gr_string(x + w * 3 + c, y, ":");
gr_string(x + w, y, ":", resize_mode);
gr_string(x + w * 3 + c, y, ":", resize_mode);
font_num = gr_get_current_fontnum();
if (font_num == -1) {
Warning(LOCATION, "Font not set - timestamps may not work correctly");
sc = 0;
} else {
sc = lcl_get_font_index(font_num);
}
if (sc == 0) {
sc = ubyte ('1'); // make do with non-mono-spaced 1
} else {
sc += 1;
}
x += w / 2;
gr_char_centered(x, y, h[0]);
gr_char_centered(x, y, h[0], sc, resize_mode);
x += w + c;
gr_char_centered(x, y, m[0]);
gr_char_centered(x, y, m[0], sc, resize_mode);
x += w;
gr_char_centered(x, y, m[1]);
gr_char_centered(x, y, m[1], sc, resize_mode);
x += w + c;
gr_char_centered(x, y, s[0]);
gr_char_centered(x, y, s[0], sc, resize_mode);
x += w;
gr_char_centered(x, y, s[1]);
gr_char_centered(x, y, s[1], sc, resize_mode);
}
int gr_get_font_height()
@@ -290,12 +304,41 @@ void _cdecl gr_printf( int x, int y, const char * format, ... )
if ( !Current_font ) return;
va_start(args, format);
vsprintf(grx_printf_text,format,args);
vsnprintf(grx_printf_text, sizeof(grx_printf_text)-1, format, args);
va_end(args);
grx_printf_text[sizeof(grx_printf_text)-1] = '\0';
gr_string(x,y,grx_printf_text);
}
void _cdecl gr_printf_menu( int x, int y, const char * format, ... )
{
va_list args;
if ( !Current_font ) return;
va_start(args, format);
vsnprintf(grx_printf_text, sizeof(grx_printf_text)-1, format, args);
va_end(args);
grx_printf_text[sizeof(grx_printf_text)-1] = '\0';
gr_string(x,y,grx_printf_text,GR_RESIZE_MENU);
}
void _cdecl gr_printf_menu_zoomed( int x, int y, const char * format, ... )
{
va_list args;
if ( !Current_font ) return;
va_start(args, format);
vsnprintf(grx_printf_text, sizeof(grx_printf_text)-1, format, args);
va_end(args);
grx_printf_text[sizeof(grx_printf_text)-1] = '\0';
gr_string(x,y,grx_printf_text,GR_RESIZE_MENU_ZOOMED);
}
void _cdecl gr_printf_no_resize( int x, int y, const char * format, ... )
{
va_list args;
@@ -303,10 +346,11 @@ void _cdecl gr_printf_no_resize( int x, int y, const char * format, ... )
if ( !Current_font ) return;
va_start(args, format);
vsprintf(grx_printf_text,format,args);
vsnprintf(grx_printf_text, sizeof(grx_printf_text)-1, format, args);
va_end(args);
grx_printf_text[sizeof(grx_printf_text)-1] = '\0';
gr_string(x,y,grx_printf_text,false);
gr_string(x,y,grx_printf_text,GR_RESIZE_NONE);
}
void gr_font_close()
@@ -523,17 +567,19 @@ void gr_set_font(int fontnum)
{
if ( fontnum < 0 ) {
Current_font = NULL;
Lcl_special_chars = 0;
return;
}
if ( fontnum >= 0 && fontnum < Num_fonts) {
Current_font = &Fonts[fontnum];
Lcl_special_chars = lcl_get_font_index(fontnum);
}
}
void parse_fonts_tbl(char *only_parse_first_font, size_t only_parse_first_font_size)
{
int rval;
int rval, i;
char *filename;
// choose file name
@@ -579,6 +625,55 @@ void parse_fonts_tbl(char *only_parse_first_font, size_t only_parse_first_font_s
int font_id = gr_create_font(font_filename);
if (font_id < 0) {
Warning(LOCATION, "Could not create font from typeface '%s'!", font_filename);
skip_to_start_of_string_either("#End","$Font:");
} else {
// max allowed special char index; i.e. 7 special chars in retail fonts 1 & 3
static const int MAX_SPECIAL_CHAR_IDX = UCHAR_MAX-6;
// 'default' special char index for all languages using this font
int default_special_char_index = 0;
if (optional_string("+Default Special Character Index:")) {
stuff_int(&default_special_char_index);
if (default_special_char_index < 0 || default_special_char_index >= MAX_SPECIAL_CHAR_IDX) {
Error(LOCATION, "Default special character index (%d) for font (%s), must be 0 - %u", default_special_char_index, font_filename, MAX_SPECIAL_CHAR_IDX);
}
for (i = 0; i < (int)Lcl_languages.size(); ++i) {
Lcl_languages[i].special_char_indexes[font_id] = (ubyte)default_special_char_index;
}
}
while (optional_string("+Language:")) {
char lang_name[LCL_LANG_NAME_LEN + 1];
int special_char_index, lang_idx = -1;
stuff_string(lang_name, F_NAME, LCL_LANG_NAME_LEN + 1);
// find language and set the index, or if not found move to the next one
for (i = 0; i < (int)Lcl_languages.size(); ++i) {
if (!strcmp(Lcl_languages[i].lang_name, lang_name)) {
lang_idx = i;
break;
}
}
if (lang_idx == -1) {
Warning(LOCATION, "Ignoring invalid language (%s) specified by font (%s); not built-in or in strings.tbl", lang_name, font_filename );
skip_to_start_of_string_either("+Language:","$Font:","#End");
continue;
}
if (optional_string("+Special Character Index:")) {
stuff_int(&special_char_index);
if (special_char_index < 0 || special_char_index >= MAX_SPECIAL_CHAR_IDX) {
Error(LOCATION, "Special character index (%d) for font (%s), language (%s) is invalid, must be 0 - %u", special_char_index, font_filename, lang_name, MAX_SPECIAL_CHAR_IDX);
}
Lcl_languages[lang_idx].special_char_indexes[font_id] = (ubyte)special_char_index;
}
}
}
}
+2 -2
View File
@@ -72,13 +72,13 @@ extern int gr_get_current_fontnum();
extern int gr_get_fontnum(char *filename);
extern void gr_set_font(int fontnum);
void gr_print_timestamp(int x, int y, fix timestamp);
void gr_print_timestamp(int x, int y, fix timestamp, int resize_mode);
char *gr_force_fit_string(char *str, int max_str, int max_width);
void gr_font_init();
void gr_font_close();
extern font *Current_font;
extern int get_char_width(ubyte c1,ubyte c2,int *width,int *spacing);
extern int get_centered_x(const char *s);
extern int get_centered_x(const char *s, bool scaled);
#endif
+3 -3
View File
@@ -418,7 +418,7 @@ void generic_render_ani_stream(generic_anim *ga)
#endif
}
void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool menu)
{
float keytime = 0.0;
@@ -487,8 +487,8 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
}
ga->previous_frame = ga->current_frame;
if(ga->use_hud_color)
gr_aabitmap(x,y);
gr_aabitmap(x, y, (menu ? GR_RESIZE_MENU : GR_RESIZE_FULL));
else
gr_bitmap(x,y);
gr_bitmap(x, y, (menu ? GR_RESIZE_MENU : GR_RESIZE_FULL));
}
}
+1 -1
View File
@@ -61,6 +61,6 @@ int generic_anim_load(generic_anim *ga);
int generic_anim_stream(generic_anim *ga);
int generic_bitmap_load(generic_bitmap *gb);
void generic_anim_unload(generic_anim *ga);
void generic_anim_render(generic_anim *ga, float frametime, int x, int y);
void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool menu = false);
#endif
+1 -1
View File
@@ -581,7 +581,7 @@ void geometry_batcher::render_buffer(int flags)
* Laser batcher
*/
struct batch_item {
batch_item(): texture(-1), tmap_flags(0), alpha(1.0f), laser(false) {};
batch_item(): texture(-1), tmap_flags(0), alpha(1.0f), laser(false) {}
geometry_batcher batch;
+3 -3
View File
@@ -29,7 +29,7 @@ private:
void clone(const geometry_batcher &geo);
public:
geometry_batcher(): n_to_render(0), n_allocated(0), vert(NULL), use_radius(true), radius_list(NULL), buffer_offset(-1) {};
geometry_batcher(): n_to_render(0), n_allocated(0), vert(NULL), use_radius(true), radius_list(NULL), buffer_offset(-1) {}
~geometry_batcher();
geometry_batcher(const geometry_batcher &geo) { clone(geo); }
@@ -69,9 +69,9 @@ public:
void render_buffer(int flags);
// determine if we even need to try and render this (helpful for particle system)
int need_to_render() { return n_to_render; };
int need_to_render() { return n_to_render; }
void operator =(int){};
void operator =(int){}
};
+62 -53
View File
@@ -22,6 +22,7 @@
#include "io/timer.h"
#include "ddsutils/ddsutils.h"
#include "model/model.h"
#include "debugconsole/console.h"
#include "debugconsole/timerbar.h"
#include "graphics/gropenglbmpman.h"
#include "graphics/gropengllight.h"
@@ -346,13 +347,15 @@ void gr_opengl_flip()
if (Gr_cursor != -1 && bm_is_valid(Gr_cursor)) {
gr_set_bitmap(Gr_cursor);
gr_bitmap( mx, my, false);
gr_bitmap( mx, my, GR_RESIZE_NONE);
}
}
#ifdef _WIN32
SwapBuffers(GL_device_context);
#else
if (Cmdline_gl_finish)
glFinish ();
SDL_GL_SwapBuffers();
#endif
@@ -367,7 +370,7 @@ void gr_opengl_flip()
#endif
}
void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
void gr_opengl_set_clip(int x, int y, int w, int h, int resize_mode)
{
// check for sanity of parameters
if (x < 0) {
@@ -378,11 +381,15 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
y = 0;
}
int to_resize = (resize && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)));
int to_resize = (resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)));
int max_w = ((to_resize) ? gr_screen.max_w_unscaled : gr_screen.max_w);
int max_h = ((to_resize) ? gr_screen.max_h_unscaled : gr_screen.max_h);
if ((gr_screen.rendering_to_texture != -1) && to_resize) {
gr_unsize_screen_pos(&max_w, &max_h);
}
if (x >= max_w) {
x = max_w - 1;
}
@@ -417,8 +424,7 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
gr_screen.clip_height_unscaled = h;
if (to_resize) {
gr_resize_screen_pos(&x, &y);
gr_resize_screen_pos(&w, &h);
gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
} else {
gr_unsize_screen_pos( &gr_screen.offset_x_unscaled, &gr_screen.offset_y_unscaled );
gr_unsize_screen_pos( &gr_screen.clip_right_unscaled, &gr_screen.clip_bottom_unscaled );
@@ -650,27 +656,25 @@ void gr_opengl_fog_set(int fog_mode, int r, int g, int b, float fog_near, float
return;
}
if (gr_screen.current_fog_mode != fog_mode) {
if (OGL_fogmode == 3) {
glFogf(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
glFogf(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
}
// Um.. this is not the correct way to fog in software, probably doesn't matter though
else if ( (OGL_fogmode == 2) && Cmdline_nohtl ) {
glFogf(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
fog_near *= fog_near; // it's faster this way
fog_far *= fog_far;
} else {
glFogf(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
}
GL_state.Fog(GL_TRUE);
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, fog_near);
glFogf(GL_FOG_END, fog_far);
gr_screen.current_fog_mode = fog_mode;
if (OGL_fogmode == 3) {
glFogf(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
glFogf(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
}
// Um.. this is not the correct way to fog in software, probably doesn't matter though
else if ( (OGL_fogmode == 2) && Cmdline_nohtl ) {
glFogf(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
fog_near *= fog_near; // it's faster this way
fog_far *= fog_far;
} else {
glFogf(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
}
GL_state.Fog(GL_TRUE);
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, fog_near);
glFogf(GL_FOG_END, fog_far);
gr_screen.current_fog_mode = fog_mode;
if ( (gr_screen.current_fog_color.red != r) ||
(gr_screen.current_fog_color.green != g) ||
@@ -1130,7 +1134,7 @@ void gr_opengl_restore_screen(int bmp_id)
return;
gr_set_bitmap(GL_saved_screen_id);
gr_bitmap(0, 0, false); // don't scale here since we already have real screen size
gr_bitmap(0, 0, GR_RESIZE_NONE); // don't scale here since we already have real screen size
}
void gr_opengl_free_screen(int bmp_id)
@@ -2078,56 +2082,61 @@ bool gr_opengl_init()
DCF(ogl_minimize, "Minimizes opengl")
{
bool minimize_ogl = false;
if ( gr_screen.mode != GR_OPENGL ) {
dc_printf("Command only available in OpenGL mode.\n");
return;
}
if (Dc_command) {
dc_get_arg(ARG_TRUE);
if ( Dc_arg_type & ARG_TRUE ) {
opengl_minimize();
}
if (dc_optional_string_either("help", "--help")) {
dc_printf("[bool] If true is passed, then the OpenGL window will minimize.\n");
return;
}
dc_stuff_boolean(&minimize_ogl);
if (Dc_help)
dc_printf("If set to true then the OpenGL window will minimize.\n");
if (minimize_ogl) {
opengl_minimize();
}
}
DCF(ogl_anisotropy, "toggles anisotropic filtering")
{
bool process = true;
int value;
if ( gr_screen.mode != GR_OPENGL ) {
dc_printf("Can only set anisotropic filter in OpenGL mode.\n");
return;
}
if ( Dc_command && !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
if (dc_optional_string_either("help", "--help")) {
dc_printf("Sets OpenGL anisotropic filtering level.\n");
dc_printf("GL_anisotropy [int] Valid values are 0 to %i. 0 turns off anisotropic filtering.\n", (int)opengl_get_max_anisotropy());
process = false;
}
if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
process = false;
}
if (!process) {
return;
}
if ( !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
dc_printf("Error: Anisotropic filter is not settable!\n");
return;
}
if ( Dc_command ) {
dc_get_arg(ARG_INT | ARG_NONE);
if ( Dc_arg_type & ARG_NONE ) {
if (!dc_maybe_stuff_int(&value)) {
// No arg passed, set to default
GL_anisotropy = 1.0f;
// opengl_set_anisotropy();
dc_printf("Anisotropic filter value reset to default level.\n");
}
if ( Dc_arg_type & ARG_INT ) {
GL_anisotropy = (GLfloat)Dc_arg_float;
} else {
GL_anisotropy = (GLfloat)value;
// opengl_set_anisotropy( (float)Dc_arg_float );
}
}
if ( Dc_status ) {
dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
}
if (Dc_help) {
dc_printf("Sets OpenGL anisotropic filtering level.\n");
dc_printf("Valid values are 1 to %i, or 0 to turn off.\n", (int)opengl_get_max_anisotropy());
}
}
Loaded 100 of 416 files, more files were not shown because too many files have changed in this diff. Show more