mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 18:31:26 -10:00
Compare commits
344
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc5a74a911 | ||
|
|
37c469ea84 | ||
|
|
f09e4dd328 | ||
|
|
37252782bd | ||
|
|
544d90710e | ||
|
|
2123a62d21 | ||
|
|
b561c627ce | ||
|
|
245e876558 | ||
|
|
89a81a4025 | ||
|
|
c20285d58e | ||
|
|
7a57db09ba | ||
|
|
d005f0ec2f | ||
|
|
7f2ae7551e | ||
|
|
af8d267ebe | ||
|
|
a26d042e7a | ||
|
|
377d572863 | ||
|
|
10845127c2 | ||
|
|
c7054d51fc | ||
|
|
c938af26fa | ||
|
|
aa7ed66c64 | ||
|
|
960cf37070 | ||
|
|
e237557a31 | ||
|
|
7d27e1d5e9 | ||
|
|
b69144e56b | ||
|
|
9b03888d39 | ||
|
|
cbca7ab34b | ||
|
|
4452762786 | ||
|
|
e006ad7ade | ||
|
|
7a8da470b8 | ||
|
|
336d4abf37 | ||
|
|
fc3fbdd1e5 | ||
|
|
d30f89bb01 | ||
|
|
0cb744487e | ||
|
|
7f7a6decb8 | ||
|
|
516a8c68ee | ||
|
|
28b733738c | ||
|
|
966735a65b | ||
|
|
a5560a59c9 | ||
|
|
7db44e0177 | ||
|
|
c98504da11 | ||
|
|
ad007cfe0c | ||
|
|
4dcc6da75f | ||
|
|
c6b4b79c2f | ||
|
|
82d36d5f1f | ||
|
|
10ede3185f | ||
|
|
b8331e7216 | ||
|
|
2fe257afca | ||
|
|
6fdc81cd88 | ||
|
|
af09318d24 | ||
|
|
c22a0697f8 | ||
|
|
f1df0c31db | ||
|
|
6a1b6638fc | ||
|
|
a5776e277c | ||
|
|
b8cc620079 | ||
|
|
1b7c9b2f8d | ||
|
|
bc20b94cde | ||
|
|
aa497aa236 | ||
|
|
1fba5a9bd4 | ||
|
|
69c54645b6 | ||
|
|
bb5fc833d4 | ||
|
|
e505e84f95 | ||
|
|
ed65937afc | ||
|
|
d4cb17531c | ||
|
|
2af7151592 | ||
|
|
ffd4142864 | ||
|
|
73a048c92f | ||
|
|
35b1cb383f | ||
|
|
0a2ffe7653 | ||
|
|
f91c78d7a7 | ||
|
|
cfa67a5390 | ||
|
|
77c1a903ee | ||
|
|
442837521f | ||
|
|
8e20c8f780 | ||
|
|
8579209137 | ||
|
|
0a73016391 | ||
|
|
97819f8ee5 | ||
|
|
a3454349e6 | ||
|
|
2b0d7fdaa8 | ||
|
|
5b9f250861 | ||
|
|
5f934f28dd | ||
|
|
fcde91a42c | ||
|
|
182af9fea9 | ||
|
|
170e04ebd0 | ||
|
|
eee6f49bf8 | ||
|
|
795e2fbe67 | ||
|
|
8f164bcdc7 | ||
|
|
69c9935ffa | ||
|
|
3e3f0691f1 | ||
|
|
fbd217ee3a | ||
|
|
b38d9b0704 | ||
|
|
7b2a349ee0 | ||
|
|
00dc14be96 | ||
|
|
c4e5640893 | ||
|
|
e00f3c8c58 | ||
|
|
54e9a7bbab | ||
|
|
a403887a90 | ||
|
|
61b584cef6 | ||
|
|
4f92dae237 | ||
|
|
4a0e043cc3 | ||
|
|
7e6c86d8aa | ||
|
|
61f908268e | ||
|
|
43ed5dd385 | ||
|
|
5b01e4d387 | ||
|
|
83922f6c0d | ||
|
|
6328aa6a78 | ||
|
|
0f10e80cd9 | ||
|
|
c880ad1634 | ||
|
|
00fc4382c0 | ||
|
|
6c30105602 | ||
|
|
3042a805d4 | ||
|
|
9adb70e863 | ||
|
|
5fb5f58dbb | ||
|
|
e4228f9b2b | ||
|
|
76f4e460e4 | ||
|
|
2b3c446f26 | ||
|
|
c54053535f | ||
|
|
6ea6b82db1 | ||
|
|
aad3b1c0e8 | ||
|
|
7467cd5537 | ||
|
|
5f1a5b3120 | ||
|
|
d128b00be0 | ||
|
|
62c4963276 | ||
|
|
18d5980178 | ||
|
|
62ecc849ac | ||
|
|
3f683496d3 | ||
|
|
03d9ffcbdc | ||
|
|
d9b05259bf | ||
|
|
680907778e | ||
|
|
8d9c3833b8 | ||
|
|
97a9146ebc | ||
|
|
fdb68fdc8b | ||
|
|
2998e9e54f | ||
|
|
7a80419d17 | ||
|
|
5c46b2530a | ||
|
|
7e679a2272 | ||
|
|
75e0b54f1c | ||
|
|
505b701fd7 | ||
|
|
1b9de12ad6 | ||
|
|
115d5aa3b8 | ||
|
|
5037612651 | ||
|
|
46a91c4128 | ||
|
|
f05252fba4 | ||
|
|
e9688af867 | ||
|
|
86b5b2f1f2 | ||
|
|
b570391a11 | ||
|
|
0ba13f58e3 | ||
|
|
11c2bec249 | ||
|
|
04287f31e6 | ||
|
|
c7b811646b | ||
|
|
37885df34e | ||
|
|
113136af3b | ||
|
|
706714f73a | ||
|
|
32e72658be | ||
|
|
ad90167396 | ||
|
|
b129927404 | ||
|
|
583c9ac6ee | ||
|
|
1917578c82 | ||
|
|
96d35f010a | ||
|
|
0313a452fa | ||
|
|
5de995b5dd | ||
|
|
b0452f08f2 | ||
|
|
f54f348f19 | ||
|
|
4530f04484 | ||
|
|
14c708be24 | ||
|
|
84dee408ad | ||
|
|
1601a5b270 | ||
|
|
60ea1c4f7f | ||
|
|
6eeb7e5c0c | ||
|
|
f61eed4dbb | ||
|
|
380f4e31b5 | ||
|
|
ab18bfacad | ||
|
|
07f58a21a1 | ||
|
|
7e6aae12ca | ||
|
|
26afaaf56e | ||
|
|
d81fa6bbe2 | ||
|
|
b6a94ff3fe | ||
|
|
9182a31173 | ||
|
|
bb5da5b6f7 | ||
|
|
ac25e6ddfa | ||
|
|
ddf0737133 | ||
|
|
0b3f745c59 | ||
|
|
ad33b70fb6 | ||
|
|
3c97ebbb75 | ||
|
|
9f19cd1a41 | ||
|
|
336283eedc | ||
|
|
e2d293a2e4 | ||
|
|
4da71f5ed8 | ||
|
|
4821c7b92e | ||
|
|
9e6b964b4b | ||
|
|
d15856e2ba | ||
|
|
827ada1960 | ||
|
|
9cfac8dc42 | ||
|
|
03ad562905 | ||
|
|
02d638a05a | ||
|
|
880b7b68eb | ||
|
|
160180b230 | ||
|
|
82d5b218e3 | ||
|
|
9d6f75e4fe | ||
|
|
269574af5c | ||
|
|
9670d16537 | ||
|
|
44706c03a1 | ||
|
|
5242a38755 | ||
|
|
97382b69ca | ||
|
|
3131006fd5 | ||
|
|
87f4c064f7 | ||
|
|
c1ad2ed64f | ||
|
|
2b91bfb98a | ||
|
|
0c33d511b0 | ||
|
|
0467fbb289 | ||
|
|
910046729b | ||
|
|
73ef4c52df | ||
|
|
4a3b9f9b76 | ||
|
|
b4ce4b3f85 | ||
|
|
2cb514ab3f | ||
|
|
2d8861e2d1 | ||
|
|
78e9e431e4 | ||
|
|
f5a192c27c | ||
|
|
97dd5149cd | ||
|
|
26a0ffe6ee | ||
|
|
52f3e10c80 | ||
|
|
37ac788606 | ||
|
|
844b3bab4f | ||
|
|
32977365d0 | ||
|
|
78289b4802 | ||
|
|
4e6b031bb9 | ||
|
|
41c834157d | ||
|
|
d4c2e9727e | ||
|
|
315e1d489c | ||
|
|
259c805c63 | ||
|
|
a944a2d9e9 | ||
|
|
120a780470 | ||
|
|
704f6580db | ||
|
|
361e7ae590 | ||
|
|
f556a6694d | ||
|
|
5735d59fdd | ||
|
|
3989ce21aa | ||
|
|
bfd30fa3d8 | ||
|
|
55801b8941 | ||
|
|
8bcd195e48 | ||
|
|
832db695ec | ||
|
|
0d747ad3b8 | ||
|
|
ebb5206315 | ||
|
|
d5c8494297 | ||
|
|
40071290f2 | ||
|
|
cc6050b711 | ||
|
|
97e9d9e8d6 | ||
|
|
838ae6eee2 | ||
|
|
ed71fe08df | ||
|
|
de5f6671ea | ||
|
|
933b9422d8 | ||
|
|
55edb850a7 | ||
|
|
14d3a1a007 | ||
|
|
b7de7ae422 | ||
|
|
c3bc4ba563 | ||
|
|
f97c5059f0 | ||
|
|
4f62a53354 | ||
|
|
708c0ae8fa | ||
|
|
8740115165 | ||
|
|
b75151cef1 | ||
|
|
a998afffe4 | ||
|
|
eeaf958420 | ||
|
|
2cd28541e7 | ||
|
|
596bae9cfa | ||
|
|
1176523e9d | ||
|
|
d9a29ac708 | ||
|
|
f4fa2e00a2 | ||
|
|
2167ece1fd | ||
|
|
bca3d084a5 | ||
|
|
bbc0eec0ba | ||
|
|
a5684ba6cf | ||
|
|
2a2c5856c3 | ||
|
|
3a951225e9 | ||
|
|
3f7b0b1c8f | ||
|
|
edb67c1b17 | ||
|
|
12d27b7913 | ||
|
|
e6f0fe4ffb | ||
|
|
fcf6cec066 | ||
|
|
c2896f83f6 | ||
|
|
a2f8be65ae | ||
|
|
53c0b4ae35 | ||
|
|
5ebae3603d | ||
|
|
7853397544 | ||
|
|
3241e58eaa | ||
|
|
4e9f4af398 | ||
|
|
80462cb097 | ||
|
|
1a2588cfba | ||
|
|
d12fee5955 | ||
|
|
4a120433e8 | ||
|
|
80730a2ffa | ||
|
|
4910a0239b | ||
|
|
36e7ebea4a | ||
|
|
746f86883d | ||
|
|
beb0aec724 | ||
|
|
8cf10625bc | ||
|
|
e1e5895749 | ||
|
|
e8556981d3 | ||
|
|
b796f523e3 | ||
|
|
bf6d547cd5 | ||
|
|
c827121e1a | ||
|
|
130e254c89 | ||
|
|
708e8d3d6c | ||
|
|
b3420befc7 | ||
|
|
b347ea17e8 | ||
|
|
02fe9d3243 | ||
|
|
985da615ba | ||
|
|
ac406437ae | ||
|
|
f2eef10a61 | ||
|
|
af7e811cf1 | ||
|
|
95e924b6ce | ||
|
|
c91f65e274 | ||
|
|
721d529776 | ||
|
|
458b67e0fc | ||
|
|
6b9a61dae0 | ||
|
|
9f2a038976 | ||
|
|
96486ad64a | ||
|
|
c6155a784c | ||
|
|
e7b8feef5f | ||
|
|
cf684e67c0 | ||
|
|
535a9ec32b | ||
|
|
b7fdae636a | ||
|
|
4dfb17ab01 | ||
|
|
bdda953b21 | ||
|
|
767bb5c862 | ||
|
|
aa07330f1e | ||
|
|
66f0dec8f4 | ||
|
|
16322a4a88 | ||
|
|
9c78519420 | ||
|
|
3806a4ed9f | ||
|
|
d3b61db4a0 | ||
|
|
caaf6526fe | ||
|
|
d8633494fb | ||
|
|
3345b78f18 | ||
|
|
d9b69e290d | ||
|
|
d48da6e765 | ||
|
|
8d35cbcfb2 | ||
|
|
6645dae670 | ||
|
|
35f1394997 | ||
|
|
45b3efd0fc | ||
|
|
c599d359cf | ||
|
|
e870a9cb63 | ||
|
|
b081e42418 | ||
|
|
f2ebe497c6 | ||
|
|
b8530023db | ||
|
|
d076e9ae95 |
No files matched your search
+20
-18
@@ -191,7 +191,10 @@ AM_LDFLAGS = @D_LDFLAGS@ @FS2_LDFLAGS@
|
||||
noinst_LIBRARIES = libcode.a
|
||||
noinst_PROGRAMS = @FS2_BINARY@
|
||||
|
||||
EXTRA_PROGRAMS = fs2_open_r fs2_open_d wxFRED2_r wxFRED2_d fs2_open_INF_r fs2_open_INF_d wxFRED2_INF_r wxFRED2_INF_d
|
||||
EXTRA_PROGRAMS = fs2_open_@PACKAGE_VERSION@ fs2_open_@PACKAGE_VERSION@_NOINF \
|
||||
fs2_open_@PACKAGE_VERSION@_DEBUG fs2_open_@PACKAGE_VERSION@_NOINF_DEBUG \
|
||||
wxFRED2_@PACKAGE_VERSION@ wxFRED2_@PACKAGE_VERSION@_NOINF \
|
||||
wxFRED2_@PACKAGE_VERSION@_DEBUG wxFRED2_@PACKAGE_VERSION@_NOINF_DEBUG
|
||||
|
||||
###############################################################################
|
||||
##
|
||||
@@ -355,7 +358,6 @@ FS2_SOURCES = \
|
||||
hud/hudobserver.h \
|
||||
hud/hudparse.cpp \
|
||||
hud/hudparse.h \
|
||||
hud/hudresource.h \
|
||||
hud/hudreticle.cpp \
|
||||
hud/hudreticle.h \
|
||||
hud/hudshield.cpp \
|
||||
@@ -792,22 +794,22 @@ FS2OPEN_SOURCES = \
|
||||
freespace2/levelpaging.cpp \
|
||||
freespace2/levelpaging.h
|
||||
|
||||
fs2_open_d_SOURCES = \
|
||||
fs2_open_@PACKAGE_VERSION@_DEBUG_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_r_SOURCES = \
|
||||
fs2_open_@PACKAGE_VERSION@_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_INF_d_SOURCES = \
|
||||
fs2_open_@PACKAGE_VERSION@_NOINF_DEBUG_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_INF_r_SOURCES = \
|
||||
fs2_open_@PACKAGE_VERSION@_NOINF_SOURCES = \
|
||||
${FS2OPEN_SOURCES}
|
||||
|
||||
fs2_open_d_LDADD = libcode.a
|
||||
fs2_open_r_LDADD = libcode.a
|
||||
fs2_open_INF_d_LDADD = libcode.a
|
||||
fs2_open_INF_r_LDADD = libcode.a
|
||||
fs2_open_@PACKAGE_VERSION@_DEBUG_LDADD = libcode.a
|
||||
fs2_open_@PACKAGE_VERSION@_LDADD = libcode.a
|
||||
fs2_open_@PACKAGE_VERSION@_NOINF_DEBUG_LDADD = libcode.a
|
||||
fs2_open_@PACKAGE_VERSION@_NOINF_LDADD = libcode.a
|
||||
|
||||
##
|
||||
## End MAIN binary
|
||||
@@ -827,22 +829,22 @@ wxFRED_SOURCES = \
|
||||
wxfred2/wxfred_xrc.cpp \
|
||||
wxfred2/wxfred_xrc.h
|
||||
|
||||
wxFRED2_d_SOURCES = \
|
||||
wxFRED2_@PACKAGE_VERSION@_DEBUG_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_r_SOURCES = \
|
||||
wxFRED2_@PACKAGE_VERSION@_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_INF_d_SOURCES = \
|
||||
wxFRED2_@PACKAGE_VERSION@_NOINF_DEBUG_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_INF_r_SOURCES = \
|
||||
wxFRED2_@PACKAGE_VERSION@_NOINF_SOURCES = \
|
||||
${wxFRED_SOURCES}
|
||||
|
||||
wxFRED2_d_LDADD = libcode.a
|
||||
wxFRED2_r_LDADD = libcode.a
|
||||
wxFRED2_INF_d_LDADD = libcode.a
|
||||
wxFRED2_INF_r_LDADD = libcode.a
|
||||
wxFRED2_@PACKAGE_VERSION@_DEBUG_LDADD = libcode.a
|
||||
wxFRED2_@PACKAGE_VERSION@_LDADD = libcode.a
|
||||
wxFRED2_@PACKAGE_VERSION@_NOINF_DEBUG_LDADD = libcode.a
|
||||
wxFRED2_@PACKAGE_VERSION@_NOINF_LDADD = libcode.a
|
||||
|
||||
##
|
||||
## End wxFRED2 binary
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ char *ai_get_goal_target_name(char *name, int *index)
|
||||
}
|
||||
|
||||
Assert(Total_goal_target_names < MAX_GOAL_TARGET_NAMES);
|
||||
Assertion(strlen(name) < NAME_LENGTH - 1, "Goal target name %s is too long. Needs to be 31 characters or less.", name);
|
||||
Assertion(strlen(name) <= NAME_LENGTH - 1, "Goal target name %s is too long. Needs to be 31 characters or less.", name);
|
||||
i = Total_goal_target_names++;
|
||||
strcpy_s(Goal_target_names[i], name);
|
||||
*index = i;
|
||||
|
||||
+22
-8
@@ -97,7 +97,7 @@ struct ship_info;
|
||||
#define AIGF_GOAL_OVERRIDE (1<<4) // paired with AIG_TYPE_DYNAMIC to mean this goal overrides any other goal
|
||||
#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_DOCK_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
|
||||
#define AIGF_DEPART_SOUND_PLAYED (1<<7) // Goober5000 - replacement for AL's hack ;)
|
||||
|
||||
#define AIGF_DOCK_INDEXES_VALID (AIGF_DOCKER_INDEX_VALID|AIGF_DOCKEE_INDEX_VALID)
|
||||
|
||||
@@ -254,13 +254,12 @@ typedef struct ai_class {
|
||||
#define AIS_CHASE_CIRCLESTRAFE 19 // Attempt a circle-strafe on the target
|
||||
|
||||
// Submodes for docking behavior
|
||||
#define AIS_DOCK_0 21
|
||||
#define AIS_DOCK_1 22
|
||||
#define AIS_DOCK_2 23
|
||||
#define AIS_DOCK_3 24
|
||||
//#define AIS_DOCK_3A 25
|
||||
#define AIS_DOCK_4 26 // Only for rearm/repair.
|
||||
#define AIS_DOCK_4A 27 // Only for not rearm/repair. MK, 7/15/97
|
||||
#define AIS_DOCK_0 20
|
||||
#define AIS_DOCK_1 21
|
||||
#define AIS_DOCK_2 22
|
||||
#define AIS_DOCK_3 23
|
||||
#define AIS_DOCK_4 24 // Only for rearm/repair.
|
||||
#define AIS_DOCK_4A 25 // Only for not rearm/repair. MK, 7/15/97
|
||||
#define AIS_UNDOCK_0 30
|
||||
#define AIS_UNDOCK_1 31
|
||||
#define AIS_UNDOCK_2 32
|
||||
@@ -539,6 +538,17 @@ typedef struct ai_info {
|
||||
int ai_override_timestamp; // mark for when to end the current override
|
||||
} ai_info;
|
||||
|
||||
// Goober5000
|
||||
typedef struct {
|
||||
vec3d docker_point;
|
||||
vec3d dockee_point;
|
||||
int dock_mode;
|
||||
int submodel;
|
||||
vec3d submodel_pos;
|
||||
float submodel_r;
|
||||
float submodel_w;
|
||||
} rotating_dockpoint_info;
|
||||
|
||||
#define MAX_AI_INFO MAX_SHIPS
|
||||
|
||||
// SUBSYS_PATH_DIST is used as the distance that a subsystem path should terminate from the actual
|
||||
@@ -681,6 +691,10 @@ extern void ai_do_objects_docked_stuff(object *docker, int docker_point, object
|
||||
extern void ai_do_objects_undocked_stuff( object *docker, object *dockee );
|
||||
extern void ai_do_objects_repairing_stuff( object *repaired_obj, object *repair_obj, int how );
|
||||
|
||||
// Goober5000
|
||||
// Move to a position relative to a dock bay using thrusters.
|
||||
extern float dock_orient_and_approach(object *docker_objp, int docker_index, object *dockee_objp, int dockee_index, int dock_mode, rotating_dockpoint_info *rdinfo = NULL);
|
||||
|
||||
extern int find_danger_weapon(object *sobjp, float dtime, float *atime, float dot_threshhold);
|
||||
|
||||
void ai_set_mode_warp_out(object *objp, ai_info *aip);
|
||||
|
||||
@@ -472,7 +472,6 @@ int ai_big_maybe_follow_subsys_path(int do_dot_check)
|
||||
// for now, only follow the path to the first point
|
||||
if ( aip->path_cur < (aip->path_start+aip->path_length-1) ) {
|
||||
if ( aip->goal_objnum != aip->target_objnum ) {
|
||||
//Int3(); // what is going on here? - Get Alan
|
||||
aip->previous_mode = aip->mode;
|
||||
aip->mode = AIM_NONE;
|
||||
aip->submode = -1;
|
||||
@@ -827,15 +826,12 @@ void ai_big_chase()
|
||||
ship_info *sip = &Ship_info[Ships[Pl_objp->instance].ship_info_index];
|
||||
ship *shipp = &Ships[Pl_objp->instance];
|
||||
ai_info *aip = &Ai_info[shipp->ai_index];
|
||||
int enemy_ship_type;
|
||||
vec3d predicted_enemy_pos;
|
||||
|
||||
Assert(aip->mode == AIM_CHASE);
|
||||
|
||||
maybe_cheat_fire_synaptic(Pl_objp, aip);
|
||||
|
||||
enemy_ship_type = Ship_info[Ships[En_objp->instance].ship_info_index].flags;
|
||||
|
||||
ai_set_positions(Pl_objp, En_objp, aip, &player_pos, &enemy_pos);
|
||||
|
||||
player_pos = Pl_objp->pos;
|
||||
@@ -1252,7 +1248,6 @@ void ai_big_strafe_attack()
|
||||
vec3d target_pos;
|
||||
vec3d rand_vec;
|
||||
float target_dist, target_dot, accel, t;
|
||||
object *target_objp;
|
||||
|
||||
aip = &Ai_info[Ships[Pl_objp->instance].ai_index];
|
||||
|
||||
@@ -1264,11 +1259,8 @@ void ai_big_strafe_attack()
|
||||
if ( ai_big_strafe_maybe_retreat(target_dist, &target_pos) )
|
||||
return;
|
||||
|
||||
target_objp = &Objects[aip->target_objnum];
|
||||
|
||||
if (aip->ai_flags & AIF_KAMIKAZE) {
|
||||
if (target_dist < 1200.0f) {
|
||||
//nprintf(("AI", "Kamikaze: %7.3f %7.3f\n", target_dot, target_dist));
|
||||
ai_turn_towards_vector(&target_pos, Pl_objp, flFrametime, Ship_info[Ships[Pl_objp->instance].ship_info_index].srotation_time, NULL, NULL, 0.0f, 0);
|
||||
accelerate_ship(aip, 1.0f);
|
||||
if ((target_dist < 400.0f) && ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
@@ -1304,7 +1296,6 @@ void ai_big_strafe_attack()
|
||||
|
||||
aip->submode = AIS_STRAFE_AVOID;
|
||||
aip->submode_start_time = Missiontime;
|
||||
// nprintf(("Alan","Ship %s entering AIS_STRAFE_AVOID at frame %d\n", Ships[aip->shipnum].ship_name, Framecount));
|
||||
|
||||
if (ai_maybe_fire_afterburner(Pl_objp, aip)) {
|
||||
afterburners_start(Pl_objp);
|
||||
|
||||
+858
-1503
File diff suppressed because it is too large.
Load diff
+23
-48
@@ -131,18 +131,9 @@ char *Ai_goal_text(int goal)
|
||||
}
|
||||
|
||||
// function to maybe add the form on my wing goal for a player's starting wing. Called when a player wing arrives.
|
||||
// Goober5000 - made more generic
|
||||
void ai_maybe_add_form_goal( wing *wingp )
|
||||
{
|
||||
int j;
|
||||
char *wing_leader;
|
||||
|
||||
// if the wing leader isn't available (ie, dead/departed) then go ahead and bail now
|
||||
if (wingp->ship_index[wingp->special_ship] < 0)
|
||||
return;
|
||||
|
||||
// Goober5000 - the wing leader is now not necessarily the player
|
||||
wing_leader = Ships[wingp->ship_index[wingp->special_ship]].ship_name;
|
||||
|
||||
// iterate through the ship_index list of this wing and check for orders. We will do
|
||||
// this for all ships in the wing instead of on a wing only basis in case some ships
|
||||
@@ -152,20 +143,15 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
|
||||
Assert( wingp->ship_index[j] != -1 ); // get Allender
|
||||
|
||||
// don't process wing leader
|
||||
if (j == wingp->special_ship)
|
||||
continue;
|
||||
|
||||
aip = &Ai_info[Ships[wingp->ship_index[j]].ai_index];
|
||||
|
||||
// don't process Player_ship
|
||||
if ( aip == Player_ai )
|
||||
continue;
|
||||
|
||||
// it is sufficient enough to check the first goal entry to see if it has a valid goal
|
||||
if ( aip->goals[0].ai_mode == AI_GOAL_NONE ) {
|
||||
// need to add a form on my wing goal here
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, wing_leader, aip );
|
||||
// need to add a form on my wing goal here. Ships are always forming on the player's wing.
|
||||
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_FORM_ON_WING, -1, Player_ship->ship_name, aip );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,38 +159,28 @@ void ai_maybe_add_form_goal( wing *wingp )
|
||||
void ai_post_process_mission()
|
||||
{
|
||||
object *objp;
|
||||
|
||||
/*
|
||||
// Goober5000 - considering that this is also done in parse_wing_create_ships,
|
||||
// it's redundant (and possibly premature for some wings) here
|
||||
int i;
|
||||
|
||||
// Check ships in player starting wings. Those ships should follow these rules:
|
||||
// (1) if they have no orders, they should get a form on my wing order
|
||||
// (2) if they have an order, they are free to act on it.
|
||||
//
|
||||
// So basically, we are checking for (1)
|
||||
if ( !Fred_running )
|
||||
{
|
||||
int i;
|
||||
if ( !Fred_running ) {
|
||||
// MK, 5/9/98: Used to iterate through MAX_STARTING_WINGS, but this was too many ships forming on player.
|
||||
// Goober5000 - MK originally iterated on only the first wing; now we iterate on only the player wing
|
||||
// because the player wing may not be first
|
||||
for ( i = 0; i < MAX_STARTING_WINGS; i++ ) {
|
||||
if ( Starting_wings[i] == Player_ship->wingnum ) {
|
||||
wing *wingp;
|
||||
|
||||
// Goober5000 - make all wings form on their respective leaders
|
||||
for ( i = 0; i < Num_wings; i++ )
|
||||
{
|
||||
ai_maybe_add_form_goal( &Wings[i] );
|
||||
wingp = &Wings[Starting_wings[i]];
|
||||
|
||||
ai_maybe_add_form_goal( wingp );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// for ( i = 0; i < 1; i++ ) { // MK, 5/9/98: Used to iterate through MAX_STARTING_WINGS, but this was too many ships forming on player.
|
||||
// if ( Starting_wings[i] != -1 ) {
|
||||
// wing *wingp;
|
||||
//
|
||||
// wingp = &Wings[Starting_wings[i]];
|
||||
//
|
||||
// ai_maybe_add_form_goal( wingp );
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
*/
|
||||
|
||||
// for every valid ship object, call process_mission_orders to be sure that ships start the
|
||||
// mission following the orders in the mission file right away instead of waiting N seconds
|
||||
@@ -1373,7 +1349,6 @@ void ai_copy_mission_wing_goal( ai_goal *aigp, ai_info *aip )
|
||||
int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
int status;
|
||||
char *ai_shipname;
|
||||
int return_val;
|
||||
object *objp;
|
||||
ai_info *aip;
|
||||
@@ -1382,7 +1357,6 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
objp = &Objects[objnum];
|
||||
Assert( objp->instance != -1 );
|
||||
ai_shipname = Ships[objp->instance].ship_name;
|
||||
aip = &Ai_info[Ships[objp->instance].ai_index];
|
||||
|
||||
// these orders are always achievable.
|
||||
@@ -1445,8 +1419,6 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
{
|
||||
case AI_GOAL_DOCK:
|
||||
case AI_GOAL_UNDOCK:
|
||||
//status = mission_log_get_time( LOG_SHIP_DOCK, ai_shipname, aigp->ship_name, NULL );
|
||||
//status = mission_log_get_time( LOG_SHIP_UNDOCK, ai_shipname, aigp->ship_name, NULL );
|
||||
//MWA 3/20/97 -- cannot short circuit a dock or undock goal already succeeded -- we must
|
||||
// rely on the goal removal code to just remove this goal. This is because docking/undock
|
||||
// can happen > 1 time per mission per pair of ships. The above checks will find only
|
||||
@@ -1474,8 +1446,13 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
// for this goal to be valid).
|
||||
Assert ( aigp->ai_submode >= 0 );
|
||||
ssp = ship_get_indexed_subsys( &Ships[sindex], aigp->ai_submode );
|
||||
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->target_name, ssp->system_info->subobj_name, NULL );
|
||||
|
||||
if (ssp != NULL) {
|
||||
status = mission_log_get_time( LOG_SHIP_SUBSYS_DESTROYED, aigp->target_name, ssp->system_info->subobj_name, NULL );
|
||||
} else {
|
||||
// not supposed to ever happen, but could if there is a mismatch between the table and model subsystems
|
||||
nprintf(("AI", "Couldn't find subsystem %d for ship %s\n", aigp->ai_submode, Ships[sindex].ship_name));
|
||||
status = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1819,7 +1796,6 @@ int ai_mission_goal_achievable( int objnum, ai_goal *aigp )
|
||||
|
||||
// test code!!!
|
||||
if ( aip->goal_objnum == -1 ) {
|
||||
// -- MK, 11/9/97 -- I was always hitting this: Int3();
|
||||
return AI_GOAL_ACHIEVABLE;
|
||||
}
|
||||
|
||||
@@ -2163,7 +2139,6 @@ void ai_process_mission_orders( int objnum, ai_info *aip )
|
||||
}
|
||||
|
||||
if ( other_obj == NULL ) {
|
||||
//Int3();
|
||||
// assume that the guy he was docked with doesn't exist anymore. (i.e. a cargo containuer
|
||||
// can get destroyed while docked with a freighter.) We should just remove this goal and
|
||||
// let this ship pick up it's next goal.
|
||||
@@ -2431,7 +2406,7 @@ char *ai_add_dock_name(char *str)
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
Assert(strlen(str) < NAME_LENGTH - 1);
|
||||
Assert(strlen(str) <= NAME_LENGTH - 1);
|
||||
for (i=0; i<Num_ai_dock_names; i++)
|
||||
if (!stricmp(Ai_dock_names[i], str))
|
||||
return Ai_dock_names[i];
|
||||
|
||||
+28
-10
@@ -401,7 +401,7 @@ int valid_turret_enemy(object *objp, object *turret_parent)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (objp->type == OBJ_SHIP) ) {
|
||||
if ( objp->type == OBJ_SHIP ) {
|
||||
Assert( objp->instance >= 0 );
|
||||
ship *shipp;
|
||||
ship_info *sip;
|
||||
@@ -835,9 +835,9 @@ int get_nearest_turret_objnum(int turret_parent_objnum, ship_subsys *turret_subs
|
||||
else
|
||||
tt = &Ai_tp_list[Weapon_info[priority_weapon_idx].targeting_priorities[i]];
|
||||
|
||||
int n_types = tt->ship_type.size();
|
||||
int n_s_classes = tt->ship_class.size();
|
||||
int n_w_classes = tt->weapon_class.size();
|
||||
int n_types = (int)tt->ship_type.size();
|
||||
int n_s_classes = (int)tt->ship_class.size();
|
||||
int n_w_classes = (int)tt->weapon_class.size();
|
||||
|
||||
bool found_something;
|
||||
object *ptr = GET_FIRST(&obj_used_list);
|
||||
@@ -1675,8 +1675,6 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
if (wip->wi_flags & WIF_BEAM) {
|
||||
// if this beam isn't free to fire
|
||||
if (!(turret->weapons.flags & SW_FLAG_BEAM_FREE)) {
|
||||
//WMC - remove this
|
||||
//Int3(); // should never get this far
|
||||
return false;
|
||||
}
|
||||
beam_fire_info fire_info;
|
||||
@@ -1707,7 +1705,11 @@ 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++)
|
||||
{
|
||||
{
|
||||
// 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);
|
||||
|
||||
weapon_objnum = weapon_create( turret_pos, &turret_orient, turret_weapon_class, parent_objnum, -1, 1);
|
||||
weapon_set_tracking_info(weapon_objnum, parent_objnum, turret->turret_enemy_objnum, 1, turret->targeted_subsys);
|
||||
|
||||
@@ -1762,8 +1764,9 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
|
||||
}
|
||||
}
|
||||
}
|
||||
turret->turret_next_fire_pos++;
|
||||
}
|
||||
|
||||
turret->turret_next_fire_pos--;
|
||||
// reset any animations if we need to
|
||||
// (I'm not sure how accurate this timestamp would be in practice - taylor)
|
||||
if (turret->turret_animation_position == MA_POS_READY)
|
||||
@@ -2081,6 +2084,12 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
}
|
||||
}
|
||||
|
||||
if ( wip->wi_flags2 & WIF2_SMALL_ONLY ) {
|
||||
if ( (lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP)) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lep->type == OBJ_SHIP) {
|
||||
// Check if we're targeting a protected ship
|
||||
if (lep->flags & OF_PROTECTED) {
|
||||
@@ -2136,7 +2145,7 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
ss->turret_enemy_objnum = -1;
|
||||
|
||||
// Maybe pick a new enemy, unless targeting has been taken over by scripting
|
||||
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override) {
|
||||
if ( turret_should_pick_new_target(ss) && !ss->scripting_target_override ) {
|
||||
Num_find_turret_enemy++;
|
||||
int objnum = find_turret_enemy(ss, parent_objnum, &gpos, &gvec, ss->turret_enemy_objnum);
|
||||
//Assert(objnum < 0 || is_target_beam_valid(tp, objnum));
|
||||
@@ -2144,11 +2153,13 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
if (objnum >= 0 && is_target_beam_valid(&ss->weapons, &Objects[objnum])) {
|
||||
if (ss->turret_enemy_objnum == -1) {
|
||||
ss->turret_enemy_objnum = objnum;
|
||||
ss->targeted_subsys = NULL; // Turret has retargeted; reset subsystem - Valathil for Mantis #2652
|
||||
ss->turret_enemy_sig = Objects[objnum].signature;
|
||||
// why return?
|
||||
return;
|
||||
} else {
|
||||
ss->turret_enemy_objnum = objnum;
|
||||
ss->targeted_subsys = NULL; // Turret has retargeted; reset subsystem - Valathil for Mantis #2652
|
||||
ss->turret_enemy_sig = Objects[objnum].signature;
|
||||
}
|
||||
} else {
|
||||
@@ -2396,7 +2407,6 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
|
||||
}
|
||||
}
|
||||
// moved this here so we increment the fire pos only after we have fired and not during it
|
||||
ss->turret_next_fire_pos++;
|
||||
}
|
||||
|
||||
@@ -2406,6 +2416,14 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
|
||||
//Impose a penalty on turret accuracy for losing site of its goal, or just not being able to fire.
|
||||
turret_update_enemy_in_range(ss, -4*Weapon_info[ss->turret_best_weapon].fire_wait);
|
||||
ss->turret_next_fire_stamp = timestamp(500);
|
||||
|
||||
// If nothing is OK to fire (lost track of the target?)
|
||||
// reset the target (so we don't continue to track what we can't hit)
|
||||
if (tp->flags2 & MSS_FLAG2_TURRET_ONLY_TARGET_IF_CAN_FIRE)
|
||||
{
|
||||
ss->turret_enemy_objnum = -1; // Reset enemy objnum, find a new one next frame.
|
||||
ss->turret_time_enemy_in_range = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -472,7 +472,7 @@ int anim_show_next_frame(anim_instance *instance, float frametime)
|
||||
if ( instance->last_bitmap != -1 ){
|
||||
bm_release(instance->last_bitmap);
|
||||
}
|
||||
bitmap_id = bm_create(16, instance->parent->width, instance->parent->height, instance->frame, bitmap_flags);
|
||||
bitmap_id = bm_create(bpp, instance->parent->width, instance->parent->height, instance->frame, bitmap_flags);
|
||||
}
|
||||
|
||||
if ( bitmap_id == -1 ) {
|
||||
@@ -840,14 +840,14 @@ int anim_free(anim *ptr)
|
||||
|
||||
if ( ptr->flags & (ANF_MEM_MAPPED|ANF_STREAMED) ) {
|
||||
cfclose(ptr->cfile_ptr);
|
||||
if ( ptr->cache ) {
|
||||
if (ptr->cache != NULL) {
|
||||
vm_free(ptr->cache);
|
||||
ptr->cache = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Assert(ptr->data);
|
||||
if ( ptr->data ) {
|
||||
if (ptr->data != NULL) {
|
||||
vm_free(ptr->data);
|
||||
ptr->data = NULL;
|
||||
}
|
||||
@@ -1000,7 +1000,7 @@ void anim_display_info(char *real_filename)
|
||||
printf("FPS: %d\n", A.fps);
|
||||
|
||||
#ifndef NDEBUG
|
||||
printf("Transparent RGB: (%d,%d,%d)\n", A.xparent_r, A.xparent_g, A.xparent_b);
|
||||
printf("Transparent RGB: (%u,%u,%u)\n", A.xparent_r, A.xparent_g, A.xparent_b);
|
||||
#endif
|
||||
|
||||
printf("ac version: %d\n", A.version);
|
||||
|
||||
@@ -49,6 +49,7 @@ anim_instance *init_anim_instance(anim *ptr, int bpp)
|
||||
ptr->instance_count++;
|
||||
inst = (anim_instance *) vm_malloc(sizeof(anim_instance));
|
||||
Assert(inst);
|
||||
memset(inst, 0, sizeof(anim_instance));
|
||||
inst->frame_num = -1;
|
||||
inst->last_frame_num = -1;
|
||||
inst->parent = ptr;
|
||||
|
||||
@@ -797,7 +797,7 @@ void maybe_throw_asteroid(int count)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete asteroid from ::Asteroid_used_list
|
||||
* Delete asteroid from Asteroid_used_list
|
||||
*/
|
||||
void asteroid_delete( object * obj )
|
||||
{
|
||||
@@ -1792,7 +1792,7 @@ void asteroid_parse_tbl()
|
||||
|
||||
Assert( Species_info.size() );
|
||||
// sanity check for debris type sizes
|
||||
for (i = Species_info.size(); i >= 0; i--) {
|
||||
for (i = (int)Species_info.size(); i >= 0; i--) {
|
||||
// must remain in proper order
|
||||
// 0 - generic debris types
|
||||
// > 0 - species specific debris types
|
||||
|
||||
@@ -60,10 +60,10 @@ typedef struct asteroid_info {
|
||||
polymodel *modelp[NUM_DEBRIS_POFS];
|
||||
int model_num[NUM_DEBRIS_POFS];
|
||||
|
||||
asteroid_info( )
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx_sav( -1 ),
|
||||
inner_rad( 0 ), outer_rad( 0 ), damage( 0 ), blast( 0 ),
|
||||
initial_asteroid_strength( 0 ), damage_type_idx( -1 )
|
||||
asteroid_info( )
|
||||
: num_detail_levels( 0 ), max_speed( 0 ), damage_type_idx( 0 ),
|
||||
damage_type_idx_sav( -1 ), inner_rad( 0 ), outer_rad( 0 ),
|
||||
damage( 0 ), blast( 0 ), initial_asteroid_strength( 0 )
|
||||
{
|
||||
name[ 0 ] = NULL;
|
||||
memset( pof_files, 0, sizeof( pof_files ) );
|
||||
|
||||
+220
-149
@@ -80,7 +80,9 @@ static int Bm_ignore_load_count = 0;
|
||||
// 2 = Debug low memory ( only use first frame of each ani )
|
||||
void bm_set_low_mem( int mode )
|
||||
{
|
||||
Assert( (mode >= 0) && (mode<=2 ));
|
||||
Assert( (mode >= 0) && (mode<=2) );
|
||||
|
||||
CLAMP(mode, 0, 2);
|
||||
Bm_low_mem = mode;
|
||||
}
|
||||
|
||||
@@ -102,8 +104,9 @@ int bm_get_next_handle()
|
||||
return bm_next_handle;
|
||||
}
|
||||
|
||||
// Frees a bitmaps data if it should, and
|
||||
// Returns true if bitmap n can free it's data.
|
||||
/**
|
||||
* Frees a bitmaps data if it can
|
||||
*/
|
||||
static void bm_free_data(int n, bool release = false)
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -118,12 +121,12 @@ static void bm_free_data(int n, bool release = false)
|
||||
|
||||
// If there isn't a bitmap in this structure, don't
|
||||
// do anything but clear out the bitmap info
|
||||
if ( be->type==BM_TYPE_NONE)
|
||||
if (be->type==BM_TYPE_NONE)
|
||||
goto SkipFree;
|
||||
|
||||
// Don't free up memory for user defined bitmaps, since
|
||||
// BmpMan isn't the one in charge of allocating/deallocing them.
|
||||
if ( ( be->type==BM_TYPE_USER ) ) {
|
||||
if (be->type==BM_TYPE_USER) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -133,7 +136,7 @@ static void bm_free_data(int n, bool release = false)
|
||||
|
||||
// If this bitmap doesn't have any data to free, skip
|
||||
// the freeing it part of this.
|
||||
if ( (bmp->data == 0) ) {
|
||||
if (bmp->data == 0) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -142,8 +145,6 @@ static void bm_free_data(int n, bool release = false)
|
||||
}
|
||||
|
||||
// Free up the data now!
|
||||
|
||||
// mprintf(( "Bitmap %d freed %d bytes\n", n, bm_bitmaps[n].data_size ));
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
bm_texture_ram -= be->data_size;
|
||||
#endif
|
||||
@@ -166,10 +167,13 @@ SkipFree:
|
||||
be->signature = Bm_next_signature++;
|
||||
}
|
||||
|
||||
// a special version of bm_free_data() that can be safely used in gr_*_texture
|
||||
// to save system memory once textures have been transfered to API memory
|
||||
// it doesn't restore the slot to a pristine state, it only releases the data
|
||||
// NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!!
|
||||
/**
|
||||
* A special version of bm_free_data() that can be safely used in gr_*_texture
|
||||
* to save system memory once textures have been transfered to API memory
|
||||
* it doesn't restore the slot to a pristine state, it only releases the data
|
||||
*
|
||||
* NOTE: THIS SHOULD ONLY BE USED FROM bm_unload_fast()!!!
|
||||
*/
|
||||
static void bm_free_data_fast(int n)
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -182,12 +186,12 @@ static void bm_free_data_fast(int n)
|
||||
|
||||
// If there isn't a bitmap in this structure, don't
|
||||
// do anything but clear out the bitmap info
|
||||
if ( be->type == BM_TYPE_NONE)
|
||||
if (be->type == BM_TYPE_NONE)
|
||||
return;
|
||||
|
||||
// Don't free up memory for user defined bitmaps, since
|
||||
// BmpMan isn't the one in charge of allocating/deallocing them.
|
||||
if ( ( be->type == BM_TYPE_USER ) ) {
|
||||
if (be->type == BM_TYPE_USER) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 )
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -197,7 +201,7 @@ static void bm_free_data_fast(int n)
|
||||
|
||||
// If this bitmap doesn't have any data to free, skip
|
||||
// the freeing it part of this.
|
||||
if ( (bmp->data == 0) ) {
|
||||
if (bmp->data == 0) {
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
if ( be->data_size != 0 ) {
|
||||
bm_texture_ram -= be->data_size;
|
||||
@@ -208,8 +212,6 @@ static void bm_free_data_fast(int n)
|
||||
}
|
||||
|
||||
// Free up the data now!
|
||||
|
||||
// mprintf(( "Bitmap %d freed %d bytes\n", n, bm_bitmaps[n].data_size ));
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
bm_texture_ram -= be->data_size;
|
||||
be->data_size = 0;
|
||||
@@ -238,11 +240,12 @@ void *bm_malloc( int n, int size )
|
||||
bm_texture_ram += size;
|
||||
#endif
|
||||
|
||||
// mprintf(( "Bitmap %d allocated %d bytes\n", n, size ));
|
||||
return vm_malloc(size);
|
||||
}
|
||||
|
||||
// kinda like bm_malloc but only keeps track of how much memory is getting used
|
||||
/**
|
||||
* Like bm_malloc but only keeps track of how much memory is getting used
|
||||
*/
|
||||
void bm_update_memory_used( int n, int size )
|
||||
{
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
@@ -303,9 +306,11 @@ void bm_init()
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
/**
|
||||
* Returns number of bytes of bitmaps locked this frame
|
||||
* @param ntotal number of bytes of bitmaps locked this frame
|
||||
* @param nnew number of bytes of bitmaps locked this frame that weren't locked last frame
|
||||
*/
|
||||
void bm_get_frame_usage(int *ntotal, int *nnew)
|
||||
{
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
@@ -327,12 +332,17 @@ void bm_get_frame_usage(int *ntotal, int *nnew)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Creates a bitmap that exists in RAM somewhere, instead
|
||||
// of coming from a disk file. You pass in a pointer to a
|
||||
// block of 32 (or 8)-bit-per-pixel data. Right now, the only
|
||||
// bpp you can pass in is 32 or 8. On success, it returns the
|
||||
// bitmap number. You cannot free that RAM until bm_release
|
||||
// is called on that bitmap.
|
||||
/**
|
||||
* Creates a bitmap that exists in RAM somewhere, instead
|
||||
* of coming from a disk file.
|
||||
*
|
||||
* You pass in a pointer to a block of 32 (or 8)-bit-per-pixel data.
|
||||
* Right now, the only bpp you can pass in is 32 or 8.
|
||||
*
|
||||
* On success, it returns the bitmap number.
|
||||
*
|
||||
* You cannot free that RAM until bm_release is called on that bitmap.
|
||||
*/
|
||||
int bm_create( int bpp, int w, int h, void *data, int flags )
|
||||
{
|
||||
if (bpp == 8) {
|
||||
@@ -398,10 +408,12 @@ int bm_create( int bpp, int w, int h, void *data, int flags )
|
||||
return bm_bitmaps[n].handle;
|
||||
}
|
||||
|
||||
// slow sub helper function. Given a raw filename and an extension set, try and find the bitmap
|
||||
// that isn't already loaded and may exist somewhere on the disk
|
||||
// returns -1 if it could not be found
|
||||
// index into ext_list[] if it was found as a file, fills img_cfg if available
|
||||
/**
|
||||
* Given a raw filename and an extension set, try and find the bitmap
|
||||
* that isn't already loaded and may exist somewhere on the disk
|
||||
*
|
||||
* @return -1 if it could not be found index into ext_list[] if it was found as a file, fills img_cfg if available
|
||||
*/
|
||||
int bm_load_sub_slow(char *real_filename, const int num_ext, const char **ext_list, CFILE **img_cfp = NULL, int dir_type = CF_TYPE_ANY)
|
||||
{
|
||||
char full_path[MAX_PATH];
|
||||
@@ -427,10 +439,10 @@ int bm_load_sub_slow(char *real_filename, const int num_ext, const char **ext_li
|
||||
return -1;
|
||||
}
|
||||
|
||||
// fast sub helper function. Given a raw filename, try and find a bitmap
|
||||
// that's already loaded
|
||||
// returns 0 if it could not be found
|
||||
// 1 if it already exists, fills in handle
|
||||
/**
|
||||
* Given a raw filename, try and find a bitmap that's already loaded
|
||||
* @return 0 if it could not be found, 1 if it already exists, fills in handle
|
||||
*/
|
||||
int bm_load_sub_fast(char *real_filename, int *handle, int dir_type = CF_TYPE_ANY, bool animated_type = false)
|
||||
{
|
||||
if (Bm_ignore_duplicates)
|
||||
@@ -464,11 +476,13 @@ int bm_load_sub_fast(char *real_filename, int *handle, int dir_type = CF_TYPE_AN
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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. Function doesn't actually load the data, only
|
||||
// width, height, and possibly flags.
|
||||
/**
|
||||
* Loads a bitmap so we can draw with it later.
|
||||
* Function doesn't actually load the data, only width, height, and possibly flags.
|
||||
*
|
||||
* @return A negative number if it couldn't load the bitmap.
|
||||
* @return On success, it returns the bitmap number.
|
||||
*/
|
||||
int bm_load( char *real_filename )
|
||||
{
|
||||
int i, free_slot = -1;
|
||||
@@ -494,7 +508,6 @@ int bm_load( char *real_filename )
|
||||
char *p = strrchr( filename, '.' );
|
||||
if ( p ) {
|
||||
mprintf(( "Someone passed an extension to bm_load for file '%s'\n", real_filename ));
|
||||
//Int3();
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
@@ -591,9 +604,12 @@ Done:
|
||||
return handle;
|
||||
}
|
||||
|
||||
// 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
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
int bm_load_duplicate(char *filename)
|
||||
{
|
||||
int ret;
|
||||
@@ -610,6 +626,37 @@ int bm_load_duplicate(char *filename)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to reload a different bitmap into an existing slot.
|
||||
* This should only be used if you are certain the new picture has the same type, dimensions etc.
|
||||
*
|
||||
* @return negative if the given handle doesn't exist, the filename was empty or the slot is still locked
|
||||
* @return the bitmap_handle on success
|
||||
*/
|
||||
int bm_reload(int bitmap_handle, char* filename)
|
||||
{
|
||||
if ( !bm_inited )
|
||||
bm_init();
|
||||
|
||||
// if no file was passed then get out now
|
||||
if ( (filename == NULL) || (strlen(filename) <= 0) )
|
||||
return -1;
|
||||
|
||||
int bitmapnum = bitmap_handle % MAX_BITMAPS;
|
||||
|
||||
if ( bm_bitmaps[bitmapnum].type == BM_TYPE_NONE )
|
||||
return -1;
|
||||
|
||||
if ( bm_bitmaps[bitmapnum].ref_count )
|
||||
{
|
||||
nprintf(("BmpMan", "Trying to reload a bitmap that is still locked. Filename: %s, ref_count: %d", bm_bitmaps[bitmapnum].filename, bm_bitmaps[bitmapnum].ref_count));
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(bm_bitmaps[bitmapnum].filename, filename, MAX_FILENAME_LEN);
|
||||
return bitmap_handle;
|
||||
}
|
||||
|
||||
DCF(bm_frag,"Shows BmpMan fragmentation")
|
||||
{
|
||||
if ( Dc_command ) {
|
||||
@@ -677,7 +724,6 @@ static int find_block_of(int n)
|
||||
return nstart;
|
||||
}
|
||||
|
||||
// Error( LOCATION, "Couldn't find block of %d frames\n", n );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -757,15 +803,18 @@ int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// bm_load_animation()
|
||||
//
|
||||
// input: filename => filename of animation
|
||||
// nframes => OUTPUT parameter: number of frames in the animation
|
||||
// fps => OUTPUT/OPTIONAL parameter: intended fps for the animation
|
||||
//
|
||||
// returns: bitmap number of first frame in the animation
|
||||
//
|
||||
/**
|
||||
* Load animation
|
||||
*
|
||||
* @param real_filename filename of animation
|
||||
* @param nframes OUTPUT parameter: number of frames in the animation
|
||||
* @param fps OUTPUT/OPTIONAL parameter: intended fps for the animation
|
||||
* @param keyframe Keyframe number
|
||||
* @param can_drop_frames Toggle to allow dropped frames
|
||||
* @param dir_type Directory type
|
||||
*
|
||||
* @returns Bitmap number of first frame in the animation
|
||||
*/
|
||||
int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
|
||||
{
|
||||
int i, n;
|
||||
@@ -800,7 +849,6 @@ int bm_load_animation( char *real_filename, int *nframes, int *fps, int *keyfram
|
||||
char *p = strchr( filename, '.' );
|
||||
if ( p ) {
|
||||
mprintf(( "Someone passed an extension to bm_load_animation for file '%s'\n", real_filename ));
|
||||
//Int3();
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
@@ -1040,7 +1088,10 @@ int bm_is_valid(int handle)
|
||||
return (bm_bitmaps[handle % MAX_BITMAPS].handle == handle);
|
||||
}
|
||||
|
||||
// Gets info. w,h,or flags,nframes or fps can be NULL if you don't care.
|
||||
/**
|
||||
* Gets info.
|
||||
* w,h,flags,nframes or fps can be NULL if you don't care.
|
||||
*/
|
||||
int bm_get_info( int handle, int *w, int * h, ubyte * flags, int *nframes, int *fps)
|
||||
{
|
||||
bitmap * bmp;
|
||||
@@ -1103,7 +1154,9 @@ unsigned int bm_get_signature(int handle)
|
||||
return bm_bitmaps[bitmapnum].signature;
|
||||
}
|
||||
|
||||
//gets the image type
|
||||
/**
|
||||
* Gets the image type
|
||||
*/
|
||||
ubyte bm_get_type(int handle)
|
||||
{
|
||||
if ( !bm_inited ) bm_init();
|
||||
@@ -1114,7 +1167,6 @@ ubyte bm_get_type(int handle)
|
||||
return bm_bitmaps[bitmapnum].type;
|
||||
}
|
||||
|
||||
extern int palman_is_nondarkening(int r,int g, int b);
|
||||
static void bm_convert_format( int bitmapnum, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
int idx;
|
||||
@@ -1246,11 +1298,7 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
|
||||
bm->data = (ptr_u)bm_malloc(first_frame + i, size);
|
||||
|
||||
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0 ,flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
|
||||
|
||||
if ( frame_data == NULL ) {
|
||||
// Error(LOCATION,"Fatal error locking .ani file: %s\n", be->filename);
|
||||
}
|
||||
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0 ,flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
|
||||
|
||||
ubyte *dptr, *sptr;
|
||||
|
||||
@@ -1259,8 +1307,6 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
|
||||
if ( (bm->w!=the_anim->width) || (bm->h!=the_anim->height) ) {
|
||||
// Scale it down
|
||||
// Int3(); // not ready yet - should only be ingame
|
||||
|
||||
// 8 bit
|
||||
if(bpp == 8){
|
||||
int w,h;
|
||||
@@ -1318,8 +1364,6 @@ void bm_lock_ani( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
if ( (i < nframes-1) && can_drop_frames ) {
|
||||
frame_data = anim_get_next_raw_buffer(the_anim_instance, 0, flags & BMP_AABITMAP ? 1 : 0, bm->bpp);
|
||||
}
|
||||
|
||||
//mprintf(( "Checksum = %d\n", be->palette_checksum ));
|
||||
}
|
||||
|
||||
free_anim_instance(the_anim_instance);
|
||||
@@ -1362,9 +1406,8 @@ void bm_lock_user( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, uby
|
||||
break;
|
||||
|
||||
default:
|
||||
Int3();
|
||||
Error( LOCATION, "Unhandled user bitmap conversion from %d to %d bpp", be->info.user.bpp, bmp->bpp );
|
||||
break;
|
||||
// Error( LOCATION, "Unhandled user bitmap conversion from %d to %d bpp", be->info.user.bpp, bmp->bpp );
|
||||
}
|
||||
|
||||
bm_convert_format( bitmapnum, bmp, bpp, flags );
|
||||
@@ -1429,7 +1472,9 @@ void bm_lock_tga( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
bm_convert_format( bitmapnum, bmp, bpp, flags );
|
||||
}
|
||||
|
||||
//lock a dds file
|
||||
/**
|
||||
* Lock a DDS file
|
||||
*/
|
||||
void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
ubyte *data = NULL;
|
||||
@@ -1493,7 +1538,9 @@ void bm_lock_dds( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
#endif
|
||||
}
|
||||
|
||||
// lock a PNG file
|
||||
/**
|
||||
* Lock a PNG file
|
||||
*/
|
||||
void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
ubyte *data = NULL;
|
||||
@@ -1501,7 +1548,6 @@ void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
int d_size;
|
||||
int png_error = PNG_ERROR_INVALID;
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
//int size = bmp->w * bmp->h * d_size;
|
||||
|
||||
// Unload any existing data
|
||||
bm_free_data( bitmapnum );
|
||||
@@ -1539,7 +1585,9 @@ void bm_lock_png( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
#endif
|
||||
}
|
||||
|
||||
// lock a JPEG file
|
||||
/**
|
||||
* Lock a JPEG file
|
||||
*/
|
||||
void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyte bpp, ubyte flags )
|
||||
{
|
||||
ubyte *data = NULL;
|
||||
@@ -1586,11 +1634,12 @@ void bm_lock_jpg( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt
|
||||
MONITOR( NumBitmapPage )
|
||||
MONITOR( SizeBitmapPage )
|
||||
|
||||
// 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.
|
||||
bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
bitmap * bm_lock( int handle, ubyte bpp, ubyte flags, bool nodebug)
|
||||
{
|
||||
bitmap *bmp;
|
||||
bitmap_entry *be;
|
||||
@@ -1601,8 +1650,6 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
|
||||
Assertion( bm_bitmaps[bitmapnum].handle == handle, "Invalid handle %d passed to bm_lock. This might be due to an animation elsewhere in the code being too short.\n", handle ); // INVALID BITMAP HANDLE
|
||||
|
||||
// flags &= (~BMP_RLE);
|
||||
|
||||
// to fix a couple of OGL bpp passes, force 8bit on AABITMAP - taylor
|
||||
if (flags & BMP_AABITMAP)
|
||||
bpp = 8;
|
||||
@@ -1652,7 +1699,7 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
#endif
|
||||
|
||||
// read the file data
|
||||
if ( gr_bm_lock( be->filename, handle, bitmapnum, bpp, flags ) == -1 ) {
|
||||
if ( gr_bm_lock( be->filename, handle, bitmapnum, bpp, flags, nodebug ) == -1 ) {
|
||||
// oops, this isn't good - reset and return NULL
|
||||
bm_unlock( bitmapnum );
|
||||
bm_unload( bitmapnum );
|
||||
@@ -1691,11 +1738,12 @@ bitmap * bm_lock( int handle, ubyte bpp, ubyte flags )
|
||||
return bmp;
|
||||
}
|
||||
|
||||
// Unlocks a bitmap
|
||||
//
|
||||
// Decrements the ref_count member of the bitmap_entry struct. A bitmap can only be unloaded
|
||||
// when the ref_count is 0.
|
||||
//
|
||||
/**
|
||||
* Unlocks a bitmap
|
||||
*
|
||||
* 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 )
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -1722,11 +1770,6 @@ void bm_unlock( int handle )
|
||||
Assert(be->ref_count >= 0); // Trying to unlock data more times than lock was called!!!
|
||||
}
|
||||
|
||||
|
||||
void bm_update()
|
||||
{
|
||||
}
|
||||
|
||||
char *bm_get_filename(int handle)
|
||||
{
|
||||
int n;
|
||||
@@ -1756,16 +1799,19 @@ void bm_get_palette(int handle, ubyte *pal, char *name)
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// bm_release() - unloads the bitmap's data and entire slot, so bitmap 'n' won't be valid anymore
|
||||
// NOTE: this releases the slot of EVERY frame in an ANI so don't pass any frame but the first
|
||||
//
|
||||
// parameters: n => index into bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
//
|
||||
// returns: 1 on successful release, 0 otherwise
|
||||
|
||||
/**
|
||||
* Unloads the bitmap's data and entire slot, so bitmap 'handle' won't be valid anymore
|
||||
* NOTE: this releases the slot of EVERY frame in an ANI so don't pass any frame but the first
|
||||
*
|
||||
* @param handle index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param clear_render_targets Whether to release a render target
|
||||
*
|
||||
* @return 1 on successful release, 0 otherwise
|
||||
*/
|
||||
int bm_release(int handle, int clear_render_targets)
|
||||
{
|
||||
Assert(handle >= 0);
|
||||
|
||||
bitmap_entry *be;
|
||||
|
||||
int n = handle % MAX_BITMAPS;
|
||||
@@ -1859,15 +1905,15 @@ int bm_release(int handle, int clear_render_targets)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// bm_unload() - unloads the data, but not the bitmap info.
|
||||
//
|
||||
// parameters: n => index into bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
//
|
||||
// returns: 0 => unload failed
|
||||
// 1 => unload successful
|
||||
//
|
||||
int bm_unload( int handle, int clear_render_targets )
|
||||
/**
|
||||
* Unloads the data, but not the bitmap info.
|
||||
*
|
||||
* @param handle index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param clear_render_targets Whether to release a render target
|
||||
*
|
||||
* @return 1 on successful release, 0 otherwise
|
||||
*/
|
||||
int bm_unload( int handle, int clear_render_targets, bool nodebug )
|
||||
{
|
||||
bitmap_entry *be;
|
||||
bitmap *bmp;
|
||||
@@ -1889,7 +1935,7 @@ int bm_unload( int handle, int clear_render_targets )
|
||||
Assert( be->handle == handle ); // INVALID BITMAP HANDLE!
|
||||
|
||||
// If it is locked, cannot free it.
|
||||
if (be->ref_count != 0) {
|
||||
if (be->ref_count != 0 && !nodebug) {
|
||||
nprintf(("BmpMan", "Tried to unload %s that has a lock count of %d.. not unloading\n", be->filename, be->ref_count));
|
||||
return 0;
|
||||
}
|
||||
@@ -1901,7 +1947,7 @@ int bm_unload( int handle, int clear_render_targets )
|
||||
if ( be->load_count > 0 )
|
||||
be->load_count--;
|
||||
|
||||
if ( be->load_count != 0 ) {
|
||||
if ( be->load_count != 0 && !nodebug) {
|
||||
nprintf(("BmpMan", "Tried to unload %s that has a load count of %d.. not unloading\n", be->filename, be->load_count + 1));
|
||||
return 0;
|
||||
}
|
||||
@@ -1917,20 +1963,25 @@ int bm_unload( int handle, int clear_render_targets )
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < bm_bitmaps[first].info.ani.num_frames; i++) {
|
||||
nprintf(("BmpMan", "Unloading %s frame %d. %dx%dx%d\n", be->filename, i, bmp->w, bmp->h, bmp->bpp));
|
||||
if(!nodebug)
|
||||
nprintf(("BmpMan", "Unloading %s frame %d. %dx%dx%d\n", be->filename, i, bmp->w, bmp->h, bmp->bpp));
|
||||
bm_free_data(first+i); // clears flags, bbp, data, etc
|
||||
}
|
||||
} else {
|
||||
nprintf(("BmpMan", "Unloading %s. %dx%dx%d\n", be->filename, bmp->w, bmp->h, bmp->bpp));
|
||||
if(!nodebug)
|
||||
nprintf(("BmpMan", "Unloading %s. %dx%dx%d\n", be->filename, bmp->w, bmp->h, bmp->bpp));
|
||||
bm_free_data(n); // clears flags, bbp, data, etc
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// just like bm_unload() except that it doesn't care about what load_count is
|
||||
// and will just plow through and release the data anyway
|
||||
// (NOTE that bm_free_data_fast() is used here and NOT bm_free_data()!)
|
||||
/**
|
||||
* Just like bm_unload() except that it doesn't care about what load_count is
|
||||
* and will just plow through and release the data anyway
|
||||
*
|
||||
* NOTE: that bm_free_data_fast() is used here and NOT bm_free_data()!
|
||||
*/
|
||||
int bm_unload_fast( int handle, int clear_render_targets )
|
||||
{
|
||||
bitmap_entry *be;
|
||||
@@ -1938,7 +1989,6 @@ int bm_unload_fast( int handle, int clear_render_targets )
|
||||
|
||||
int n = handle % MAX_BITMAPS;
|
||||
|
||||
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
be = &bm_bitmaps[n];
|
||||
bmp = &be->bm;
|
||||
@@ -1970,7 +2020,9 @@ int bm_unload_fast( int handle, int clear_render_targets )
|
||||
return 1;
|
||||
}
|
||||
|
||||
// unload all used bitmaps
|
||||
/**
|
||||
* Unload all used bitmaps
|
||||
*/
|
||||
void bm_unload_all()
|
||||
{
|
||||
int i;
|
||||
@@ -2036,7 +2088,9 @@ DCF(bmpman,"Shows/changes bitmap caching parameters and usage")
|
||||
}
|
||||
}
|
||||
|
||||
// Marks a texture as being used for this level
|
||||
/**
|
||||
* Marks a texture as being used for this level
|
||||
*/
|
||||
void bm_page_in_texture( int bitmapnum, int nframes )
|
||||
{
|
||||
int i;
|
||||
@@ -2088,9 +2142,12 @@ void bm_page_in_texture( int bitmapnum, int nframes )
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
/**
|
||||
* Marks a texture as being a transparent texture used for this level
|
||||
*
|
||||
* @param bitmapnum Index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param nframes Animation number of frames
|
||||
*/
|
||||
void bm_page_in_xparent_texture( int bitmapnum, int nframes)
|
||||
{
|
||||
int i;
|
||||
@@ -2135,7 +2192,12 @@ void bm_page_in_xparent_texture( int bitmapnum, int nframes)
|
||||
}
|
||||
}
|
||||
|
||||
// Marks an aabitmap as being used for this level
|
||||
/**
|
||||
* Marks an aabitmap as being used for this level
|
||||
*
|
||||
* @param bitmapnum Index into ::bm_bitmaps ( index returned from bm_load() or bm_create() )
|
||||
* @param nframes Animation number of frames
|
||||
*/
|
||||
void bm_page_in_aabitmap( int bitmapnum, int nframes )
|
||||
{
|
||||
int i;
|
||||
@@ -2155,9 +2217,9 @@ void bm_page_in_aabitmap( int bitmapnum, int nframes )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Tell the bitmap manager to start keeping track of what bitmaps are used where.
|
||||
/**
|
||||
* Tell the bitmap manager to start keeping track of what bitmaps are used where.
|
||||
*/
|
||||
void bm_page_in_start()
|
||||
{
|
||||
int i;
|
||||
@@ -2255,12 +2317,13 @@ void bm_page_in_stop()
|
||||
}
|
||||
|
||||
mprintf(( "Bmpman: %d/%d bitmap slots in use.\n", total_bitmaps, MAX_BITMAPS ));
|
||||
//mprintf(( "Bmpman: Usage went from %d KB to %d KB.\n", usage_before/1024, usage_after/1024 ));
|
||||
|
||||
Bm_paging = 0;
|
||||
}
|
||||
|
||||
// for unloading bitmaps while a mission is going
|
||||
/**
|
||||
* For unloading bitmaps while a mission is going
|
||||
*/
|
||||
int bm_page_out( int bitmap_id )
|
||||
{
|
||||
int n = bitmap_id % MAX_BITMAPS;
|
||||
@@ -2271,7 +2334,6 @@ int bm_page_out( int bitmap_id )
|
||||
if ( bm_bitmaps[n].type == BM_TYPE_NONE )
|
||||
return 0;
|
||||
|
||||
|
||||
Assert( bm_bitmaps[n].handle == bitmap_id ); // INVALID BITMAP HANDLE
|
||||
|
||||
// it's possible to hit < 0 here when model_page_out_textures() is called from
|
||||
@@ -2357,7 +2419,9 @@ void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv
|
||||
*((unsigned int*)pixel) |= (unsigned int)(Gr_current_alpha->mask);
|
||||
}
|
||||
|
||||
// for selecting pixel formats
|
||||
/**
|
||||
* For selecting pixel formats
|
||||
*/
|
||||
void BM_SELECT_SCREEN_FORMAT()
|
||||
{
|
||||
Gr_current_red = &Gr_red;
|
||||
@@ -2397,7 +2461,9 @@ void BM_SELECT_ALPHA_TEX_FORMAT()
|
||||
bm_set_components = bm_set_components_argb_16_tex;
|
||||
}
|
||||
|
||||
// get the rgba components of a pixel, any of the parameters can be NULL
|
||||
/**
|
||||
* Get the rgba components of a pixel, any of the parameters can be NULL
|
||||
*/
|
||||
void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
{
|
||||
int bit_32 = 0;
|
||||
@@ -2406,7 +2472,6 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
bit_32 = 1;
|
||||
}
|
||||
|
||||
|
||||
if(r != NULL){
|
||||
if(bit_32){
|
||||
*r = ubyte(( (*((unsigned int*)pixel) & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale);
|
||||
@@ -2414,6 +2479,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
*r = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_red->mask)>>Gr_current_red->shift)*Gr_current_red->scale);
|
||||
}
|
||||
}
|
||||
|
||||
if(g != NULL){
|
||||
if(bit_32){
|
||||
*g = ubyte(( (*((unsigned int*)pixel) & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale);
|
||||
@@ -2421,6 +2487,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
*g = ubyte(( ( ((unsigned short*)pixel)[0] & Gr_current_green->mask) >>Gr_current_green->shift)*Gr_current_green->scale);
|
||||
}
|
||||
}
|
||||
|
||||
if(b != NULL){
|
||||
if(bit_32){
|
||||
*b = ubyte(( (*((unsigned int*)pixel) & Gr_current_blue->mask)>>Gr_current_blue->shift)*Gr_current_blue->scale);
|
||||
@@ -2440,7 +2507,9 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
|
||||
}
|
||||
}
|
||||
|
||||
// get filename
|
||||
/**
|
||||
* Get filename
|
||||
*/
|
||||
void bm_get_filename(int bitmapnum, char *filename)
|
||||
{
|
||||
if(!bm_is_valid(bitmapnum))
|
||||
@@ -2455,7 +2524,9 @@ void bm_get_filename(int bitmapnum, char *filename)
|
||||
strcpy(filename, bm_bitmaps[n].filename);
|
||||
}
|
||||
|
||||
// needed only for compressed bitmaps
|
||||
/**
|
||||
* Needed only for compressed bitmaps
|
||||
*/
|
||||
int bm_is_compressed(int num)
|
||||
{
|
||||
int n = num % MAX_BITMAPS;
|
||||
@@ -2511,17 +2582,17 @@ int bm_has_alpha_channel(int handle)
|
||||
return (bm_bitmaps[n].bm.true_bpp == 32);
|
||||
}
|
||||
|
||||
// the only real purpose for this is to return the correct TCACHE_TYPE for compressed graphics,
|
||||
// uncompressed graphics are assumed to be of type NORMAL. The only other real format to check
|
||||
// for is TCACHE_TYPE_SECTIONED - taylor
|
||||
/**
|
||||
* Purpose for this is to return the correct TCACHE_TYPE for compressed graphics,
|
||||
* uncompressed graphics are assumed to be of type NORMAL.
|
||||
*
|
||||
* The only other real format to check for is TCACHE_TYPE_SECTIONED - taylor
|
||||
*/
|
||||
int bm_get_tcache_type(int num)
|
||||
{
|
||||
if ( bm_is_compressed(num) )
|
||||
return TCACHE_TYPE_COMPRESSED;
|
||||
|
||||
// if ( bm_is_render_target(num) )
|
||||
// return TCACHE_TYPE_RENDER_TARGET;
|
||||
|
||||
return TCACHE_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
@@ -2548,7 +2619,9 @@ int bm_get_num_mipmaps(int num)
|
||||
return bm_bitmaps[n].num_mipmaps;
|
||||
}
|
||||
|
||||
// convert an 8-bit (256 color) image to a 24-bit BGR image sending new bitmap data to "out_data"
|
||||
/**
|
||||
* Convert an 8-bit (256 color) image to a 24-bit BGR image sending new bitmap data to "out_data"
|
||||
*/
|
||||
int bm_convert_color_index_to_BGR(int num, ubyte **out_data)
|
||||
{
|
||||
int n = num % MAX_BITMAPS;
|
||||
@@ -2631,8 +2704,10 @@ int bm_convert_color_index_to_BGR(int num, ubyte **out_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// list of all bitmaps loaded, but not necessarily in memory
|
||||
// used to debug bmpman after a mission load
|
||||
/**
|
||||
* List of all bitmaps loaded, but not necessarily in memory
|
||||
* used to debug bmpman after a mission load
|
||||
*/
|
||||
void bm_print_bitmaps()
|
||||
{
|
||||
#ifdef BMPMAN_NDEBUG
|
||||
@@ -2651,12 +2726,11 @@ void bm_print_bitmaps()
|
||||
#endif
|
||||
}
|
||||
|
||||
// this will create a render target as close to the desiered resolution as posable of the following base types:
|
||||
// this will create a render target as close to the desired resolution as possable of the following base types:
|
||||
// - BMP_FLAG_RENDER_TARGET_STATIC
|
||||
// static render targets are ones that you intend to draw to once or not very often in game
|
||||
// - BMP_FLAG_RENDER_TARGET_DYNAMIC
|
||||
// dynamic render targets are ones that you will be drawing to all the time (like once per frame)
|
||||
|
||||
int bm_make_render_target( int width, int height, int flags )
|
||||
{
|
||||
int i, n;
|
||||
@@ -2681,11 +2755,9 @@ int bm_make_render_target( int width, int height, int flags )
|
||||
if ( n == -1 )
|
||||
return -1;
|
||||
|
||||
|
||||
if ( !gr_bm_make_render_target(n, &w, &h, &bpp, &mm_lvl, flags) )
|
||||
return -1;
|
||||
|
||||
|
||||
Assert( mm_lvl > 0 );
|
||||
|
||||
if (flags & BMP_FLAG_RENDER_TARGET_STATIC) {
|
||||
@@ -2728,7 +2800,6 @@ int bm_make_render_target( int width, int height, int flags )
|
||||
if (bm_bitmaps[n].mem_taken) {
|
||||
bm_bitmaps[n].bm.data = (ptr_u) bm_malloc(n, bm_bitmaps[n].mem_taken);
|
||||
}
|
||||
// bm_update_memory_used( n, bm_bitmaps[n].mem_taken );
|
||||
|
||||
return bm_bitmaps[n].handle;
|
||||
}
|
||||
@@ -2762,7 +2833,7 @@ int bm_set_render_target(int handle, int face)
|
||||
|
||||
if ( gr_bm_set_render_target(n, face) ) {
|
||||
if (gr_screen.rendering_to_texture == -1) {
|
||||
//if we are moveing from the back buffer to a texture save whatever the current settings are
|
||||
//if we are moving from the back buffer to a texture save whatever the current settings are
|
||||
gr_screen.save_max_w = gr_screen.max_w;
|
||||
gr_screen.save_max_h = gr_screen.max_h;
|
||||
}
|
||||
|
||||
+6
-10
@@ -19,11 +19,6 @@
|
||||
#define BMPMAN_NDEBUG
|
||||
#endif
|
||||
|
||||
|
||||
// this is causing problems - let's UP IT -- Kazan
|
||||
// bumped from 3500 to 4500 2004/09/21 - taylor
|
||||
// bumped to 4750 2005/02/03 - taylor
|
||||
//#define MAX_BITMAPS 3500 // How many bitmaps the game can handle
|
||||
#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
|
||||
@@ -113,7 +108,7 @@ 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 );
|
||||
int bm_unload( int n, int clear_render_targets = 0, bool nodebug = false);
|
||||
|
||||
// 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
|
||||
@@ -137,7 +132,7 @@ extern int bm_load_either(char *filename, int *nframes = NULL, int *fps = NULL,
|
||||
// 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 );
|
||||
extern bitmap * bm_lock( int bitmapnum, ubyte bpp, ubyte flags, bool nodebug = false);
|
||||
|
||||
// The signature is a field that gets filled in with
|
||||
// a unique signature for each bitmap. The signature for each bitmap
|
||||
@@ -160,9 +155,6 @@ int bm_get_info( int bitmapnum, int *w=NULL, int * h=NULL, ubyte * flags=NULL, i
|
||||
// get filename
|
||||
extern void bm_get_filename(int bitmapnum, char *filename);
|
||||
|
||||
// resyncs all the bitmap palette
|
||||
extern void bm_update();
|
||||
|
||||
// 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();
|
||||
@@ -179,6 +171,9 @@ void bm_gfx_get_pixel( int bitmap, float u, float v, ubyte *r, ubyte *g, ubyte *
|
||||
// nnew = number of bytes of bitmaps locked this frame that weren't locked last frame
|
||||
void bm_get_frame_usage(int *ntotal, int *nnew);
|
||||
|
||||
// Reload a different image into an existing bmpman slot
|
||||
int bm_reload(int bitmap_handle, char* filename);
|
||||
|
||||
/*
|
||||
* Example on using bm_create
|
||||
*
|
||||
@@ -287,4 +282,5 @@ int bm_make_render_target( int width, int height, int flags );
|
||||
int bm_is_render_target(int bitmap_id);
|
||||
int bm_set_render_target(int handle, int face = -1);
|
||||
|
||||
int bm_load_and_parse_eff(char *filename, int dir_type, int *nframes, int *nfps, int *key, ubyte *type);
|
||||
#endif
|
||||
@@ -1266,7 +1266,7 @@ void cfread_string_len(char *buf,int n, CFILE *file)
|
||||
{
|
||||
int len;
|
||||
len = cfread_int(file);
|
||||
Assert( len < n );
|
||||
Assertion( (len < n), "len: %i, n: %i", len, n );
|
||||
if (len)
|
||||
cfread(buf, len, 1, file);
|
||||
|
||||
|
||||
+15
-4
@@ -271,8 +271,15 @@ void cfread_angles(angles *ang, CFILE *file, int ver = 0, angles *deflt = NULL);
|
||||
// Reads variable length, null-termined string. Will only read up
|
||||
// to n characters.
|
||||
void cfread_string(char *buf,int n, CFILE *file);
|
||||
// Read a fixed length that is null-terminatedm, and has the length
|
||||
// stored in file
|
||||
/**
|
||||
* @brief Read a fixed length string that is not null-terminated, with the length stored in file
|
||||
*
|
||||
* @param buf Pre-allocated array to store string
|
||||
* @param n Size of pre-allocated array
|
||||
* @param file File to read from
|
||||
*
|
||||
* @note Appends NULL character to string (buf)
|
||||
*/
|
||||
void cfread_string_len(char *buf,int n, CFILE *file);
|
||||
|
||||
// functions for writing cfiles
|
||||
@@ -289,8 +296,12 @@ int cfwrite_angles(angles *ang, CFILE *file);
|
||||
// writes variable length, null-termined string.
|
||||
int cfwrite_string(char *buf, CFILE *file);
|
||||
|
||||
// write a fixed length that is null-terminatedm, and has the length
|
||||
// stored in file
|
||||
/**
|
||||
* @brief Write a fixed length string (not including its null terminator), with the length stored in file
|
||||
*
|
||||
* @param buf String to write to file
|
||||
* @param file File to write to
|
||||
*/
|
||||
int cfwrite_string_len(const char *buf, CFILE *file);
|
||||
|
||||
int cf_get_file_list( SCP_vector<SCP_string> &list, int pathtype, char *filter, int sort = CF_SORT_NONE, SCP_vector<file_list_info> *info = NULL );
|
||||
|
||||
@@ -261,7 +261,7 @@ void extract_all_files(char *file)
|
||||
|
||||
printf("Extracting: %s...\n", file);
|
||||
|
||||
for (uint i = 0; i < VP_FileInfo.size(); i++) {
|
||||
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
|
||||
// save the file path to a temp location and recursively make the needed directories
|
||||
if (have_outdir) {
|
||||
if ( (out_len + 1 + strlen(path)) > MAX_PATH-1 )
|
||||
@@ -365,7 +365,7 @@ void list_all_files(char *file)
|
||||
|
||||
printf(" Name Size Offset Date/Time Path\n");
|
||||
printf("-------------------------------------------------------------------------------\n");
|
||||
for (uint i = 0; i < VP_FileInfo.size(); i++) {
|
||||
for (size_t i = 0; i < VP_FileInfo.size(); i++) {
|
||||
plat_time = VP_FileInfo[i].write_time; // gets rid of some platform strangeness this way
|
||||
strftime(out_time, 32, "%F %H:%M", localtime(&plat_time)); // YYYY-mm-dd HH:mm (ISO 8601 date format, 24-hr time)
|
||||
|
||||
|
||||
@@ -376,6 +376,7 @@ cmdline_parm no3dsound_arg("-no_3d_sound", NULL); // Cmdline_no_3d_sound - Disa
|
||||
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);
|
||||
|
||||
int Cmdline_load_all_weapons = 0;
|
||||
int Cmdline_nohtl = 0;
|
||||
@@ -390,6 +391,7 @@ int Cmdline_no_3d_sound = 0;
|
||||
int Cmdline_no_glsl_model_rendering = 0;
|
||||
int Cmdline_no_di_mouse = 0;
|
||||
int Cmdline_drawelements = 0;
|
||||
char* Cmdline_keyboard_layout = NULL;
|
||||
|
||||
// Developer/Testing related
|
||||
cmdline_parm start_mission_arg("-start_mission", NULL); // Cmdline_start_mission
|
||||
@@ -437,6 +439,12 @@ 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
|
||||
|
||||
float Cmdline_percentflashtobang = -1.0;
|
||||
int Cmdline_enforce_concurrent_sound_count = 1;
|
||||
|
||||
cmdline_parm percent_flashtobang_arg("-percent_flashtobang", NULL);
|
||||
cmdline_parm do_not_enforce_concurrent_sound("-donotenforce", NULL);
|
||||
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -645,11 +653,17 @@ void os_validate_parms(char *cmdline)
|
||||
snprintf(buffer, 128, "Unrecognized command line parameter, \"%s\", continue?", token);
|
||||
message = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingASCII);
|
||||
|
||||
if ( CFUserNotificationDisplayAlert(0, kCFUserNotificationPlainAlertLevel, NULL, NULL, NULL, CFSTR("Unknown Command"), message, NULL, CFSTR("Quit"), NULL, &result) )
|
||||
if ( CFUserNotificationDisplayAlert(0, kCFUserNotificationPlainAlertLevel, NULL, NULL, NULL, CFSTR("Unknown Command"), message, NULL, CFSTR("Quit"), NULL, &result) ) {
|
||||
CFRelease(message);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (result != kCFUserNotificationDefaultResponse)
|
||||
if (result != kCFUserNotificationDefaultResponse) {
|
||||
CFRelease(message);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
CFRelease(message);
|
||||
#else
|
||||
// if we got a -help, --help, -h, or -? then show the help text, otherwise show unknown option
|
||||
if ( !stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?") ) {
|
||||
@@ -1359,6 +1373,11 @@ bool SetCmdlineParams()
|
||||
Cmdline_drawelements = 1;
|
||||
}
|
||||
|
||||
if( keyboard_layout.found())
|
||||
{
|
||||
Cmdline_keyboard_layout = keyboard_layout.str();
|
||||
}
|
||||
|
||||
if ( snd_preload_arg.found() )
|
||||
{
|
||||
Cmdline_snd_preload = 1;
|
||||
@@ -1397,11 +1416,7 @@ bool SetCmdlineParams()
|
||||
if ( ogl_spec_arg.found() ) {
|
||||
Cmdline_ogl_spec = ogl_spec_arg.get_float();
|
||||
|
||||
if ( Cmdline_ogl_spec < 0.0f )
|
||||
Cmdline_ogl_spec = 0.0f;
|
||||
|
||||
if ( Cmdline_ogl_spec > 128.0f )
|
||||
Cmdline_ogl_spec = 128.0f;
|
||||
CLAMP(Cmdline_ogl_spec, 0.0f, 128.0f);
|
||||
}
|
||||
|
||||
if ( rearm_timer_arg.found() )
|
||||
@@ -1452,6 +1467,16 @@ bool SetCmdlineParams()
|
||||
Cmdline_bloom_intensity = bloom_intensity_arg.get_int();
|
||||
}
|
||||
|
||||
if ( percent_flashtobang_arg.found() )
|
||||
{
|
||||
Cmdline_percentflashtobang = percent_flashtobang_arg.get_float();
|
||||
}
|
||||
|
||||
if ( do_not_enforce_concurrent_sound.found() )
|
||||
{
|
||||
Cmdline_enforce_concurrent_sound_count = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,7 @@ extern int Cmdline_no_3d_sound;
|
||||
extern int Cmdline_no_glsl_model_rendering;
|
||||
extern int Cmdline_no_di_mouse;
|
||||
extern int Cmdline_drawelements;
|
||||
extern char* Cmdline_keyboard_layout;
|
||||
|
||||
// Developer/Testing related
|
||||
extern char *Cmdline_start_mission;
|
||||
@@ -145,7 +146,9 @@ extern int Cmdline_verify_vps;
|
||||
extern int Cmdline_no_grab;
|
||||
#endif
|
||||
|
||||
|
||||
// Temp, only for evaluating new defaults
|
||||
extern float Cmdline_percentflashtobang;
|
||||
extern int Cmdline_enforce_concurrent_sound_count;
|
||||
|
||||
//extern char FreeSpace_Directory[]; // allievating a cfilesystem problem caused by fred -- Kazan
|
||||
#endif
|
||||
@@ -454,7 +454,7 @@ void control_config_list_prepare()
|
||||
|
||||
Num_cc_lines = y = z = 0;
|
||||
while (z < CCFG_MAX) {
|
||||
if ((Control_config[z].tab == Tab)) {
|
||||
if (Control_config[z].tab == Tab) {
|
||||
k = Control_config[z].key_id;
|
||||
j = Control_config[z].joy_id;
|
||||
|
||||
@@ -1610,8 +1610,8 @@ void control_config_do_frame(float frametime)
|
||||
for (i=0; i<CCFG_MAX; i++) {
|
||||
if (Control_config[i].joy_id == j) {
|
||||
z = i;
|
||||
for (j=0; j<NUM_BUTTONS; j++){
|
||||
CC_Buttons[gr_screen.res][j].button.reset();
|
||||
for (size_t buttonid=0; buttonid<NUM_BUTTONS; buttonid++){
|
||||
CC_Buttons[gr_screen.res][buttonid].button.reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2100,7 +2100,7 @@ void control_check_indicate()
|
||||
Control_check_count = 0;
|
||||
}
|
||||
|
||||
int check_control(int id, int key)
|
||||
int check_control_used(int id, int key)
|
||||
{
|
||||
int z, mask;
|
||||
static int last_key = 0;
|
||||
@@ -2152,10 +2152,8 @@ int check_control(int id, int key)
|
||||
z &= KEY_MASK;
|
||||
|
||||
if (keyd_pressed[z] || key_down_count(z)) {
|
||||
if ( !hud_squadmsg_read_key(z) ) {
|
||||
control_used(id);
|
||||
return 1;
|
||||
}
|
||||
control_used(id);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2171,6 +2169,24 @@ int check_control(int id, int key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for check_control_used. Allows the game to ignore the key if told to do so by the ignore-key SEXP.
|
||||
*/
|
||||
int check_control(int id, int key)
|
||||
{
|
||||
if (check_control_used(id, key)) {
|
||||
if (Ignored_keys[id]) {
|
||||
if (Ignored_keys[id] > 0) {
|
||||
Ignored_keys[id]--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get heading, pitch, bank, throttle abs. and throttle rel. values.
|
||||
void control_get_axes_readings(int *h, int *p, int *b, int *ta, int *tr)
|
||||
{
|
||||
|
||||
@@ -163,10 +163,10 @@ config_item Control_config[CCFG_MAX + 1] = {
|
||||
{ KEY_SHIFTED | KEY_B, -1, TARGET_TAB, true, "Target Previous Hostile Bomb or Bomber" },
|
||||
|
||||
// multiplayer messaging keys
|
||||
{ KEY_1, -1, COMPUTER_TAB, true, "(Multiplayer) Message All", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_2, -1, COMPUTER_TAB, true, "(Multiplayer) Message Friendly", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_3, -1, COMPUTER_TAB, true, "(Multiplayer) Message Hostile", CC_TYPE_CONTINUOUS },
|
||||
{ KEY_4, -1, COMPUTER_TAB, true, "(Multiplayer) Message Target", CC_TYPE_CONTINUOUS },
|
||||
{ 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" },
|
||||
|
||||
@@ -127,6 +127,7 @@ bool movie_play(char *name)
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
Mouse_hidden--; // show the mouse cursor!
|
||||
return false;
|
||||
}
|
||||
} else if (rc == MOVIE_MVE) {
|
||||
@@ -143,6 +144,7 @@ bool movie_play(char *name)
|
||||
} else {
|
||||
// uh-oh, movie is invalid... Abory, Retry, Fail?
|
||||
mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name));
|
||||
Mouse_hidden--; // show the mouse cursor!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+176
-36
@@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/def_files.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
@@ -42,6 +43,9 @@ static int g_screenX = 0;
|
||||
static int g_screenY = 0;
|
||||
|
||||
static GLuint GLtex = 0;
|
||||
static GLuint ytex = 0;
|
||||
static GLuint utex = 0;
|
||||
static GLuint vtex = 0;
|
||||
static GLint gl_screenYH = 0;
|
||||
static GLint gl_screenXW = 0;
|
||||
static GLfloat gl_screenU = 0;
|
||||
@@ -74,7 +78,7 @@ static int audiofd_fragsize = 0;
|
||||
static longlong videobuf_granulepos = -1;
|
||||
static double videobuf_time = 0;
|
||||
|
||||
|
||||
static bool use_shaders = true;
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utility items
|
||||
//
|
||||
@@ -82,8 +86,8 @@ static double videobuf_time = 0;
|
||||
// helper; just grab some more compressed bitstream and sync it for page extraction
|
||||
static int OGG_buffer_data(THEORAFILE *movie)
|
||||
{
|
||||
char *buffer = ogg_sync_buffer(&movie->osyncstate, 4096);
|
||||
int bytes = cfread(buffer, 1, 4096, movie->cfp);
|
||||
char *buffer = ogg_sync_buffer(&movie->osyncstate, 8192); // Doubled read size to fix choppy audio with high bitrate movies - Valathil
|
||||
int bytes = cfread(buffer, 1, 8192, movie->cfp);
|
||||
|
||||
ogg_sync_wrote(&movie->osyncstate, bytes);
|
||||
|
||||
@@ -326,6 +330,8 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
{
|
||||
float scale_by = 0.0f;
|
||||
|
||||
GLhandleARB shader_id = 0;
|
||||
|
||||
if (video_inited)
|
||||
return;
|
||||
|
||||
@@ -339,35 +345,137 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
opengl_set_texture_target(GL_TEXTURE_2D);
|
||||
opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
|
||||
|
||||
glGenTextures(1, &GLtex);
|
||||
if(!Use_GLSL)
|
||||
use_shaders = false;
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
if(use_shaders) {
|
||||
glGenTextures(1, &ytex);
|
||||
glGenTextures(1, &utex);
|
||||
glGenTextures(1, &vtex);
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
Assert( ytex != 0 );
|
||||
Assert( utex != 0 );
|
||||
Assert( vtex != 0 );
|
||||
|
||||
|
||||
if ( ytex + utex + vtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
char *vert = NULL, *frag = NULL;
|
||||
opengl_shader_t new_shader;
|
||||
|
||||
// choose appropriate files
|
||||
char *vert_name = "video-v.sdr";
|
||||
char *frag_name = "video-f.sdr";
|
||||
|
||||
mprintf(("Compiling video-processing shader ... \n"));
|
||||
|
||||
// read vertex shader
|
||||
CFILE *cf_shader = cfopen(vert_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
vert = (char*) vm_malloc(len + 1);
|
||||
cfread(vert, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
} else {
|
||||
mprintf((" Loading built-in default shader for: %s\n", vert_name));
|
||||
vert = defaults_get_file(vert_name);
|
||||
}
|
||||
|
||||
if(!vert)
|
||||
use_shaders = false;
|
||||
|
||||
// read fragment shader
|
||||
cf_shader = cfopen(frag_name, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS);
|
||||
|
||||
if (cf_shader != NULL) {
|
||||
int len = cfilelength(cf_shader);
|
||||
frag = (char*) vm_malloc(len + 1);
|
||||
cfread(frag, len + 1, 1, cf_shader);
|
||||
cfclose(cf_shader);
|
||||
} else {
|
||||
mprintf((" Loading built-in default shader for: %s\n", frag_name));
|
||||
frag = defaults_get_file(frag_name);
|
||||
}
|
||||
|
||||
if(!vert)
|
||||
use_shaders = false;
|
||||
Verify( vert != NULL );
|
||||
Verify( frag != NULL );
|
||||
|
||||
shader_id = opengl_shader_create(vert, frag);
|
||||
vglUseProgramObjectARB(shader_id);
|
||||
if (!shader_id)
|
||||
use_shaders = false;
|
||||
}
|
||||
|
||||
if(!use_shaders) {
|
||||
glGenTextures(1, &GLtex);
|
||||
|
||||
Assert( GLtex != 0 );
|
||||
|
||||
if ( GLtex == 0 ) {
|
||||
nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gr_set_lighting(false, false);
|
||||
GL_state.Texture.DisableAll();
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
|
||||
if(!use_shaders) {
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(GLtex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
GL_state.SetTextureSource(TEXTURE_SOURCE_DECAL);
|
||||
GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
if(use_shaders) {
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(ytex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 2048, 2048, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_RGB8, wp2, hp2, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(utex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(2);
|
||||
GL_state.Texture.SetTarget(GL_texture_target);
|
||||
GL_state.Texture.Enable(vtex);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
|
||||
glTexImage2D(GL_state.Texture.GetTarget(), 0, GL_LUMINANCE8, 1024, 1024, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
float screen_ratio = (float)gr_screen.max_w / (float)gr_screen.max_h;
|
||||
float movie_ratio = (float)g_screenWidth / (float)g_screenHeight;
|
||||
|
||||
@@ -390,15 +498,17 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
pixelbuf = (ubyte *) vm_malloc_q(g_screenWidth * g_screenHeight * 3);
|
||||
if(!use_shaders) {
|
||||
pixelbuf = (ubyte *) vm_malloc_q(g_screenWidth * g_screenHeight * 3);
|
||||
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
if (pixelbuf == NULL) {
|
||||
nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
|
||||
video_inited = 1;
|
||||
return;
|
||||
}
|
||||
memset( pixelbuf, 0, g_screenWidth * g_screenHeight * 3 );
|
||||
}
|
||||
|
||||
memset( pixelbuf, 0, g_screenWidth * g_screenHeight * 3 );
|
||||
|
||||
|
||||
if (scale_video) {
|
||||
g_screenX = ((fl2i(gr_screen.max_w / scale_by + 0.5f) - g_screenWidth) / 2);
|
||||
@@ -416,8 +526,19 @@ static void OGG_video_init(theora_info *tinfo)
|
||||
|
||||
gl_screenU = i2fl(g_screenWidth) / i2fl(wp2);
|
||||
gl_screenV = i2fl(g_screenHeight) / i2fl(hp2);
|
||||
}
|
||||
|
||||
if(use_shaders) {
|
||||
gl_screenU = i2fl(tinfo->frame_width-1) / i2fl(2048) ;
|
||||
gl_screenV = i2fl(tinfo->frame_height-1) / i2fl(2048);
|
||||
GL_state.Texture.SetShaderMode(GL_TRUE);
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "ytex"), 0 );
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "utex"), 1 );
|
||||
vglUniform1iARB( vglGetUniformLocationARB(shader_id, "vtex"), 2 );
|
||||
}
|
||||
}
|
||||
if(!use_shaders && tinfo->frame_height > 450) {
|
||||
mprintf(("VIDEO: No shader support and hd video is beeing played this can get choppy."));
|
||||
}
|
||||
video_inited = 1;
|
||||
}
|
||||
|
||||
@@ -434,12 +555,23 @@ static void OGG_video_close()
|
||||
}
|
||||
|
||||
GL_state.Texture.Disable();
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
|
||||
if(use_shaders) {
|
||||
GL_state.Texture.Delete(ytex);
|
||||
GL_state.Texture.Delete(utex);
|
||||
GL_state.Texture.Delete(vtex);
|
||||
glDeleteTextures(1, &ytex);
|
||||
glDeleteTextures(1, &utex);
|
||||
glDeleteTextures(1, &vtex);
|
||||
} else {
|
||||
GL_state.Texture.Delete(GLtex);
|
||||
glDeleteTextures(1, &GLtex);
|
||||
}
|
||||
opengl_set_texture_target();
|
||||
|
||||
ytex = utex = vtex = 0;
|
||||
GLtex = 0;
|
||||
GL_state.Texture.SetShaderMode(GL_FALSE);
|
||||
opengl_shader_set_current( 0 );
|
||||
}
|
||||
|
||||
if (pixelbuf != NULL) {
|
||||
@@ -455,7 +587,6 @@ static void OGG_video_close()
|
||||
g_screenX = 0;
|
||||
g_screenY = 0;
|
||||
|
||||
GLtex = 0;
|
||||
gl_screenYH = 0;
|
||||
gl_screenXW = 0;
|
||||
gl_screenU = 0;
|
||||
@@ -530,16 +661,25 @@ static void convert_YUV_to_RGB(yuv_buffer *yuv)
|
||||
}
|
||||
}
|
||||
|
||||
extern int Mouse_hidden;
|
||||
static void OGG_video_draw(theora_state *tstate)
|
||||
{
|
||||
yuv_buffer yuv;
|
||||
|
||||
theora_decode_YUVout(tstate, &yuv);
|
||||
convert_YUV_to_RGB(&yuv);
|
||||
|
||||
if(!use_shaders)
|
||||
convert_YUV_to_RGB(&yuv);
|
||||
if (gr_screen.mode == GR_OPENGL) {
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
|
||||
|
||||
if(use_shaders) {
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.y_stride, yuv.y_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.y);
|
||||
GL_state.Texture.SetActiveUnit(1);
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.u);
|
||||
GL_state.Texture.SetActiveUnit(2);
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, yuv.uv_stride, yuv.uv_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, yuv.v);
|
||||
} else {
|
||||
glTexSubImage2D(GL_state.Texture.GetTarget(), 0, 0, 0, g_screenWidth, g_screenHeight, GL_BGR, GL_UNSIGNED_BYTE, pixelbuf);
|
||||
}
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(g_screenX, g_screenY);
|
||||
@@ -554,7 +694,7 @@ static void OGG_video_draw(theora_state *tstate)
|
||||
glVertex2i(gl_screenXW, g_screenY);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
Mouse_hidden = 1;
|
||||
gr_flip();
|
||||
os_poll();
|
||||
|
||||
|
||||
+67
-113
@@ -9,7 +9,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "debris/debris.h"
|
||||
#include "render/3d.h"
|
||||
#include "fireball/fireballs.h"
|
||||
@@ -31,15 +30,11 @@
|
||||
#include "weapon/weapon.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_LIFE 10.0f
|
||||
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
|
||||
#define DEBRIS_SOUND_DELAY 2000 // time to start debris sound after created
|
||||
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES // limit the number of hull debris chunks that can exist.
|
||||
|
||||
// limit the number of hull debris chunks that can exist.
|
||||
//#define MAX_HULL_PIECES 10
|
||||
#define MAX_HULL_PIECES MAX_DEBRIS_PIECES //-WMCD
|
||||
int Num_hull_pieces; // number of hull pieces in existance
|
||||
debris Hull_debris_list; // head of linked list for hull debris chunks, for quick search
|
||||
|
||||
@@ -59,13 +54,10 @@ int Debris_num_submodels = 0;
|
||||
#define MAX_SPEED_SMALL_DEBRIS 200 // maximum velocity of small debris piece
|
||||
#define MAX_SPEED_BIG_DEBRIS 150 // maximum velocity of big debris piece
|
||||
#define MAX_SPEED_CAPITAL_DEBRIS 100 // maximum velocity of capital debris piece
|
||||
//#define DEBRIS_SPEED_DEBUG
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_start_death_roll()
|
||||
//
|
||||
// Start the sequence of a piece of debris writhing in unholy agony!!!
|
||||
//
|
||||
/**
|
||||
* Start the sequence of a piece of debris writhing in unholy agony!!!
|
||||
*/
|
||||
static void debris_start_death_roll(object *debris_obj, debris *debris_p)
|
||||
{
|
||||
if (debris_p->is_hull) {
|
||||
@@ -87,14 +79,11 @@ static void debris_start_death_roll(object *debris_obj, debris *debris_p)
|
||||
}
|
||||
|
||||
debris_obj->flags |= OF_SHOULD_BE_DEAD;
|
||||
// demo_do_flag_dead(OBJ_INDEX(debris_obj));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_init()
|
||||
//
|
||||
// This will get called at the start of each level.
|
||||
//
|
||||
/**
|
||||
* This will get called at the start of each level.
|
||||
*/
|
||||
void debris_init()
|
||||
{
|
||||
int i;
|
||||
@@ -118,7 +107,9 @@ void debris_init()
|
||||
list_init(&Hull_debris_list);
|
||||
}
|
||||
|
||||
// Page in debris bitmaps at level load
|
||||
/**
|
||||
* Page in debris bitmaps at level load
|
||||
*/
|
||||
void debris_page_in()
|
||||
{
|
||||
uint i;
|
||||
@@ -152,10 +143,9 @@ void debris_page_in()
|
||||
MONITOR(NumSmallDebrisRend)
|
||||
MONITOR(NumHullDebrisRend)
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_render()
|
||||
//
|
||||
//
|
||||
/**
|
||||
* Render debris
|
||||
*/
|
||||
void debris_render(object * obj)
|
||||
{
|
||||
int i, num, swapped;
|
||||
@@ -211,7 +201,9 @@ void debris_render(object * obj)
|
||||
}
|
||||
}
|
||||
|
||||
// Removed the DEBRIS_EXPIRE flag, and remove item from Hull_debris_list
|
||||
/**
|
||||
* Removed the ::DEBRIS_EXPIRE flag, and remove item from ::Hull_debris_list
|
||||
*/
|
||||
void debris_clear_expired_flag(debris *db)
|
||||
{
|
||||
if ( db->flags & DEBRIS_EXPIRE ) {
|
||||
@@ -224,12 +216,11 @@ void debris_clear_expired_flag(debris *db)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_delete()
|
||||
//
|
||||
// Delete the debris object. This is only ever called via obj_delete(). Do not call directly.
|
||||
// Use debris_start_death_roll() if you want to force a debris piece to die.
|
||||
//
|
||||
/**
|
||||
* Delete the debris object.
|
||||
* This is only ever called via obj_delete(). Do not call directly.
|
||||
* Use debris_start_death_roll() if you want to force a debris piece to die.
|
||||
*/
|
||||
void debris_delete( object * obj )
|
||||
{
|
||||
int num;
|
||||
@@ -249,9 +240,11 @@ void debris_delete( object * obj )
|
||||
Num_debris_pieces--;
|
||||
}
|
||||
|
||||
// If debris piece *db is far away from all players, make it go away very soon.
|
||||
// In single player game, delete if MAX_DEBRIS_DIST from player.
|
||||
// In multiplayer game, delete if MAX_DEBRIS_DIST from all players.
|
||||
/**
|
||||
* If debris piece *db is far away from all players, make it go away very soon.
|
||||
* In single player game, delete if MAX_DEBRIS_DIST from player.
|
||||
* In multiplayer game, delete if MAX_DEBRIS_DIST from all players.
|
||||
*/
|
||||
void maybe_delete_debris(debris *db)
|
||||
{
|
||||
object *objp;
|
||||
@@ -276,24 +269,16 @@ void maybe_delete_debris(debris *db)
|
||||
}
|
||||
}
|
||||
|
||||
// broke debris_move into debris_process_pre and debris_process_post as was done with all
|
||||
// *_move functions on 8/13 by MK and MA.
|
||||
void debris_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}
|
||||
|
||||
MONITOR(NumSmallDebris)
|
||||
MONITOR(NumHullDebris)
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_process_post()
|
||||
//
|
||||
// Do various updates to debris: check if time to die, start fireballs
|
||||
//
|
||||
// parameters: obj => pointer to debris object
|
||||
// frame_time => time elapsed since last debris_move() called
|
||||
//
|
||||
// Maybe delete debris if it's very far away from player.
|
||||
/**
|
||||
* Do various updates to debris: check if time to die, start fireballs
|
||||
* Maybe delete debris if it's very far away from player.
|
||||
*
|
||||
* @param obj pointer to debris object
|
||||
* @param frame_time time elapsed since last debris_move() called
|
||||
*/
|
||||
void debris_process_post(object * obj, float frame_time)
|
||||
{
|
||||
int i, num;
|
||||
@@ -329,10 +314,7 @@ void debris_process_post(object * obj, float frame_time)
|
||||
return; // If arc_frequency <= 0, this piece has no arcs on it
|
||||
}
|
||||
|
||||
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
|
||||
|
||||
// start the next fireball up in the next 50 - 100 ms
|
||||
//db->next_fireball = timestamp_rand(60,80);
|
||||
if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball)) {
|
||||
|
||||
db->next_fireball = timestamp_rand(db->arc_frequency,db->arc_frequency*2 );
|
||||
db->arc_frequency += 100;
|
||||
@@ -353,7 +335,7 @@ void debris_process_post(object * obj, float frame_time)
|
||||
// Create the spark effects
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
if ( !timestamp_valid( db->arc_timestamp[i] ) ) {
|
||||
//db->arc_timestamp[i] = timestamp_rand(400,1000); // live up to a second
|
||||
|
||||
db->arc_timestamp[i] = timestamp(lifetime); // live up to a second
|
||||
|
||||
switch( n ) {
|
||||
@@ -405,11 +387,7 @@ void debris_process_post(object * obj, float frame_time)
|
||||
// 0.10 second effect
|
||||
snd_play_3d( &Snds[SND_DEBRIS_ARC_01], &snd_pos, &View_position, obj->radius );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
@@ -428,15 +406,12 @@ void debris_process_post(object * obj, float frame_time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_find_oldest()
|
||||
//
|
||||
// Locate the oldest hull debris chunk. Search through the Hull_debris_list, which is a list
|
||||
// of all the hull debris chunks.
|
||||
//
|
||||
/**
|
||||
* Locate the oldest hull debris chunk. Search through the ::Hull_debris_list, which is a list
|
||||
* of all the hull debris chunks.
|
||||
*/
|
||||
int debris_find_oldest()
|
||||
{
|
||||
int oldest_index;
|
||||
@@ -458,13 +433,18 @@ int debris_find_oldest()
|
||||
|
||||
#define DEBRIS_ROTVEL_SCALE 5.0f
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *min, vec3d *max );
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_create()
|
||||
//
|
||||
// Create debris from an object
|
||||
//
|
||||
// exp_force: Explosion force, used to assign velocity to pieces.
|
||||
// 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
|
||||
|
||||
/**
|
||||
* Create debris from an object
|
||||
*
|
||||
* @param source_obj Source object
|
||||
* @param model_num Model number
|
||||
* @param submodel_num Sub-model number
|
||||
* @param pos Position in vector space
|
||||
* @param exp_center Explosion center in vector space
|
||||
* @param hull_flag Hull flag settings
|
||||
* @param exp_force Explosion force, used to assign velocity to pieces. 1.0f assigns velocity like before. 2.0f assigns twice as much to non-inherited part of velocity
|
||||
*/
|
||||
object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force)
|
||||
{
|
||||
int i, n, objnum, parent_objnum;
|
||||
@@ -491,7 +471,6 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
dist /= 2.0f;
|
||||
}
|
||||
if ( dist > 200.0f ) {
|
||||
//mprintf(( "Not creating debris that is %.1f m away\n", dist ));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -581,7 +560,6 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
|
||||
for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
|
||||
db->arc_timestamp[i] = timestamp(-1);
|
||||
// vec3d arc_pts[MAX_DEBRIS_ARCS][2]; // The endpoints of each arc
|
||||
}
|
||||
|
||||
if ( db->is_hull ) {
|
||||
@@ -635,8 +613,6 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
obj->net_signature = multi_get_next_network_signature( MULTI_SIG_DEBRIS );
|
||||
}
|
||||
|
||||
// -- No long need shield: bset_shield_strength(obj, 100.0f); // Hey! Set to some meaningful value!
|
||||
|
||||
if (source_obj->type == OBJ_SHIP) {
|
||||
obj->hull_strength = Ships[source_obj->instance].ship_max_hull_strength/8.0f;
|
||||
} else
|
||||
@@ -709,14 +685,8 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_copy_scale(&radial_vel, &to_center, scale );
|
||||
}
|
||||
|
||||
// MK: This next line causes debris pieces to get between 50% and 100% of the parent ship's
|
||||
// velocity. What would be very cool is if the rotational velocity of the parent would become
|
||||
// translational velocity of the debris piece. This would be based on the location of the debris
|
||||
// piece in the parent object.
|
||||
|
||||
// DA: here we need to vel_from_rot = w x to_center, where w is world is unrotated to world coords and offset is the
|
||||
// displacement fromt the center of the parent object to the center of the debris piece
|
||||
|
||||
vec3d world_rotvel, vel_from_rotvel;
|
||||
vm_vec_unrotate ( &world_rotvel, &source_obj->phys_info.rotvel, &source_obj->orient );
|
||||
vm_vec_crossprod ( &vel_from_rotvel, &world_rotvel, &to_center );
|
||||
@@ -725,10 +695,7 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
|
||||
vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
|
||||
|
||||
// vm_vec_scale_add(&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel, frand()/2.0f + 0.5f);
|
||||
// nprintf(("Andsager","object vel from rotvel: %0.2f, %0.2f, %0.2f\n",vel_from_rotvel.x, vel_from_rotvel.y, vel_from_rotvel.z));
|
||||
|
||||
// make sure rotational velocity does not get too high
|
||||
// make sure rotational velocity does not get too high
|
||||
if (radius < 1.0) {
|
||||
radius = 1.0f;
|
||||
}
|
||||
@@ -756,29 +723,20 @@ object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d
|
||||
vm_vec_zero(&pi->max_vel); // make so he can't turn on his own VOLITION anymore.
|
||||
vm_vec_zero(&pi->max_rotvel); // make so he can't change speed on his own VOLITION anymore.
|
||||
|
||||
|
||||
// ensure vel is valid
|
||||
Assert( !vm_is_vec_nan(&obj->phys_info.vel) );
|
||||
|
||||
// if ( hull_flag ) {
|
||||
// vm_vec_zero(&pi->vel);
|
||||
// vm_vec_zero(&pi->rotvel);
|
||||
// }
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_hit()
|
||||
//
|
||||
// Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
|
||||
// can do something about it.
|
||||
//
|
||||
/**
|
||||
* Alas, poor debris_obj got whacked. Fortunately, we know who did it, where and how hard, so we
|
||||
* can do something about it.
|
||||
*/
|
||||
void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float damage)
|
||||
{
|
||||
debris *debris_p = &Debris[debris_obj->instance];
|
||||
|
||||
|
||||
// Do a little particle spark shower to show we hit
|
||||
{
|
||||
particle_emitter pe;
|
||||
@@ -827,13 +785,11 @@ void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float dama
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_check_collision()
|
||||
//
|
||||
// See if poor debris object *obj got whacked by evil *other_obj at point *hitpos.
|
||||
// NOTE: debris_hit_info pointer NULL for debris:weapon collision, otherwise debris:ship collision.
|
||||
// Return true if hit, else return false.
|
||||
//
|
||||
/**
|
||||
* See if poor debris object *obj got whacked by evil *other_obj at point *hitpos.
|
||||
* NOTE: debris_hit_info pointer NULL for debris:weapon collision, otherwise debris:ship collision.
|
||||
* @return true if hit, else return false.
|
||||
*/
|
||||
int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, collision_info_struct *debris_hit_info)
|
||||
{
|
||||
mc_info mc;
|
||||
@@ -972,7 +928,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
|
||||
mc.p0 = &p0;
|
||||
mc.p1 = &p1;
|
||||
// mc.pos = zero // in submodel RF
|
||||
|
||||
mc.orient = &vmd_identity_matrix;
|
||||
mc.submodel_num = *smv;
|
||||
@@ -1000,7 +955,6 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
// Don't look at this submodel again
|
||||
pmi->submodel[*smv].collision_checked = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Recover and do usual ship_ship collision, but without rotating submodels
|
||||
@@ -1089,11 +1043,9 @@ int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, co
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// debris_get_team()
|
||||
//
|
||||
// Return the team field for a debris object
|
||||
//
|
||||
/**
|
||||
* Return the team field for a debris object
|
||||
*/
|
||||
int debris_get_team(object *objp)
|
||||
{
|
||||
Assert( objp->type == OBJ_DEBRIS );
|
||||
@@ -1101,7 +1053,9 @@ int debris_get_team(object *objp)
|
||||
return Debris[objp->instance].team;
|
||||
}
|
||||
|
||||
// fills in debris physics properties when created, specifically mass and moment of inertia
|
||||
/**
|
||||
* Fills in debris physics properties when created, specifically mass and moment of inertia
|
||||
*/
|
||||
void calc_debris_physics_properties( physics_info *pi, vec3d *mins, vec3d *maxs )
|
||||
{
|
||||
float dx, dy, dz, mass;
|
||||
|
||||
@@ -52,7 +52,6 @@ typedef struct debris {
|
||||
#define DEBRIS_USED (1<<0)
|
||||
#define DEBRIS_EXPIRE (1<<1) // debris can expire (ie hull chunks from small ships)
|
||||
|
||||
|
||||
#define MAX_DEBRIS_PIECES 64
|
||||
|
||||
extern debris Debris[MAX_DEBRIS_PIECES];
|
||||
@@ -64,7 +63,6 @@ struct collision_info_struct;
|
||||
void debris_init();
|
||||
void debris_render( object * obj );
|
||||
void debris_delete( object * obj );
|
||||
void debris_process_pre( object * obj, float frame_time);
|
||||
void debris_process_post( object * obj, float frame_time);
|
||||
object *debris_create( object * source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force );
|
||||
int debris_check_collision( object * obj, object * other_obj, vec3d * hitpos, collision_info_struct *debris_hit_info=NULL );
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "io/key.h"
|
||||
#include "globalincs/alphacolors.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
|
||||
|
||||
#define MAX_COMMANDS 300
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
#include "dbugfile.h"
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
|
||||
int dbugfile_counters[MAX_COUNTERS];
|
||||
bool dbugfile_init_var = false;
|
||||
|
||||
char dbugfile_filename[512];
|
||||
|
||||
void dbugfile_output(char *buffer)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FILE *fp = fopen(dbugfile_filename, "a");
|
||||
|
||||
if(fp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(buffer, sizeof(char) * strlen(buffer), 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void dbugfile_init()
|
||||
{
|
||||
// Clear the counters
|
||||
memset(dbugfile_counters, 0, sizeof(int) * MAX_COUNTERS);
|
||||
|
||||
char big_buffer[1000];
|
||||
char temp_buff[512];
|
||||
|
||||
dbugfile_filename[0] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
char path[MAX_PATH];
|
||||
|
||||
GetCurrentDirectory(MAX_PATH, path);
|
||||
|
||||
int path_len = strlen(path);
|
||||
if(path[path_len - 1] != '\\')
|
||||
{
|
||||
path[path_len] = '\\';
|
||||
path[path_len + 1] = '\0';
|
||||
}
|
||||
|
||||
strcpy_s(dbugfile_filename, path);
|
||||
|
||||
#endif
|
||||
|
||||
strcat_s(dbugfile_filename, "DBUG-");
|
||||
strcpy_s(big_buffer, "DBUGFILE Active: ");
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
unsigned long len = 512;
|
||||
GetUserName(temp_buff, &len);
|
||||
|
||||
strcat_s(dbugfile_filename, temp_buff);
|
||||
strcat_s(big_buffer, temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, "-");
|
||||
strcat_s(big_buffer, " ");
|
||||
}
|
||||
#endif
|
||||
|
||||
_tzset();
|
||||
|
||||
// Display operating system-style date and time.
|
||||
_strdate( temp_buff);
|
||||
strcat_s(dbugfile_filename, "D(");
|
||||
strcat_s(dbugfile_filename,temp_buff);
|
||||
strcat_s(big_buffer,temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, ") T(");
|
||||
strcat_s(big_buffer, " ");
|
||||
|
||||
_strtime( temp_buff);
|
||||
strcat_s(dbugfile_filename,temp_buff);
|
||||
strcat_s(big_buffer,temp_buff);
|
||||
|
||||
strcat_s(dbugfile_filename, ").txt");
|
||||
strcat_s(big_buffer, "\n");
|
||||
|
||||
// Remove invalid slash chars
|
||||
int len = strlen(dbugfile_filename);
|
||||
while(len >= 2)
|
||||
{
|
||||
if(dbugfile_filename[len] == '/' || dbugfile_filename[len] == ':')
|
||||
{
|
||||
dbugfile_filename[len] = '-';
|
||||
}
|
||||
len--;
|
||||
}
|
||||
|
||||
// open file
|
||||
// Uncomment this to see where the file is going
|
||||
//MessageBox(NULL, dbugfile_filename, "das", MB_OK);
|
||||
FILE *fp = fopen(dbugfile_filename, "w");
|
||||
|
||||
if(fp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(big_buffer, sizeof(char) * strlen(big_buffer), 1, fp);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// detect OS type
|
||||
|
||||
OSVERSIONINFO version_info;
|
||||
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
if(GetVersionEx(&version_info) != false)
|
||||
{
|
||||
char *error = "Error in detecting OS version";
|
||||
char *version = error;
|
||||
|
||||
switch(version_info.dwMajorVersion)
|
||||
{
|
||||
case 4:
|
||||
{
|
||||
if(version_info.dwMinorVersion == 0)
|
||||
{
|
||||
version = "Windows 95";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 10)
|
||||
{
|
||||
version = "Windows 98";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 90)
|
||||
{
|
||||
version = "Windows Me";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if(version_info.dwMinorVersion == 0)
|
||||
{
|
||||
version = "Windows 2000";
|
||||
}
|
||||
else if(version_info.dwMinorVersion == 1)
|
||||
{
|
||||
version = "Windows XP";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *release_type = NULL;
|
||||
#ifdef _DEBUG
|
||||
release_type = "Debug";
|
||||
#else
|
||||
release_type = "Release";
|
||||
#endif
|
||||
sprintf(big_buffer, "OS: %s %s, ", version, release_type);
|
||||
}
|
||||
|
||||
fwrite(big_buffer, sizeof(char) * strlen(big_buffer), 1, fp);
|
||||
|
||||
char exe_name[MAX_PATH];
|
||||
|
||||
GetModuleFileName(NULL, exe_name, MAX_PATH);
|
||||
strcat_s(exe_name, "\n");
|
||||
fwrite(exe_name, sizeof(char) * strlen(exe_name), 1, fp);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
fclose(fp);
|
||||
|
||||
dbugfile_init_var = true;
|
||||
}
|
||||
|
||||
void dbugfile_deinit()
|
||||
{
|
||||
dbugfile_output("Normal end");
|
||||
dbugfile_init_var = false;
|
||||
}
|
||||
|
||||
void dbugfile_sprintf(int line, char *file, const char *format, ...)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
int i = sprintf(buffer, "[%s,%4d] ", ptr, line);
|
||||
|
||||
va_list ap;
|
||||
char *p, *sval;
|
||||
long ival;
|
||||
double dval;
|
||||
|
||||
// Add each extra parameter to string
|
||||
va_start(ap, format);
|
||||
|
||||
for(p = (char *) format; *p; p++)
|
||||
{
|
||||
if(*p != '%')
|
||||
{
|
||||
*(buffer + i) = *p;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
p++;
|
||||
if (!*p)
|
||||
break; // stupid edge case
|
||||
|
||||
switch(*p)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
ival = va_arg(ap, int);
|
||||
i += sprintf(buffer+i,"%d", ival);
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
ival = va_arg(ap, char);
|
||||
buffer[i] = (char) ival;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
{
|
||||
ival = va_arg(ap, int);
|
||||
i += sprintf(buffer+i,"%x", ival);
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
dval = va_arg(ap, double);
|
||||
i += sprintf(buffer+i,"%f", dval);
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
{
|
||||
for(sval = va_arg(ap, char *); *sval; sval++)
|
||||
{
|
||||
*(buffer + i++) = *sval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
{
|
||||
buffer[i] = '%'; // escaped %
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
i += sprintf(buffer+i,"N/A: %%%c", *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
i += sprintf(buffer + i, "\n");
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_matrix_4x4(int line, char *file, float *matrix, char *text)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(text == NULL)
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
|
||||
sprintf(buffer,"[%s,%4d] Matrix %s:\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n",
|
||||
ptr,line, text,
|
||||
matrix[0],
|
||||
matrix[1],
|
||||
matrix[2],
|
||||
matrix[3],
|
||||
matrix[4],
|
||||
matrix[5],
|
||||
matrix[6],
|
||||
matrix[7],
|
||||
matrix[8],
|
||||
matrix[9],
|
||||
matrix[10],
|
||||
matrix[11],
|
||||
matrix[12],
|
||||
matrix[13],
|
||||
matrix[14],
|
||||
matrix[15]);
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_matrix_3x3(int line, char *file, float *matrix, char *text)
|
||||
{
|
||||
if(dbugfile_init_var == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find last slash (for PC) to crop file path
|
||||
char *ptr = strrchr(file, '\\');
|
||||
|
||||
if(ptr == NULL)
|
||||
{
|
||||
ptr = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(text == NULL)
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
char buffer[1000];
|
||||
|
||||
sprintf(buffer,"[%s,%4d] Matrix %s:\n"
|
||||
"%f %f %f\n"
|
||||
"%f %f %f\n"
|
||||
"%f %f %f\n",
|
||||
ptr,line, text,
|
||||
matrix[0],
|
||||
matrix[1],
|
||||
matrix[2],
|
||||
matrix[3],
|
||||
matrix[4],
|
||||
matrix[5],
|
||||
matrix[6],
|
||||
matrix[7],
|
||||
matrix[8]);
|
||||
|
||||
dbugfile_output(buffer);
|
||||
}
|
||||
|
||||
void dbugfile_print_counter(int line, char *file, int counter_num, char *string)
|
||||
{
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, string);
|
||||
strcat_s(buffer, " %d");
|
||||
|
||||
dbugfile_sprintf(line, file, buffer, dbugfile_counters[counter_num]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
|
||||
#ifndef _DBUGFILE_HEADER_
|
||||
#define _DBUGFILE_HEADER_
|
||||
|
||||
#define MAX_COUNTERS 10
|
||||
|
||||
void dbugfile_init();
|
||||
void dbugfile_deinit();
|
||||
void dbugfile_sprintf(int line, char *file, const char *format, ...);
|
||||
void dbugfile_print_matrix_3x3(int line, char *file, float *matrix, char *text);
|
||||
void dbugfile_print_matrix_4x4(int line, char *file, float *matrix, char *text);
|
||||
void dbugfile_print_counter(int line, char *file, int counter_num, char *string);
|
||||
|
||||
#ifdef DBUGFILE_ACTIVE
|
||||
|
||||
#define DBUGFILE_INIT() dbugfile_init();
|
||||
#define DBUGFILE_DEINIT() dbugfile_deinit();
|
||||
|
||||
#define DBUGFILE_OUTPUT_0(t) dbugfile_sprintf(__LINE__, __FILE__, t);
|
||||
#define DBUGFILE_OUTPUT_1(t,a) dbugfile_sprintf(__LINE__, __FILE__, t,a);
|
||||
#define DBUGFILE_OUTPUT_2(t,a,b) dbugfile_sprintf(__LINE__, __FILE__, t,a,b);
|
||||
#define DBUGFILE_OUTPUT_3(t,a,b,c) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c);
|
||||
#define DBUGFILE_OUTPUT_4(t,a,b,c,d) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d);
|
||||
#define DBUGFILE_OUTPUT_5(t,a,b,c,d,e) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e);
|
||||
#define DBUGFILE_OUTPUT_6(t,a,b,c,d,e,f) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f);
|
||||
#define DBUGFILE_OUTPUT_7(t,a,b,c,d,e,f,g) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g);
|
||||
#define DBUGFILE_OUTPUT_8(t,a,b,c,d,e,f,g,h) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g,h);
|
||||
#define DBUGFILE_OUTPUT_9(t,a,b,c,d,e,f,g,h,i) dbugfile_sprintf(__LINE__, __FILE__, t,a,b,c,d,e,f,g,h,i);
|
||||
|
||||
#define DBUGFILE_OUTPUT_MATRIX_3X3(m,t) dbugfile_print_matrix_3x3(__LINE__, __FILE__, m,t);
|
||||
#define DBUGFILE_OUTPUT_MATRIX_4X4(m,t) dbugfile_print_matrix_4x4(__LINE__, __FILE__, m,t);
|
||||
|
||||
extern int dbugfile_counters[MAX_COUNTERS];
|
||||
#define DBUGFILE_INC_COUNTER(n) if(n < MAX_COUNTERS) dbugfile_counters[n]++;
|
||||
#define DBUGFILE_DEC_COUNTER(n) if(n < MAX_COUNTERS) dbugfile_counters[n]--;
|
||||
|
||||
#define DBUGFILE_OUTPUT_COUNTER(n,s) dbugfile_print_counter(__LINE__, __FILE__, n, s);
|
||||
|
||||
#else
|
||||
|
||||
#define DBUGFILE_INIT() ;
|
||||
#define DBUGFILE_DEINIT() ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_0(t) ;
|
||||
#define DBUGFILE_OUTPUT_1(t,a) ;
|
||||
#define DBUGFILE_OUTPUT_2(t,a,b) ;
|
||||
#define DBUGFILE_OUTPUT_3(t,a,b,c) ;
|
||||
#define DBUGFILE_OUTPUT_4(t,a,b,c,d) ;
|
||||
#define DBUGFILE_OUTPUT_5(t,a,b,c,d,e) ;
|
||||
#define DBUGFILE_OUTPUT_6(t,a,b,c,d,e,f) ;
|
||||
#define DBUGFILE_OUTPUT_7(t,a,b,c,d,e,f,g) ;
|
||||
#define DBUGFILE_OUTPUT_8(t,a,b,c,d,e,f,g,h) ;
|
||||
#define DBUGFILE_OUTPUT_9(t,a,b,c,d,e,f,g,h,i) ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_MATRIX_3X3(m,t) ;
|
||||
#define DBUGFILE_OUTPUT_MATRIX_4X4(m,t) ;
|
||||
|
||||
#define DBUGFILE_INC_COUNTER(n) ;
|
||||
#define DBUGFILE_DEC_COUNTER(n) ;
|
||||
|
||||
#define DBUGFILE_OUTPUT_COUNTER(n,s) ;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+43
-78
@@ -47,7 +47,6 @@ fireball_info Fireball_info[MAX_FIREBALL_TYPES];
|
||||
int fireball_used[MAX_FIREBALL_TYPES];
|
||||
|
||||
int Num_fireballs = 0;
|
||||
|
||||
int Num_fireball_types = 0;
|
||||
|
||||
int fireballs_inited = 0;
|
||||
@@ -57,7 +56,9 @@ int Warp_ball_bitmap = -1;
|
||||
|
||||
#define FB_INDEX(fb) (fb-Fireballs)
|
||||
|
||||
// play warp in sound for warp effect
|
||||
/**
|
||||
* Play warp in sound for warp effect
|
||||
*/
|
||||
void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
|
||||
{
|
||||
int sound_index;
|
||||
@@ -87,7 +88,9 @@ void fireball_play_warphole_open_sound(int ship_class, fireball *fb)
|
||||
snd_play_3d(&Snds[sound_index], &fireball_objp->pos, &Eye_position, fireball_objp->radius, NULL, 0, 1.0f, SND_PRIORITY_DOUBLE_INSTANCE, NULL, range_multiplier); // play warp sound effect
|
||||
}
|
||||
|
||||
// play warp out sound for warp effect
|
||||
/**
|
||||
* Play warp out sound for warp effect
|
||||
*/
|
||||
void fireball_play_warphole_close_sound(fireball *fb)
|
||||
{
|
||||
int sound_index;
|
||||
@@ -103,14 +106,15 @@ void fireball_play_warphole_close_sound(fireball *fb)
|
||||
} else if ( fb->flags & FBF_WARP_CAPITAL_SIZE ) {
|
||||
sound_index = SND_CAPITAL_WARP_OUT;
|
||||
} else {
|
||||
// AL 27-3-98: Decided that warphole closing is only required for capital ship sized warp effects.
|
||||
return;
|
||||
}
|
||||
|
||||
snd_play_3d(&Snds[sound_index], &fireball_objp->pos, &Eye_position, fireball_objp->radius); // play warp sound effect
|
||||
}
|
||||
|
||||
// set default colors for each explosion type (original values from object.cpp)
|
||||
/**
|
||||
* Set default colors for each explosion type (original values from object.cpp)
|
||||
*/
|
||||
static void fireball_set_default_color(int idx)
|
||||
{
|
||||
Assert( (idx >= 0) && (idx < MAX_FIREBALL_TYPES) );
|
||||
@@ -147,7 +151,11 @@ static void fireball_set_default_color(int idx)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
|
||||
/**
|
||||
* Parse fireball tbl
|
||||
*
|
||||
* NOTE: we can't be too trusting here so a tbm will only modify the LOD count, not add an entry
|
||||
*/
|
||||
void parse_fireball_tbl(char *filename)
|
||||
{
|
||||
int rval;
|
||||
@@ -326,15 +334,6 @@ void fireball_load_data()
|
||||
if ( Warp_ball_bitmap == -1 ) {
|
||||
Warp_ball_bitmap = bm_load( NOX("warpball01") );
|
||||
}
|
||||
|
||||
// polymodel Warp_pm;
|
||||
|
||||
}
|
||||
|
||||
void fireball_preload()
|
||||
{
|
||||
// Do nothing. Called before level init, this used to page in warp effect.
|
||||
// Not needed with new BmpMan system.
|
||||
}
|
||||
|
||||
// This will get called at the start of each level.
|
||||
@@ -375,8 +374,6 @@ MONITOR( NumFireballsRend )
|
||||
|
||||
void fireball_render(object * obj)
|
||||
{
|
||||
// if(!Cmdline_nohtl)gr_set_lighting(false,false);
|
||||
|
||||
int num;
|
||||
vertex p;
|
||||
fireball *fb;
|
||||
@@ -391,10 +388,6 @@ void fireball_render(object * obj)
|
||||
if ( Fireballs[num].current_bitmap < 0 )
|
||||
return;
|
||||
|
||||
// gr_set_color( 0, 100, 0 );
|
||||
// g3_draw_sphere_ez( &obj->pos, obj->radius );
|
||||
// return;
|
||||
|
||||
// turn off fogging
|
||||
if(The_mission.flags & MISSION_FLAG_FULLNEB){
|
||||
gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
|
||||
@@ -440,17 +433,11 @@ void fireball_render(object * obj)
|
||||
|
||||
if ( t < WARPHOLE_GROW_TIME ) {
|
||||
rad = (float)pow(t/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
//rad = t*obj->radius/WARPHOLE_GROW_TIME;
|
||||
//mprintf(( "T=%.2f, Rad = %.2f\n", t, rad ));
|
||||
} else if ( t < fb->total_time - WARPHOLE_GROW_TIME ) {
|
||||
rad = obj->radius;
|
||||
} else {
|
||||
rad = (float)pow((fb->total_time - t)/WARPHOLE_GROW_TIME,0.4f)*obj->radius;
|
||||
//rad = (fb->total_time - t )*obj->radius/WARPHOLE_GROW_TIME;
|
||||
}
|
||||
//rad = obj->radius;
|
||||
// obj->alt_rad = rad;
|
||||
|
||||
|
||||
warpin_render(obj, &obj->orient, &obj->pos, Fireballs[num].current_bitmap, rad, percent_life, obj->radius, (Fireballs[num].flags & FBF_WARP_3D) );
|
||||
}
|
||||
@@ -462,12 +449,10 @@ void fireball_render(object * obj)
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_delete()
|
||||
//
|
||||
// Delete a fireball. Called by object_delete() code... do not call
|
||||
// directly.
|
||||
//
|
||||
/**
|
||||
* Delete a fireball.
|
||||
* Called by object_delete() code... do not call directly.
|
||||
*/
|
||||
void fireball_delete( object * obj )
|
||||
{
|
||||
int num;
|
||||
@@ -483,11 +468,9 @@ void fireball_delete( object * obj )
|
||||
Assert( Num_fireballs >= 0 );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_delete_all()
|
||||
//
|
||||
// Delete all active fireballs, by calling obj_delete directly.
|
||||
//
|
||||
/**
|
||||
* Delete all active fireballs, by calling obj_delete directly.
|
||||
*/
|
||||
void fireball_delete_all()
|
||||
{
|
||||
fireball *fb;
|
||||
@@ -577,12 +560,12 @@ int fireball_is_perishable(object * obj)
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_free_one()
|
||||
//
|
||||
// There are too many fireballs, so delete the oldest small one
|
||||
// to free up a slot. Returns the fireball slot freed.
|
||||
//
|
||||
/**
|
||||
* There are too many fireballs, so delete the oldest small one
|
||||
* to free up a slot.
|
||||
*
|
||||
* @return The fireball slot freed.
|
||||
*/
|
||||
int fireball_free_one()
|
||||
{
|
||||
fireball *fb;
|
||||
@@ -613,12 +596,6 @@ int fireball_free_one()
|
||||
return oldest_slotnum;
|
||||
}
|
||||
|
||||
// broke fireball_move into fireball_process_pre and fireball_process_post as was done
|
||||
// with all *_move functions on 8/13 by Mike K. and Mark A.
|
||||
void fireball_process_pre( object *objp, float frame_time)
|
||||
{
|
||||
}
|
||||
|
||||
int fireball_is_warp(object * obj)
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -684,7 +661,9 @@ void fireball_process_post(object * obj, float frame_time)
|
||||
fireball_set_framenum(num);
|
||||
}
|
||||
|
||||
// Returns life left of a fireball in seconds
|
||||
/**
|
||||
* Returns life left of a fireball in seconds
|
||||
*/
|
||||
float fireball_lifeleft( object *obj )
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -699,7 +678,9 @@ float fireball_lifeleft( object *obj )
|
||||
return fb->total_time - fb->time_elapsed;
|
||||
}
|
||||
|
||||
// Returns life left of a fireball in percent
|
||||
/**
|
||||
* Returns life left of a fireball in percent
|
||||
*/
|
||||
float fireball_lifeleft_percent( object *obj )
|
||||
{
|
||||
int num, objnum;
|
||||
@@ -711,14 +692,14 @@ float fireball_lifeleft_percent( object *obj )
|
||||
|
||||
fb = &Fireballs[num];
|
||||
|
||||
// Assert((fb->total_time - fb->time_elapsed) / fb->total_time >=0);
|
||||
|
||||
float p = (fb->total_time - fb->time_elapsed) / fb->total_time;
|
||||
if (p < 0)p=0.0f;
|
||||
return p;
|
||||
}
|
||||
|
||||
// determine LOD to use
|
||||
/**
|
||||
* Determine LOD to use
|
||||
*/
|
||||
int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
|
||||
{
|
||||
vertex v;
|
||||
@@ -799,7 +780,9 @@ int fireball_get_lod(vec3d *pos, fireball_info *fd, float size)
|
||||
return MIN(ret_lod, fd->lod_count - 1);
|
||||
}
|
||||
|
||||
// Create a fireball, return object index.
|
||||
/**
|
||||
* Create a fireball, return object index.
|
||||
*/
|
||||
int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, int warp_open_sound, int warp_close_sound)
|
||||
{
|
||||
int n, objnum, fb_lod;
|
||||
@@ -824,22 +807,11 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
}
|
||||
|
||||
if ( (Num_fireballs >= MAX_FIREBALLS) || (Num_objects >= MAX_OBJECTS) ) {
|
||||
// who cares if we don't create a spark.
|
||||
// JAS - Should this code be in? Is it better to remove an old spark
|
||||
// and start a new one, or just not start the new one?
|
||||
//if ( fd->type == FIREBALL_TYPE_SMALL ) {
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
//mprintf(( "Out of fireball slots, trying to free one up!\n" ));
|
||||
// out of slots, so free one up.
|
||||
n = fireball_free_one();
|
||||
if ( n < 0 ) {
|
||||
// If there's still no free slots, then exit
|
||||
//mprintf(( "ERROR: Couldn't free one up!!\n" ));
|
||||
if ( n < 0 ) {
|
||||
return -1;
|
||||
} else {
|
||||
//mprintf(( "Freed one up just fine!!\n" ));
|
||||
}
|
||||
} else {
|
||||
for ( n = 0; n < MAX_FIREBALLS; n++ ) {
|
||||
@@ -863,11 +835,6 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
|
||||
// if this is a warpout fireball, never go higher than LOD 1
|
||||
if(fireball_type == FIREBALL_WARP){
|
||||
/*
|
||||
if(fb_lod > 1){
|
||||
fb_lod = 1;
|
||||
}
|
||||
*/
|
||||
fb_lod = MAX_WARP_LOD;
|
||||
}
|
||||
fl = &fd->lod[fb_lod];
|
||||
@@ -962,11 +929,9 @@ int fireball_create( vec3d * pos, int fireball_type, int render_type, int parent
|
||||
return objnum;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// fireball_close()
|
||||
//
|
||||
// Called at game shutdown to clean up the fireball system
|
||||
//
|
||||
/**
|
||||
* Called at game shutdown to clean up the fireball system
|
||||
*/
|
||||
void fireball_close()
|
||||
{
|
||||
if ( !fireballs_inited )
|
||||
|
||||
@@ -77,7 +77,6 @@ typedef struct fireball {
|
||||
void fireball_init();
|
||||
void fireball_render(object * obj);
|
||||
void fireball_delete( object * obj );
|
||||
void fireball_process_pre(object * obj, float frame_time);
|
||||
void fireball_process_post(object * obj, float frame_time);
|
||||
|
||||
// reversed is for warp_in/out effects
|
||||
@@ -86,7 +85,6 @@ void fireball_process_post(object * obj, float frame_time);
|
||||
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reversed=0, vec3d *velocity=NULL, float warp_lifetime=0.0f, int ship_class=-1, matrix *orient=NULL, int low_res=0, int extra_flags=0, int warp_open_sound=-1, int warp_close_sound=-1);
|
||||
void fireball_render_plane(int plane);
|
||||
void fireball_close();
|
||||
void fireball_preload(); // page in warpout effect data
|
||||
|
||||
// Returns 1 if you can remove this fireball
|
||||
int fireball_is_perishable(object * obj);
|
||||
|
||||
+406
-406
@@ -1,406 +1,406 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
|
||||
AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AltShipClassDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AltShipClassDlg)
|
||||
m_selected_variable = -1;
|
||||
m_selected_class = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
multi_edit = false;
|
||||
player_ships_only = true;
|
||||
num_string_variables = 0;
|
||||
|
||||
memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
|
||||
memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
|
||||
DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
|
||||
DDX_Control(pDX, IDC_SET_FROM_SHIP_CLASS, m_set_from_ship_class);
|
||||
DDX_Control(pDX, IDC_SET_FROM_VARIABLES, m_set_from_variables);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_VARIABLES, m_selected_variable);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
|
||||
ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
|
||||
ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i, count;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// have we got multiple selected ships?
|
||||
num_selected_ships = 0;
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Fill the variable combo box
|
||||
m_set_from_variables.ResetContent();
|
||||
m_set_from_variables.AddString("Set From Ship Class");
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
|
||||
m_set_from_variables.AddString(buff);
|
||||
string_variable_indices[num_string_variables++] = i;
|
||||
}
|
||||
}
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
if (!num_string_variables) {
|
||||
m_set_from_variables.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// Fill the ship classes combo box
|
||||
m_set_from_ship_class.ResetContent();
|
||||
// Add the default entry if we need one followed by all the ship classes
|
||||
if (num_string_variables) {
|
||||
m_set_from_ship_class.AddString("Set From Variable");
|
||||
}
|
||||
count = 0;
|
||||
for (i=0; i<Num_ship_classes; i++)
|
||||
{
|
||||
if (player_ships_only && !(Ship_info[i].flags & SIF_PLAYER_SHIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ship_class_indices[count++] = i;
|
||||
m_set_from_ship_class.AddString(Ship_info[i].name);
|
||||
}
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild()
|
||||
{
|
||||
int i, j;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
j = m_alt_class_list.GetCount();
|
||||
for ( i=0; i < j ; i++) {
|
||||
m_alt_class_list.DeleteString(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)alt_class_pool.size() ; i++) {
|
||||
// Default classes should be at the end of the list
|
||||
if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
|
||||
// Int3();
|
||||
// TO DO : we should fix this.
|
||||
}
|
||||
|
||||
if (alt_class_pool[i].variable_index != -1) {
|
||||
Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
|
||||
Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
|
||||
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
|
||||
|
||||
// add it to the list
|
||||
m_alt_class_list.AddString(buff);
|
||||
}
|
||||
else {
|
||||
if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
|
||||
m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
|
||||
}
|
||||
else {
|
||||
m_alt_class_list.AddString("Invalid Ship Class");
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++) {
|
||||
Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassAdd()
|
||||
{
|
||||
alt_class new_list_item;
|
||||
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassInsert()
|
||||
{
|
||||
int index;
|
||||
alt_class new_list_item;
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// If nothing is selected just add it
|
||||
if ( index == -1) {
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
}
|
||||
// Stick it in front of the current selection
|
||||
else {
|
||||
alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
|
||||
}
|
||||
|
||||
alt_class_list_rebuild();
|
||||
|
||||
// If we inserted the user will probably want to edit the selection
|
||||
if (index > -1) {
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the currently selected list entry
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Add a string variable to the list
|
||||
if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
|
||||
index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
|
||||
|
||||
Assert (index >= 0);
|
||||
list_item.variable_index = index;
|
||||
list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
|
||||
}
|
||||
// Add a ship class to the list
|
||||
else {
|
||||
index = m_set_from_ship_class.GetCurSel();
|
||||
|
||||
// Correct the index if the first entry isn't actually a ship class
|
||||
if (num_string_variables) {
|
||||
Assert (index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
list_item.variable_index = -1;
|
||||
list_item.ship_class = ship_class_indices[index];
|
||||
}
|
||||
|
||||
// check the default tickbox
|
||||
list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassDelete()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert (index < (int) alt_class_pool.size());
|
||||
alt_class_pool.erase(alt_class_pool.begin()+index);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveUp()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the top
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index-1]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index-1);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveDown()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
int inext = index + 1;
|
||||
|
||||
// Nothing selected or already at the bottom
|
||||
if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[inext]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromShipClass()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
|
||||
m_set_from_variables.SetCurSel(1);
|
||||
}
|
||||
else {
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromVariables()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_variables.GetCurSel() == 0) {
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
m_set_from_ship_class.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelchangeAltClassList()
|
||||
{
|
||||
int i;
|
||||
int variable_selection = 0;
|
||||
int ship_selection = 0;
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Selected nothing
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a variable selected
|
||||
if (alt_class_pool[index].variable_index != -1) {
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
|
||||
variable_selection = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ship selected
|
||||
else {
|
||||
for (i=0; i < MAX_SHIP_CLASSES; i++) {
|
||||
if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
|
||||
ship_selection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have string variables in the mission the first entry on the list won't be a ship
|
||||
if (num_string_variables) {
|
||||
ship_selection++;
|
||||
}
|
||||
}
|
||||
|
||||
m_set_from_variables.SetCurSel(variable_selection);
|
||||
m_set_from_ship_class.SetCurSel(ship_selection);
|
||||
m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnDefaultToClass()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
// AltShipClassDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "AltShipClassDlg.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "ship/ship.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
|
||||
AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AltShipClassDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AltShipClassDlg)
|
||||
m_selected_variable = -1;
|
||||
m_selected_class = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
multi_edit = false;
|
||||
player_ships_only = true;
|
||||
num_string_variables = 0;
|
||||
|
||||
memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
|
||||
memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AltShipClassDlg)
|
||||
DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
|
||||
DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
|
||||
DDX_Control(pDX, IDC_SET_FROM_SHIP_CLASS, m_set_from_ship_class);
|
||||
DDX_Control(pDX, IDC_SET_FROM_VARIABLES, m_set_from_variables);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_VARIABLES, m_selected_variable);
|
||||
DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(AltShipClassDlg)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
|
||||
ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
|
||||
ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
|
||||
ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
|
||||
ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg message handlers
|
||||
|
||||
|
||||
BOOL AltShipClassDlg::OnInitDialog()
|
||||
{
|
||||
int i, count;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// have we got multiple selected ships?
|
||||
num_selected_ships = 0;
|
||||
object *objp;
|
||||
|
||||
objp = GET_FIRST(&obj_used_list);
|
||||
while (objp != END_OF_LIST(&obj_used_list)) {
|
||||
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
|
||||
if (objp->flags & OF_MARKED) {
|
||||
m_selected_ships[num_selected_ships++] = objp->instance;
|
||||
}
|
||||
}
|
||||
objp = GET_NEXT(objp);
|
||||
}
|
||||
|
||||
Assert (num_selected_ships > 0);
|
||||
Assert (Objects[cur_object_index].flags & OF_MARKED);
|
||||
|
||||
if (num_selected_ships > 1)
|
||||
{
|
||||
multi_edit = true;
|
||||
}
|
||||
|
||||
// Fill the variable combo box
|
||||
m_set_from_variables.ResetContent();
|
||||
m_set_from_variables.AddString("Set From Ship Class");
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (Sexp_variables[i].type & SEXP_VARIABLE_STRING)
|
||||
{
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
|
||||
m_set_from_variables.AddString(buff);
|
||||
string_variable_indices[num_string_variables++] = i;
|
||||
}
|
||||
}
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
if (!num_string_variables) {
|
||||
m_set_from_variables.EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// Fill the ship classes combo box
|
||||
m_set_from_ship_class.ResetContent();
|
||||
// Add the default entry if we need one followed by all the ship classes
|
||||
if (num_string_variables) {
|
||||
m_set_from_ship_class.AddString("Set From Variable");
|
||||
}
|
||||
count = 0;
|
||||
for (i=0; i<Num_ship_classes; i++)
|
||||
{
|
||||
if (player_ships_only && !(Ship_info[i].flags & SIF_PLAYER_SHIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ship_class_indices[count++] = i;
|
||||
m_set_from_ship_class.AddString(Ship_info[i].name);
|
||||
}
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
|
||||
|
||||
// Set up the actual list of alt classes
|
||||
alt_class_pool.clear();
|
||||
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
|
||||
alt_class_list_rebuild();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild()
|
||||
{
|
||||
int i, j;
|
||||
char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
|
||||
|
||||
j = m_alt_class_list.GetCount();
|
||||
for ( i=0; i < j ; i++) {
|
||||
m_alt_class_list.DeleteString(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)alt_class_pool.size() ; i++) {
|
||||
// Default classes should be at the end of the list
|
||||
if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
|
||||
// Int3();
|
||||
// TO DO : we should fix this.
|
||||
}
|
||||
|
||||
if (alt_class_pool[i].variable_index != -1) {
|
||||
Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
|
||||
Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
|
||||
|
||||
sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
|
||||
|
||||
// add it to the list
|
||||
m_alt_class_list.AddString(buff);
|
||||
}
|
||||
else {
|
||||
if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
|
||||
m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
|
||||
}
|
||||
else {
|
||||
m_alt_class_list.AddString("Invalid Ship Class");
|
||||
Int3();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
for (int i=0; i < num_selected_ships; i++) {
|
||||
Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassAdd()
|
||||
{
|
||||
alt_class new_list_item;
|
||||
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassInsert()
|
||||
{
|
||||
int index;
|
||||
alt_class new_list_item;
|
||||
alt_class_update_entry(new_list_item);
|
||||
|
||||
index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// If nothing is selected just add it
|
||||
if ( index == -1) {
|
||||
alt_class_pool.push_back(new_list_item);
|
||||
}
|
||||
// Stick it in front of the current selection
|
||||
else {
|
||||
alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
|
||||
}
|
||||
|
||||
alt_class_list_rebuild();
|
||||
|
||||
// If we inserted the user will probably want to edit the selection
|
||||
if (index > -1) {
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the currently selected list entry
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
|
||||
{
|
||||
int index;
|
||||
|
||||
// Add a string variable to the list
|
||||
if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
|
||||
index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
|
||||
|
||||
Assert (index >= 0);
|
||||
list_item.variable_index = index;
|
||||
list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
|
||||
}
|
||||
// Add a ship class to the list
|
||||
else {
|
||||
index = m_set_from_ship_class.GetCurSel();
|
||||
|
||||
// Correct the index if the first entry isn't actually a ship class
|
||||
if (num_string_variables) {
|
||||
Assert (index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
list_item.variable_index = -1;
|
||||
list_item.ship_class = ship_class_indices[index];
|
||||
}
|
||||
|
||||
// check the default tickbox
|
||||
list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnAltClassDelete()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Assert (index < (int) alt_class_pool.size());
|
||||
alt_class_pool.erase(alt_class_pool.begin()+index);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveUp()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected or already at the top
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[index-1]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index-1);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnMoveDown()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
int inext = index + 1;
|
||||
|
||||
// Nothing selected or already at the bottom
|
||||
if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap(alt_class_pool[index], alt_class_pool[inext]);
|
||||
alt_class_list_rebuild();
|
||||
m_alt_class_list.SetCurSel(index);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromShipClass()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
|
||||
m_set_from_variables.SetCurSel(1);
|
||||
}
|
||||
else {
|
||||
m_set_from_variables.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelendokSetFromVariables()
|
||||
{
|
||||
int current_selection;
|
||||
|
||||
if (m_set_from_variables.GetCurSel() == 0) {
|
||||
m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
m_set_from_ship_class.SetCurSel(0);
|
||||
}
|
||||
|
||||
// if a list entry is selected we should update it
|
||||
current_selection = m_alt_class_list.GetCurSel();
|
||||
if (current_selection >= 0) {
|
||||
alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
|
||||
alt_class_list_rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnSelchangeAltClassList()
|
||||
{
|
||||
int i;
|
||||
int variable_selection = 0;
|
||||
int ship_selection = 0;
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Selected nothing
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a variable selected
|
||||
if (alt_class_pool[index].variable_index != -1) {
|
||||
for (i=0; i < MAX_SEXP_VARIABLES; i++)
|
||||
{
|
||||
if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
|
||||
variable_selection = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ship selected
|
||||
else {
|
||||
for (i=0; i < MAX_SHIP_CLASSES; i++) {
|
||||
if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
|
||||
ship_selection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have string variables in the mission the first entry on the list won't be a ship
|
||||
if (num_string_variables) {
|
||||
ship_selection++;
|
||||
}
|
||||
}
|
||||
|
||||
m_set_from_variables.SetCurSel(variable_selection);
|
||||
m_set_from_ship_class.SetCurSel(ship_selection);
|
||||
m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
|
||||
}
|
||||
|
||||
void AltShipClassDlg::OnDefaultToClass()
|
||||
{
|
||||
int index = m_alt_class_list.GetCurSel();
|
||||
|
||||
// Nothing selected
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
#define AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
class AltShipClassDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AltShipClassDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AltShipClassDlg)
|
||||
enum { IDD = IDD_ALT_SHIP_CLASS };
|
||||
CButton m_default_to_class;
|
||||
CListBox m_alt_class_list;
|
||||
CComboBox m_set_from_ship_class;
|
||||
CComboBox m_set_from_variables;
|
||||
int m_selected_variable;
|
||||
int m_selected_class;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AltShipClassDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AltShipClassDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAltClassAdd();
|
||||
afx_msg void OnAltClassInsert();
|
||||
afx_msg void OnAltClassDelete();
|
||||
afx_msg void OnMoveUp();
|
||||
afx_msg void OnMoveDown();
|
||||
afx_msg void OnSelendokSetFromShipClass();
|
||||
afx_msg void OnSelendokSetFromVariables();
|
||||
afx_msg void OnSelchangeAltClassList();
|
||||
afx_msg void OnDefaultToClass();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
|
||||
bool player_ships_only; // Whether we only add player ships to the alt classes or if we can add any ship
|
||||
|
||||
SCP_vector<alt_class> alt_class_pool;
|
||||
int num_string_variables; // Number of string variables in the mission
|
||||
int string_variable_indices[MAX_SEXP_VARIABLES]; // maps string variables to their index in Sexp_variables
|
||||
int ship_class_indices[MAX_SHIP_CLASSES]; // maps ships in the ships combobox to their index in Ship_info
|
||||
|
||||
|
||||
// variables to handle selection of multiple ships
|
||||
bool multi_edit;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild();
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
/*
|
||||
* Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
|
||||
* You may not sell or otherwise commercially exploit the source or things you
|
||||
* create based on the source.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
#define AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AltShipClassDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AltShipClassDlg dialog
|
||||
|
||||
class AltShipClassDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AltShipClassDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AltShipClassDlg)
|
||||
enum { IDD = IDD_ALT_SHIP_CLASS };
|
||||
CButton m_default_to_class;
|
||||
CListBox m_alt_class_list;
|
||||
CComboBox m_set_from_ship_class;
|
||||
CComboBox m_set_from_variables;
|
||||
int m_selected_variable;
|
||||
int m_selected_class;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AltShipClassDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AltShipClassDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnCancel();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnAltClassAdd();
|
||||
afx_msg void OnAltClassInsert();
|
||||
afx_msg void OnAltClassDelete();
|
||||
afx_msg void OnMoveUp();
|
||||
afx_msg void OnMoveDown();
|
||||
afx_msg void OnSelendokSetFromShipClass();
|
||||
afx_msg void OnSelendokSetFromVariables();
|
||||
afx_msg void OnSelchangeAltClassList();
|
||||
afx_msg void OnDefaultToClass();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
|
||||
bool player_ships_only; // Whether we only add player ships to the alt classes or if we can add any ship
|
||||
|
||||
SCP_vector<alt_class> alt_class_pool;
|
||||
int num_string_variables; // Number of string variables in the mission
|
||||
int string_variable_indices[MAX_SEXP_VARIABLES]; // maps string variables to their index in Sexp_variables
|
||||
int ship_class_indices[MAX_SHIP_CLASSES]; // maps ships in the ships combobox to their index in Ship_info
|
||||
|
||||
|
||||
// variables to handle selection of multiple ships
|
||||
bool multi_edit;
|
||||
int m_selected_ships[MAX_SHIPS];
|
||||
int num_selected_ships;
|
||||
|
||||
void AltShipClassDlg::alt_class_list_rebuild();
|
||||
void AltShipClassDlg::alt_class_update_entry(alt_class &list_item);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AltShipClassDlg_H__2FE2C917_C7DA_4C05_A11F_DCC46BFB26BB__INCLUDED_)
|
||||
+115
-115
@@ -1,115 +1,115 @@
|
||||
// FictionViewerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
|
||||
FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(FictionViewerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(FictionViewerDlg)
|
||||
m_story_file = _T("");
|
||||
m_font_file = _T("");
|
||||
m_fiction_music = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(FictionViewerDlg)
|
||||
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
|
||||
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
|
||||
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(FictionViewerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(FictionViewerDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg message handlers
|
||||
|
||||
BOOL FictionViewerDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
CComboBox *box;
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FICTION_MUSIC);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++){
|
||||
box->AddString(Spooled_music[i].name);
|
||||
}
|
||||
|
||||
// init variables
|
||||
m_story_file = _T(fiction_file());
|
||||
m_font_file = _T(fiction_font());
|
||||
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// load it up
|
||||
fiction_viewer_reset();
|
||||
fiction_viewer_load((char *)(LPCSTR) m_story_file, (char *)(LPCSTR) m_font_file);
|
||||
|
||||
// set music
|
||||
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::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);
|
||||
}
|
||||
// FictionViewerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fred.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "missionui/fictionviewer.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
|
||||
FictionViewerDlg::FictionViewerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(FictionViewerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(FictionViewerDlg)
|
||||
m_story_file = _T("");
|
||||
m_font_file = _T("");
|
||||
m_fiction_music = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void FictionViewerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(FictionViewerDlg)
|
||||
DDX_Text(pDX, IDC_STORY_FILE, m_story_file);
|
||||
DDX_Text(pDX, IDC_FONT_FILE, m_font_file);
|
||||
DDX_CBIndex(pDX, IDC_FICTION_MUSIC, m_fiction_music);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(FictionViewerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(FictionViewerDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg message handlers
|
||||
|
||||
BOOL FictionViewerDlg::OnInitDialog()
|
||||
{
|
||||
int i;
|
||||
CComboBox *box;
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FICTION_MUSIC);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++){
|
||||
box->AddString(Spooled_music[i].name);
|
||||
}
|
||||
|
||||
// init variables
|
||||
m_story_file = _T(fiction_file());
|
||||
m_font_file = _T(fiction_font());
|
||||
m_fiction_music = Mission_music[SCORE_FICTION_VIEWER] + 1;
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnOK()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// load it up
|
||||
fiction_viewer_reset();
|
||||
fiction_viewer_load((char *)(LPCSTR) m_story_file, (char *)(LPCSTR) m_font_file);
|
||||
|
||||
// set music
|
||||
Mission_music[SCORE_FICTION_VIEWER] = m_fiction_music - 1;
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnCancel()
|
||||
{
|
||||
// TODO: Add extra cleanup here
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
void FictionViewerDlg::OnClose()
|
||||
{
|
||||
int z;
|
||||
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (query_modified()) {
|
||||
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
if (z == IDCANCEL){
|
||||
return;
|
||||
}
|
||||
|
||||
if (z == IDYES) {
|
||||
OnOK();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::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);
|
||||
}
|
||||
@@ -1,52 +1,52 @@
|
||||
#if !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#define AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FictionViewerDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
class FictionViewerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
FictionViewerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
int query_modified();
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(FictionViewerDlg)
|
||||
enum { IDD = IDD_FICTION_VIEWER };
|
||||
CString m_story_file;
|
||||
CString m_font_file;
|
||||
int m_fiction_music;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(FictionViewerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(FictionViewerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#if !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
#define AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FictionViewerDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FictionViewerDlg dialog
|
||||
|
||||
class FictionViewerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
FictionViewerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
int query_modified();
|
||||
void OnOK();
|
||||
void OnCancel();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(FictionViewerDlg)
|
||||
enum { IDD = IDD_FICTION_VIEWER };
|
||||
CString m_story_file;
|
||||
CString m_font_file;
|
||||
int m_fiction_music;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(FictionViewerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(FictionViewerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FICTIONVIEWERDLG_H__46BAD1B6_F9DC_4414_9C33_18EC17FD491F__INCLUDED_)
|
||||
@@ -186,7 +186,7 @@ void briefing_editor_dlg::create()
|
||||
box->AddString(Icon_names[i]);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_TEAM);
|
||||
for (i=0; i<Num_team_names; i++)
|
||||
for (i=0; i<Num_iffs; i++)
|
||||
box->AddString(Iff_info[i].iff_name);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_SHIP_TYPE);
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
#include "DebriefingEditorDlg.h"
|
||||
#include "FREDDoc.h"
|
||||
#include "mission/missionbriefcommon.h"
|
||||
#include "mission/missionparse.h"
|
||||
#include "globalincs/linklist.h"
|
||||
#include "parse/sexp.h"
|
||||
#include "gamesnd/eventmusic.h"
|
||||
#include "cfile/cfile.h"
|
||||
#include "sound/audiostr.h"
|
||||
#include "localization/localize.h"
|
||||
@@ -35,6 +38,9 @@ debriefing_editor_dlg::debriefing_editor_dlg(CWnd* pParent /*=NULL*/)
|
||||
m_voice = _T("");
|
||||
m_stage_title = _T("");
|
||||
m_rec_text = _T("");
|
||||
m_debriefPass_music = 0;
|
||||
m_debriefAvg_music = 0;
|
||||
m_debriefFail_music = 0;
|
||||
m_current_debriefing = -1;
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
@@ -54,6 +60,9 @@ void debriefing_editor_dlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Text(pDX, IDC_VOICE, m_voice);
|
||||
DDX_Text(pDX, IDC_STAGE_TITLE, m_stage_title);
|
||||
DDX_Text(pDX, IDC_REC_TEXT, m_rec_text);
|
||||
DDX_CBIndex(pDX, IDC_SUCCESSFUL_MISSION_TRACK, m_debriefPass_music);
|
||||
DDX_CBIndex(pDX, IDC_DEBRIEFING_TRACK, m_debriefAvg_music);
|
||||
DDX_CBIndex(pDX, IDC_FAILED_MISSION_TRACK, m_debriefFail_music);
|
||||
//}}AFX_DATA_MAP
|
||||
|
||||
DDV_MaxChars(pDX, m_text, MAX_BRIEF_LEN - 1);
|
||||
@@ -115,12 +124,33 @@ BOOL debriefing_editor_dlg::OnInitDialog()
|
||||
CDialog::OnInitDialog();
|
||||
m_play_bm.LoadBitmap(IDB_PLAY);
|
||||
((CButton *) GetDlgItem(IDC_PLAY)) -> SetBitmap(m_play_bm);
|
||||
CComboBox *box;
|
||||
box = (CComboBox *) GetDlgItem(IDC_ICON_IMAGE);
|
||||
|
||||
m_current_debriefing = 0;
|
||||
UpdateData(FALSE);
|
||||
|
||||
Debriefing = &Debriefings[m_current_debriefing];
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_SUCCESSFUL_MISSION_TRACK);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++)
|
||||
box->AddString(Spooled_music[i].name);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_DEBRIEFING_TRACK);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++)
|
||||
box->AddString(Spooled_music[i].name);
|
||||
|
||||
box = (CComboBox *) GetDlgItem(IDC_FAILED_MISSION_TRACK);
|
||||
box->AddString("None");
|
||||
for (i=0; i<Num_music_files; i++)
|
||||
box->AddString(Spooled_music[i].name);
|
||||
|
||||
m_debriefPass_music = Mission_music[SCORE_DEBRIEF_SUCCESS] + 1;
|
||||
m_debriefAvg_music = Mission_music[SCORE_DEBRIEF_AVERAGE] + 1;
|
||||
m_debriefFail_music = Mission_music[SCORE_DEBRIEF_FAIL] + 1;
|
||||
|
||||
m_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
|
||||
n = m_tree.select_sexp_node = select_sexp_node;
|
||||
select_sexp_node = -1;
|
||||
@@ -139,6 +169,7 @@ BOOL debriefing_editor_dlg::OnInitDialog()
|
||||
}
|
||||
}
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
update_data();
|
||||
set_modified();
|
||||
|
||||
@@ -402,6 +433,11 @@ void debriefing_editor_dlg::OnClose()
|
||||
m_voice_id = -1;
|
||||
m_cur_stage = -1;
|
||||
update_data(1);
|
||||
|
||||
Mission_music[SCORE_DEBRIEF_SUCCESS] = m_debriefPass_music - 1;
|
||||
Mission_music[SCORE_DEBRIEF_AVERAGE] = m_debriefAvg_music - 1;
|
||||
Mission_music[SCORE_DEBRIEF_FAIL] = m_debriefFail_music - 1;
|
||||
|
||||
CDialog::OnClose();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "mission/missionbriefcommon.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// debriefing_editor_dlg dialog
|
||||
@@ -29,6 +30,9 @@ public:
|
||||
CString m_voice;
|
||||
CString m_stage_title;
|
||||
CString m_rec_text;
|
||||
int m_debriefPass_music;
|
||||
int m_debriefAvg_music;
|
||||
int m_debriefFail_music;
|
||||
int m_current_debriefing;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
@@ -1254,7 +1254,7 @@ void event_editor::OnBrowseAvi()
|
||||
|
||||
z = cfile_push_chdir(CF_TYPE_INTERFACE);
|
||||
CFileDialog dlg(TRUE, "ani", m_avi_filename, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
|
||||
"Ani Files (*.ani)|*.ani|Avi Files (*.avi)|*.avi|Both (*.ani, *.avi)|*.ani;*.avi||");
|
||||
"Ani Files (*.ani)|*.ani|Eff Files (*.eff)|*.eff|Avi Files (*.avi)|*.avi|Both (*.ani, *.avi)|*.ani;*.avi||");
|
||||
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
m_avi_filename = dlg.GetFileName();
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "CampaignTreeWnd.h"
|
||||
#include "CampaignTreeView.h"
|
||||
#include "CampaignEditorDlg.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "globalincs/mspdb_callstack.h"
|
||||
|
||||
#include "AFXADV.H"
|
||||
@@ -98,7 +97,6 @@ CFREDApp::CFREDApp()
|
||||
{
|
||||
app_init = 0;
|
||||
|
||||
DBUGFILE_INIT();
|
||||
SCP_mspdbcs_Initialise( );
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -109,7 +107,6 @@ CFREDApp::CFREDApp()
|
||||
CFREDApp::~CFREDApp()
|
||||
{
|
||||
SCP_mspdbcs_Cleanup( );
|
||||
DBUGFILE_DEINIT();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+14
-7
@@ -622,7 +622,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.6.13 OpenGL",IDC_STATIC,39,8,184,10,SS_NOPREFIX
|
||||
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.6.14 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
|
||||
@@ -1646,7 +1646,7 @@ BEGIN
|
||||
CONTROL "order 10",IDC_CHECK10,"Button",BS_3STATE | WS_TABSTOP,7,183,105,10
|
||||
END
|
||||
|
||||
IDD_DEBRIEFING_EDITOR DIALOGEX 0, 0, 322, 172
|
||||
IDD_DEBRIEFING_EDITOR DIALOGEX 0, 0, 322, 225
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Debriefing Editor"
|
||||
MENU IDR_PLAYER_EDIT_MENU
|
||||
@@ -1668,6 +1668,13 @@ BEGIN
|
||||
LTEXT "Stage 1 of 9",IDC_STAGE_TITLE,7,10,53,8
|
||||
LTEXT "Usage Formula",IDC_STATIC,7,43,48,8
|
||||
LTEXT "Recommendation Text",IDC_STATIC,135,96,72,8
|
||||
GROUPBOX "Debriefing Music",IDC_STATIC,7,175,260,45
|
||||
LTEXT "Success Music",IDC_STATIC,15,187,53,8
|
||||
COMBOBOX IDC_SUCCESSFUL_MISSION_TRACK,12,195,80,180,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Average Music",IDC_STATIC,100,187,53,8
|
||||
COMBOBOX IDC_DEBRIEFING_TRACK,97,195,80,180,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Failure Music",IDC_STATIC,185,187,53,8
|
||||
COMBOBOX IDC_FAILED_MISSION_TRACK,182,195,80,180,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_ADJUST_GRID DIALOG 0, 0, 153, 94
|
||||
@@ -2064,8 +2071,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,6,13,0
|
||||
PRODUCTVERSION 3,6,13,0
|
||||
FILEVERSION 3,6,14,9276
|
||||
PRODUCTVERSION 3,6,14,9276
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -2082,12 +2089,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Volition Inc."
|
||||
VALUE "FileDescription", "Fred 2 Open"
|
||||
VALUE "FileVersion", "3.6.13.0000"
|
||||
VALUE "FileVersion", "3.6.14.9276"
|
||||
VALUE "InternalName", "Fred 2 Open"
|
||||
VALUE "LegalCopyright", "Copyright © 1998"
|
||||
VALUE "OriginalFilename", "fred2.exe"
|
||||
VALUE "ProductName", "Fred 2 Open"
|
||||
VALUE "ProductVersion", "3.6.13"
|
||||
VALUE "ProductVersion", "3.6.14"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
@@ -2658,7 +2665,7 @@ IDC_CURSOR2 CURSOR "res\\cursor2.cur"
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDR_MAINFRAME "FRED2_OPEN 3.6.13 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
|
||||
IDR_MAINFRAME "FRED2_OPEN 3.6.14 RC6 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
|
||||
@@ -905,7 +905,7 @@ void render_one_model_htl(object *objp)
|
||||
|
||||
if (Fred_outline) {
|
||||
model_set_outline_color(Fred_outline >> 16, (Fred_outline >> 8) & 0xff, Fred_outline & 0xff);
|
||||
j |= MR_SHOW_OUTLINE;
|
||||
j |= MR_SHOW_OUTLINE_HTL;
|
||||
}
|
||||
|
||||
g3_done_instance(0);
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
#include "VoiceActingManager.h"
|
||||
#include "FictionViewerDlg.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "sound/audiostr.h"
|
||||
@@ -2453,12 +2452,6 @@ int CFREDView::global_error_check()
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count && Ships[i].weapons.num_secondary_banks > 0){
|
||||
if (error("Player \"%s\" has no secondary weapons. Should have at least 1", Ships[i].ship_name)){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Ships[i].objnum != OBJ_INDEX(ptr)){
|
||||
@@ -4593,7 +4586,6 @@ void CFREDView::OnDestroy()
|
||||
{
|
||||
audiostream_close();
|
||||
snd_close();
|
||||
DBUGFILE_OUTPUT_0("About to gr_close");
|
||||
gr_close();
|
||||
os_set_window(NULL);
|
||||
|
||||
|
||||
@@ -941,7 +941,7 @@ void initial_status::undock(object *objp1, object *objp2)
|
||||
ship_num = get_ship_from_obj(OBJ_INDEX(objp1));
|
||||
other_ship_num = get_ship_from_obj(OBJ_INDEX(objp2));
|
||||
|
||||
if (ship_class_compare(Ships[ship_num].ship_info_index, Ships[other_ship_num].ship_info_index) > 0)
|
||||
if (ship_class_compare(Ships[ship_num].ship_info_index, Ships[other_ship_num].ship_info_index) <= 0)
|
||||
vm_vec_scale_add2(&objp2->pos, &v, objp2->radius * 2.0f);
|
||||
else
|
||||
vm_vec_scale_add2(&objp1->pos, &v, objp1->radius * -2.0f);
|
||||
@@ -973,51 +973,6 @@ void initial_status::undock(object *objp1, object *objp2)
|
||||
|
||||
// ----- the following are not contained in the class because of apparent scope issues -----
|
||||
|
||||
// NOTE - in both retail and SCP, the dock "leader" is defined as the only guy in his
|
||||
// group with a non-false arrival cue
|
||||
void initial_status_mark_dock_leader_helper(object *objp, dock_function_info *infop)
|
||||
{
|
||||
ship *shipp = &Ships[objp->instance];
|
||||
|
||||
// all ships except the leader should have a locked false arrival cue
|
||||
if (shipp->arrival_cue != Locked_sexp_false)
|
||||
{
|
||||
object *existing_leader;
|
||||
|
||||
// increment number of leaders found
|
||||
infop->maintained_variables.int_value++;
|
||||
|
||||
// see if we already found a leader
|
||||
existing_leader = infop->maintained_variables.objp_value;
|
||||
if (existing_leader != NULL)
|
||||
{
|
||||
ship *leader_shipp = &Ships[existing_leader->instance];
|
||||
|
||||
// keep existing leader if he has a higher priority than us
|
||||
if (ship_class_compare(shipp->ship_info_index, leader_shipp->ship_info_index) < 0)
|
||||
{
|
||||
// set my arrival cue to false
|
||||
reset_arrival_to_false(SHIP_INDEX(shipp), true);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, unmark the existing leader and set his arrival cue to false
|
||||
leader_shipp->flags &= ~SF_DOCK_LEADER;
|
||||
reset_arrival_to_false(SHIP_INDEX(leader_shipp), true);
|
||||
}
|
||||
|
||||
// mark and save me as the leader
|
||||
shipp->flags |= SF_DOCK_LEADER;
|
||||
infop->maintained_variables.objp_value = objp;
|
||||
}
|
||||
}
|
||||
|
||||
// self-explanatory, really
|
||||
void initial_status_unmark_dock_handled_flag(object *objp, dock_function_info *infop)
|
||||
{
|
||||
objp->flags &= ~OF_DOCKED_ALREADY_HANDLED;
|
||||
}
|
||||
|
||||
bool set_cue_to_false(int *cue)
|
||||
{
|
||||
// if the cue is not false, make it false. Be sure to set all ship editor dialog functions
|
||||
@@ -1025,11 +980,13 @@ bool set_cue_to_false(int *cue)
|
||||
if (*cue != Locked_sexp_false)
|
||||
{
|
||||
Ship_editor_dialog.update_data(1);
|
||||
Wing_editor_dialog.update_data(1);
|
||||
|
||||
free_sexp2(*cue);
|
||||
*cue = Locked_sexp_false;
|
||||
|
||||
Ship_editor_dialog.initialize_data(1);
|
||||
Wing_editor_dialog.initialize_data(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1067,6 +1024,63 @@ void reset_arrival_to_false(int shipnum, bool reset_wing)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE - in both retail and SCP, the dock "leader" is defined as the only guy in his
|
||||
// group with a non-false arrival cue
|
||||
void initial_status_mark_dock_leader_helper(object *objp, dock_function_info *infop)
|
||||
{
|
||||
ship *shipp = &Ships[objp->instance];
|
||||
int cue_to_check;
|
||||
|
||||
// if this guy is part of a wing, he uses his wing's arrival cue
|
||||
if (shipp->wingnum >= 0)
|
||||
{
|
||||
cue_to_check = Wings[shipp->wingnum].arrival_cue;
|
||||
}
|
||||
// check the ship's arrival cue
|
||||
else
|
||||
{
|
||||
cue_to_check = shipp->arrival_cue;
|
||||
}
|
||||
|
||||
// all ships except the leader should have a locked false arrival cue
|
||||
if (cue_to_check != Locked_sexp_false)
|
||||
{
|
||||
object *existing_leader;
|
||||
|
||||
// increment number of leaders found
|
||||
infop->maintained_variables.int_value++;
|
||||
|
||||
// see if we already found a leader
|
||||
existing_leader = infop->maintained_variables.objp_value;
|
||||
if (existing_leader != NULL)
|
||||
{
|
||||
ship *leader_shipp = &Ships[existing_leader->instance];
|
||||
|
||||
// keep existing leader if he has a higher priority than us
|
||||
if (ship_class_compare(shipp->ship_info_index, leader_shipp->ship_info_index) >= 0)
|
||||
{
|
||||
// set my arrival cue to false
|
||||
reset_arrival_to_false(SHIP_INDEX(shipp), true);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, unmark the existing leader and set his arrival cue to false
|
||||
leader_shipp->flags &= ~SF_DOCK_LEADER;
|
||||
reset_arrival_to_false(SHIP_INDEX(leader_shipp), true);
|
||||
}
|
||||
|
||||
// mark and save me as the leader
|
||||
shipp->flags |= SF_DOCK_LEADER;
|
||||
infop->maintained_variables.objp_value = objp;
|
||||
}
|
||||
}
|
||||
|
||||
// self-explanatory, really
|
||||
void initial_status_unmark_dock_handled_flag(object *objp, dock_function_info *infop)
|
||||
{
|
||||
objp->flags &= ~OF_DOCKED_ALREADY_HANDLED;
|
||||
}
|
||||
|
||||
void initial_status::OnPrimariesLocked()
|
||||
{
|
||||
if (m_primaries_locked == 1)
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
#include "species_defs/species_defs.h"
|
||||
#include "osapi/osapi.h"
|
||||
#include "graphics/font.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "object/objectdock.h"
|
||||
#include "gamesnd/gamesnd.h"
|
||||
#include "iff_defs/iff_defs.h"
|
||||
@@ -345,7 +344,6 @@ bool fred_init()
|
||||
#endif
|
||||
|
||||
// d'oh
|
||||
DBUGFILE_OUTPUT_0("About to cfile_init");
|
||||
if(cfile_init(Fred_exe_dir)){
|
||||
exit(1);
|
||||
}
|
||||
@@ -394,13 +392,11 @@ bool fred_init()
|
||||
// Cmdline_nospec = 1;
|
||||
// Cmdline_noglow = 1;
|
||||
Cmdline_window = 1;
|
||||
DBUGFILE_OUTPUT_0("About to gr_init");
|
||||
|
||||
gr_init(GR_OPENGL, 640, 480, 32);
|
||||
|
||||
Mouse_hidden = 1;
|
||||
|
||||
DBUGFILE_OUTPUT_0("About to init everything");
|
||||
gr_font_init(); // loads up all fonts
|
||||
|
||||
gr_set_gamma(3.0f);
|
||||
@@ -475,12 +471,9 @@ bool fred_init()
|
||||
gr_reset_clip();
|
||||
g3_start_frame(0);
|
||||
g3_set_view_matrix(&eye_pos, &eye_orient, 0.5f);
|
||||
|
||||
for (i=0; i<Num_ship_classes; i++)
|
||||
if (Ship_info[i].flags & SIF_DEFAULT_PLAYER_SHIP) {
|
||||
Default_player_model = cur_model_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the default player ship
|
||||
Default_player_model = cur_model_index = get_default_player_ship_index();
|
||||
|
||||
Id_select_type_start = Num_ship_classes + 2;
|
||||
Id_select_type_jump_node = Num_ship_classes + 1;
|
||||
|
||||
@@ -630,11 +630,12 @@ void CMissionNotesDlg::OnSquadLogo()
|
||||
}
|
||||
}
|
||||
|
||||
char *Load_screen_ext = "Image Files (*.dds, *.pcx, *.jpg, *.jpeg, *.tga)|*.dds;*.pcx;*.jpg;*.jpeg;*.tga|"
|
||||
char *Load_screen_ext = "Image Files (*.dds, *.pcx, *.jpg, *.jpeg, *.tga, *.png)|*.dds;*.pcx;*.jpg;*.jpeg;*.tga;*.png|"
|
||||
"DDS Files (*.dds)|*.dds|"
|
||||
"PCX Files (*.pcx)|*.pcx|"
|
||||
"JPG Files (*.jpg; *.jpeg)|*.jpg;*.jpeg|"
|
||||
"TGA Files (*.tga)|*.tga|"
|
||||
"PNG Files (*.png)|*.png|"
|
||||
"All Files (*.*)|*.*|"
|
||||
"|";
|
||||
|
||||
|
||||
@@ -347,13 +347,13 @@ int CFred_mission_save::save_mission_info()
|
||||
fout("\n+Storm: %s\n", Mission_parse_storm_name);
|
||||
}
|
||||
|
||||
// write out the nebula clipping multipliers
|
||||
fout("\n+Fog Near Mult: %f\n", Neb2_fog_near_mult);
|
||||
fout("\n+Fog Far Mult: %f\n", Neb2_fog_far_mult);
|
||||
|
||||
// Goober5000
|
||||
if (Format_fs2_open != FSO_FORMAT_RETAIL)
|
||||
{
|
||||
// write out the nebula clipping multipliers
|
||||
fout("\n+Fog Near Mult: %f\n", Neb2_fog_near_mult);
|
||||
fout("\n+Fog Far Mult: %f\n", Neb2_fog_far_mult);
|
||||
|
||||
if (The_mission.contrail_threshold != CONTRAIL_THRESHOLD_DEFAULT)
|
||||
{
|
||||
fout("\n$Contrail Speed Threshold: %d\n", The_mission.contrail_threshold);
|
||||
@@ -710,7 +710,10 @@ int CFred_mission_save::save_cutscenes()
|
||||
break;
|
||||
case MOVIE_PRE_DEBRIEF:
|
||||
strcpy_s(type, "$Debriefing Cutscene:");
|
||||
break;
|
||||
break;
|
||||
case MOVIE_END_CAMPAIGN:
|
||||
strcpy_s(type, "$Campaign End Cutscene:");
|
||||
break;
|
||||
default:
|
||||
Int3();
|
||||
continue;
|
||||
@@ -2069,8 +2072,13 @@ int CFred_mission_save::save_common_object_data(object *objp, ship *shipp)
|
||||
fout("\n+Primary Banks:");
|
||||
|
||||
fout(" ( ");
|
||||
for (j=0; j<wp->num_primary_banks; j++)
|
||||
fout("\"%s\" ", Weapon_info[wp->primary_bank_weapons[j]].name);
|
||||
for (j=0; j<wp->num_primary_banks; j++) {
|
||||
if (wp->primary_bank_weapons[j] != -1) { // Just in case someone has set a weapon bank to empty
|
||||
fout("\"%s\" ", Weapon_info[wp->primary_bank_weapons[j]].name);
|
||||
} else {
|
||||
fout("\"\" ");
|
||||
}
|
||||
}
|
||||
|
||||
fout(")");
|
||||
}
|
||||
@@ -2088,8 +2096,13 @@ int CFred_mission_save::save_common_object_data(object *objp, ship *shipp)
|
||||
fout("\n+Secondary Banks:");
|
||||
|
||||
fout(" ( ");
|
||||
for (j=0; j<wp->num_secondary_banks; j++)
|
||||
fout("\"%s\" ", Weapon_info[wp->secondary_bank_weapons[j]].name);
|
||||
for (j=0; j<wp->num_secondary_banks; j++) {
|
||||
if (wp->secondary_bank_weapons[j] != -1) {
|
||||
fout("\"%s\" ", Weapon_info[wp->secondary_bank_weapons[j]].name);
|
||||
} else {
|
||||
fout("\"\" ");
|
||||
}
|
||||
}
|
||||
|
||||
fout(")");
|
||||
}
|
||||
|
||||
@@ -131,15 +131,15 @@ BOOL orient_editor::OnInitDialog()
|
||||
m_object_index = 0;
|
||||
}
|
||||
|
||||
m_spin1.SetRange((short)99999, (short)-99999);
|
||||
m_spin1.SetRange((short)9999, (short)-9999);
|
||||
m_spin1.SetPos((int) convert(m_position_x));
|
||||
m_spin2.SetRange((short)99999, (short)-99999);
|
||||
m_spin2.SetRange((short)9999, (short)-9999);
|
||||
m_spin2.SetPos((int) convert(m_position_y));
|
||||
m_spin3.SetRange((short)99999, (short)-99999);
|
||||
m_spin3.SetRange((short)9999, (short)-9999);
|
||||
m_spin3.SetPos((int) convert(m_position_z));
|
||||
m_spin4.SetRange((short)99999, (short)-99999);
|
||||
m_spin5.SetRange((short)99999, (short)-99999);
|
||||
m_spin6.SetRange((short)99999, (short)-99999);
|
||||
m_spin4.SetRange((short)9999, (short)-9999);
|
||||
m_spin5.SetRange((short)9999, (short)-9999);
|
||||
m_spin6.SetRange((short)9999, (short)-9999);
|
||||
UpdateData(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+74
-98
@@ -564,71 +564,6 @@ void sexp_tree::setup_selected(HTREEITEM h)
|
||||
}
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
int get_sexp_id(char *sexp_name)
|
||||
{
|
||||
for (int i = 0; i < Num_operators; i++)
|
||||
{
|
||||
if (!stricmp(sexp_name, Operators[i].text))
|
||||
return Operators[i].value;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
int get_category(int sexp_id)
|
||||
{
|
||||
int category = (sexp_id & OP_CATEGORY_MASK);
|
||||
|
||||
// hack so that CHANGE and CHANGE2 show up in the same menu
|
||||
if (category == OP_CATEGORY_CHANGE2)
|
||||
category = OP_CATEGORY_CHANGE;
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
int category_of_subcategory(int subcategory_id)
|
||||
{
|
||||
int category = (subcategory_id & OP_CATEGORY_MASK);
|
||||
|
||||
// hack so that CHANGE and CHANGE2 show up in the same menu
|
||||
if (category == OP_CATEGORY_CHANGE2)
|
||||
category = OP_CATEGORY_CHANGE;
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
// this seems not to be used anywhere?
|
||||
int get_category_id(char *category_name)
|
||||
{
|
||||
for (int i = 0; i < Num_op_menus; i++)
|
||||
{
|
||||
if (!stricmp(category_name, op_menu[i].name))
|
||||
{
|
||||
return op_menu[i].id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
// this seems not to be used anywhere?
|
||||
int has_submenu(char *category_name)
|
||||
{
|
||||
int category_id = get_category_id(category_name);
|
||||
if (category_id != -1)
|
||||
{
|
||||
for (int i = 0; i < Num_submenus; i++)
|
||||
{
|
||||
if (category_of_subcategory(op_submenu[i].id) == category_id)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handler for right mouse button clicks.
|
||||
void sexp_tree::right_clicked(int mode)
|
||||
{
|
||||
@@ -2253,7 +2188,6 @@ int sexp_tree::add_default_operator(int op, int argnum)
|
||||
(argnum == 8 && Operators[op].value == OP_ADD_BACKGROUND_BITMAP) ||
|
||||
(argnum == 5 && Operators[op].value == OP_ADD_SUN_BITMAP) ||
|
||||
(argnum == 2 && Operators[op].value == OP_STRING_CONCATENATE) ||
|
||||
(argnum == 0 && Operators[op].value == OP_DIRECTIVE_IS_VARIABLE) ||
|
||||
(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))
|
||||
@@ -2347,7 +2281,7 @@ int sexp_tree::get_default_value(sexp_list_item *item, int op, int i)
|
||||
{
|
||||
item->set_data("-1", (SEXPT_NUMBER | SEXPT_VALID));
|
||||
}
|
||||
else if ( (Operators[op].value == OP_SHIP_TAG) && (i == 1) )
|
||||
else if ( (Operators[op].value == OP_SHIP_TAG) && (i == 1) || (Operators[op].value == OP_TRIGGER_SUBMODEL_ANIMATION) && (i == 3) )
|
||||
{
|
||||
item->set_data("1", (SEXPT_NUMBER | SEXPT_VALID));
|
||||
}
|
||||
@@ -2694,8 +2628,8 @@ int sexp_tree::query_default_argument_available(int op, int i)
|
||||
case OPF_TURRET_TARGET_ORDER:
|
||||
case OPF_POST_EFFECT:
|
||||
case OPF_TARGET_PRIORITIES:
|
||||
case OPF_ARMOR_TYPES:
|
||||
case OPF_DAMAGE_TYPES:
|
||||
case OPF_ARMOR_TYPE:
|
||||
case OPF_DAMAGE_TYPE:
|
||||
case OPF_FONT:
|
||||
case OPF_HUD_ELEMENT:
|
||||
case OPF_SOUND_ENVIRONMENT:
|
||||
@@ -2706,6 +2640,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
|
||||
case OPF_MESSAGE_OR_STRING:
|
||||
case OPF_HUD_GAUGE:
|
||||
case OPF_SHIP_EFFECT:
|
||||
case OPF_ANIMATION_TYPE:
|
||||
return 1;
|
||||
|
||||
case OPF_SHIP:
|
||||
@@ -3089,12 +3024,12 @@ int sexp_tree::verify_tree(int node, int *bypass)
|
||||
|
||||
case OPF_IFF:
|
||||
if (type2 == SEXP_ATOM_STRING) {
|
||||
for (i=0; i<Num_team_names; i++)
|
||||
for (i=0; i<Num_iffs; i++)
|
||||
if (!stricmp(Team_names[i], tree_nodes[node].text))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == Num_team_names)
|
||||
if (i == Num_iffs)
|
||||
return node_error(node, "Iff team type expected here", bypass);
|
||||
|
||||
break;
|
||||
@@ -3294,10 +3229,9 @@ void sexp_tree::verify_and_fix_arguments(int node)
|
||||
(arg_num == 8 && Operators[op].value == OP_ADD_BACKGROUND_BITMAP) ||
|
||||
(arg_num == 5 && Operators[op].value == OP_ADD_SUN_BITMAP) ||
|
||||
(arg_num == 2 && Operators[op].value == OP_STRING_CONCATENATE) ||
|
||||
(arg_num == 0 && Operators[op].value == OP_DIRECTIVE_IS_VARIABLE) ||
|
||||
(arg_num == 1 && Operators[op].value == OP_INT_TO_STRING) ||
|
||||
(arg_num == 3 && Operators[op].value == OP_STRING_GET_SUBSTRING) ||
|
||||
(arg_num == 4 && Operators[op].value == OP_STRING_SET_SUBSTRING))
|
||||
(arg_num == 4 && Operators[op].value == OP_STRING_SET_SUBSTRING))
|
||||
{
|
||||
// make text_ptr to start - before '('
|
||||
get_variable_name_from_sexp_tree_node_text(tree_nodes[item_index].text, default_variable_text);
|
||||
@@ -4391,12 +4325,16 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
|
||||
list = get_listing_opf_turret_target_priorities();
|
||||
break;
|
||||
|
||||
case OPF_ARMOR_TYPES:
|
||||
list = get_listing_opf_armor_types();
|
||||
case OPF_ARMOR_TYPE:
|
||||
list = get_listing_opf_armor_type();
|
||||
break;
|
||||
|
||||
case OPF_DAMAGE_TYPES:
|
||||
list = get_listing_opf_damage_types();
|
||||
case OPF_DAMAGE_TYPE:
|
||||
list = get_listing_opf_damage_type();
|
||||
break;
|
||||
|
||||
case OPF_ANIMATION_TYPE:
|
||||
list = get_listing_opf_animation_type();
|
||||
break;
|
||||
|
||||
case OPF_PERSONA:
|
||||
@@ -4440,11 +4378,11 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
|
||||
break;
|
||||
|
||||
case OPF_HUD_GAUGE:
|
||||
list = get_listing_hud_gauge();
|
||||
list = get_listing_opf_hud_gauge();
|
||||
break;
|
||||
|
||||
case OPF_SHIP_EFFECT:
|
||||
list = get_listing_ship_effects();
|
||||
list = get_listing_opf_ship_effect();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -5176,21 +5114,33 @@ sexp_list_item *sexp_tree::get_listing_opf_ai_goal(int parent_node)
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_docker_point(int parent_node)
|
||||
{
|
||||
int i, z, sh;
|
||||
int i, z;
|
||||
sexp_list_item head;
|
||||
int sh = -1;
|
||||
|
||||
Assert(parent_node >= 0);
|
||||
Assert(!stricmp(tree_nodes[parent_node].text, "ai-dock"));
|
||||
Assert(!stricmp(tree_nodes[parent_node].text, "ai-dock") || !stricmp(tree_nodes[parent_node].text, "set-docked"));
|
||||
|
||||
z = tree_nodes[parent_node].parent;
|
||||
Assert(z >= 0);
|
||||
Assert(!stricmp(tree_nodes[z].text, "add-ship-goal") || !stricmp(tree_nodes[z].text, "add-wing-goal") || !stricmp(tree_nodes[z].text, "add-goal"));
|
||||
if (!stricmp(tree_nodes[parent_node].text, "ai-dock"))
|
||||
{
|
||||
z = tree_nodes[parent_node].parent;
|
||||
Assert(z >= 0);
|
||||
Assert(!stricmp(tree_nodes[z].text, "add-ship-goal") || !stricmp(tree_nodes[z].text, "add-wing-goal") || !stricmp(tree_nodes[z].text, "add-goal"));
|
||||
|
||||
z = tree_nodes[z].child;
|
||||
Assert(z >= 0);
|
||||
z = tree_nodes[z].child;
|
||||
Assert(z >= 0);
|
||||
|
||||
sh = ship_name_lookup(tree_nodes[z].text, 1);
|
||||
if (sh >= 0) {
|
||||
sh = ship_name_lookup(tree_nodes[z].text, 1);
|
||||
}
|
||||
else if (!stricmp(tree_nodes[parent_node].text, "set-docked"))
|
||||
{
|
||||
//Docker ship should be the first child node
|
||||
z = tree_nodes[parent_node].child;
|
||||
sh = ship_name_lookup(tree_nodes[z].text, 1);
|
||||
}
|
||||
|
||||
if (sh >= 0)
|
||||
{
|
||||
z = get_docking_list(Ship_info[Ships[sh].ship_info_index].model_num);
|
||||
for (i=0; i<z; i++)
|
||||
head.add_data(Docking_bay_list[i]);
|
||||
@@ -5201,17 +5151,32 @@ sexp_list_item *sexp_tree::get_listing_opf_docker_point(int parent_node)
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_dockee_point(int parent_node)
|
||||
{
|
||||
int i, z, sh;
|
||||
int i, z;
|
||||
sexp_list_item head;
|
||||
int sh = -1;
|
||||
|
||||
Assert(parent_node >= 0);
|
||||
Assert(!stricmp(tree_nodes[parent_node].text, "ai-dock"));
|
||||
Assert(!stricmp(tree_nodes[parent_node].text, "ai-dock") || !stricmp(tree_nodes[parent_node].text, "set-docked"));
|
||||
|
||||
z = tree_nodes[parent_node].child;
|
||||
Assert(z >= 0);
|
||||
if (!stricmp(tree_nodes[parent_node].text, "ai-dock"))
|
||||
{
|
||||
z = tree_nodes[parent_node].child;
|
||||
Assert(z >= 0);
|
||||
|
||||
sh = ship_name_lookup(tree_nodes[z].text, 1);
|
||||
if (sh >= 0) {
|
||||
sh = ship_name_lookup(tree_nodes[z].text, 1);
|
||||
}
|
||||
else if (!stricmp(tree_nodes[parent_node].text, "set-docked"))
|
||||
{
|
||||
//Dockee ship should be the third child node
|
||||
z = tree_nodes[parent_node].child; // 1
|
||||
z = tree_nodes[z].next; // 2
|
||||
z = tree_nodes[z].next; // 3
|
||||
|
||||
sh = ship_name_lookup(tree_nodes[z].text, 1);
|
||||
}
|
||||
|
||||
if (sh >= 0)
|
||||
{
|
||||
z = get_docking_list(Ship_info[Ships[sh].ship_info_index].model_num);
|
||||
for (i=0; i<z; i++)
|
||||
head.add_data(Docking_bay_list[i]);
|
||||
@@ -5333,7 +5298,7 @@ sexp_list_item *sexp_tree::get_listing_opf_adjust_audio_volume()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_hud_gauge()
|
||||
sexp_list_item *sexp_tree::get_listing_opf_hud_gauge()
|
||||
{
|
||||
sexp_list_item head;
|
||||
|
||||
@@ -5343,7 +5308,7 @@ sexp_list_item *sexp_tree::get_listing_hud_gauge()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_ship_effects()
|
||||
sexp_list_item *sexp_tree::get_listing_opf_ship_effect()
|
||||
{
|
||||
sexp_list_item head;
|
||||
|
||||
@@ -5844,7 +5809,7 @@ sexp_list_item *sexp_tree::get_listing_opf_turret_target_priorities()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_armor_types()
|
||||
sexp_list_item *sexp_tree::get_listing_opf_armor_type()
|
||||
{
|
||||
size_t t;
|
||||
sexp_list_item head;
|
||||
@@ -5854,7 +5819,7 @@ sexp_list_item *sexp_tree::get_listing_opf_armor_types()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_damage_types()
|
||||
sexp_list_item *sexp_tree::get_listing_opf_damage_type()
|
||||
{
|
||||
size_t t;
|
||||
sexp_list_item head;
|
||||
@@ -5865,6 +5830,17 @@ sexp_list_item *sexp_tree::get_listing_opf_damage_types()
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_animation_type()
|
||||
{
|
||||
size_t t;
|
||||
sexp_list_item head;
|
||||
|
||||
for (t = 0; t < MAX_TRIGGER_ANIMATION_TYPES; t++)
|
||||
head.add_data(Animation_type_names[t]);
|
||||
|
||||
return head.next;
|
||||
}
|
||||
|
||||
sexp_list_item *sexp_tree::get_listing_opf_hud_elements()
|
||||
{
|
||||
sexp_list_item head;
|
||||
|
||||
@@ -252,8 +252,8 @@ public:
|
||||
sexp_list_item *get_listing_opf_subsystem_or_none(int parent_node, int arg_index);
|
||||
sexp_list_item *get_listing_opf_subsys_or_generic(int parent_node, int arg_index);
|
||||
sexp_list_item *get_listing_opf_turret_target_order();
|
||||
sexp_list_item *get_listing_opf_armor_types();
|
||||
sexp_list_item *get_listing_opf_damage_types();
|
||||
sexp_list_item *get_listing_opf_armor_type();
|
||||
sexp_list_item *get_listing_opf_damage_type();
|
||||
sexp_list_item *get_listing_opf_turret_target_priorities();
|
||||
sexp_list_item *get_listing_opf_persona();
|
||||
sexp_list_item *get_listing_opf_font();
|
||||
@@ -264,8 +264,9 @@ public:
|
||||
sexp_list_item *get_listing_opf_explosion_option();
|
||||
sexp_list_item *get_listing_opf_adjust_audio_volume();
|
||||
sexp_list_item *get_listing_opf_weapon_banks();
|
||||
sexp_list_item *get_listing_hud_gauge();
|
||||
sexp_list_item *get_listing_ship_effects();
|
||||
sexp_list_item *get_listing_opf_hud_gauge();
|
||||
sexp_list_item *get_listing_opf_ship_effect();
|
||||
sexp_list_item *get_listing_opf_animation_type();
|
||||
|
||||
int m_mode;
|
||||
int item_index;
|
||||
|
||||
@@ -204,7 +204,7 @@ void ship_select::create_list()
|
||||
char text[512];
|
||||
object *ptr;
|
||||
|
||||
update_status();
|
||||
update_status(true);
|
||||
m_ship_list.ResetContent();
|
||||
list_size = 0;
|
||||
|
||||
@@ -301,7 +301,7 @@ void ship_select::OnOK()
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void ship_select::update_status()
|
||||
void ship_select::update_status(bool first_time)
|
||||
{
|
||||
int i, z;
|
||||
object *ptr;
|
||||
@@ -320,8 +320,8 @@ void ship_select::update_status()
|
||||
else
|
||||
obj_index[i]->flags |= OF_TEMP_MARKED;
|
||||
}
|
||||
|
||||
OnSelchangeShipList();
|
||||
if(!first_time)
|
||||
OnSelchangeShipList();
|
||||
}
|
||||
|
||||
void ship_select::OnFilterShips()
|
||||
|
||||
@@ -21,7 +21,7 @@ class ship_select : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
void update_status();
|
||||
void update_status(bool first_time = false);
|
||||
void OnOK();
|
||||
void create_list();
|
||||
ship_select(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
@@ -882,6 +882,8 @@ void CShipEditorDlg::initialize_data(int full_update)
|
||||
GetDlgItem(IDC_FLAGS)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_TEXTURES)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_ALT_SHIP_CLASS)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SPECIAL_EXP)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_SPECIAL_HITPOINTS)->EnableWindow(TRUE);
|
||||
} else {
|
||||
GetDlgItem(IDC_SHIP_NAME)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SHIP_CLASS)->EnableWindow(FALSE);
|
||||
@@ -891,6 +893,8 @@ void CShipEditorDlg::initialize_data(int full_update)
|
||||
GetDlgItem(IDC_FLAGS)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_TEXTURES)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_ALT_SHIP_CLASS)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPECIAL_EXP)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_SPECIAL_HITPOINTS)->EnableWindow(FALSE);
|
||||
}
|
||||
|
||||
// disable textures for multiple ships
|
||||
@@ -2273,6 +2277,12 @@ void CShipEditorDlg::OnRestrictArrival()
|
||||
CComboBox *box;
|
||||
restrict_paths dlg;
|
||||
|
||||
if (multi_edit)
|
||||
{
|
||||
MessageBox("Please select only one ship.", "Too many ships selected");
|
||||
return;
|
||||
}
|
||||
|
||||
// grab stuff from GUI
|
||||
UpdateData(TRUE);
|
||||
|
||||
@@ -2311,6 +2321,12 @@ void CShipEditorDlg::OnRestrictDeparture()
|
||||
CComboBox *box;
|
||||
restrict_paths dlg;
|
||||
|
||||
if (multi_edit)
|
||||
{
|
||||
MessageBox("Please select only one ship.", "Too many ships selected");
|
||||
return;
|
||||
}
|
||||
|
||||
// grab stuff from GUI
|
||||
UpdateData(TRUE);
|
||||
|
||||
|
||||
@@ -121,10 +121,10 @@ void WeaponEditorDlg::DoDataExchange(CDataExchange* pDX)
|
||||
m_ammo4 = m_ammo_max4;
|
||||
}
|
||||
|
||||
m_spin1.SetRange(0, m_ammo_max1);
|
||||
m_spin2.SetRange(0, m_ammo_max2);
|
||||
m_spin3.SetRange(0, m_ammo_max3);
|
||||
m_spin4.SetRange(0, m_ammo_max4);
|
||||
m_spin1.SetRange(0, (short) m_ammo_max1);
|
||||
m_spin2.SetRange(0, (short) m_ammo_max2);
|
||||
m_spin3.SetRange(0, (short) m_ammo_max3);
|
||||
m_spin4.SetRange(0, (short) m_ammo_max4);
|
||||
|
||||
} else {
|
||||
if (m_ammo1 != BLANK_FIELD)
|
||||
|
||||
+1
-1
@@ -229,7 +229,7 @@ int create_wing()
|
||||
leader = cur_object_index;
|
||||
ptr = GET_FIRST(&obj_used_list);
|
||||
while (ptr != END_OF_LIST(&obj_used_list)) {
|
||||
if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
|
||||
if (( (ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START) ) && (ptr->flags & OF_MARKED)) {
|
||||
count++;
|
||||
i = -1;
|
||||
switch (ptr->type) {
|
||||
|
||||
@@ -405,7 +405,7 @@ void wing_editor::initialize_data_safe(int full_update)
|
||||
for (i=0; i<Wings[cur_wing].wave_count; i++)
|
||||
ptr->AddString(Ships[Wings[cur_wing].ship_index[i]].ship_name);
|
||||
|
||||
m_threshold_spin.SetRange(0, Wings[cur_wing].wave_count - 1);
|
||||
m_threshold_spin.SetRange(0, (short) Wings[cur_wing].wave_count - 1);
|
||||
for (i=0; i<Num_reinforcements; i++)
|
||||
if (!stricmp(Reinforcements[i].name, Wings[cur_wing].name))
|
||||
break;
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "cutscene/cutscenes.h"
|
||||
#include "cutscene/movie.h"
|
||||
#include "debris/debris.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "exceptionhandler/exceptionhandler.h"
|
||||
#include "fireball/fireballs.h"
|
||||
#include "freespace2/freespace.h"
|
||||
@@ -986,7 +985,7 @@ void game_level_init(int seed)
|
||||
|
||||
Perspective_locked = false;
|
||||
|
||||
// reset the geometry batcher, this should to be done pretty soon in this mission load process (though it's not required)
|
||||
// reset the geometry map and distortion map batcher, this should to be done pretty soon in this mission load process (though it's not required)
|
||||
batch_reset();
|
||||
|
||||
// Initialize the game subsystems
|
||||
@@ -1036,7 +1035,6 @@ void game_level_init(int seed)
|
||||
Missiontime = 0;
|
||||
Pre_player_entry = 1; // Means the player has not yet entered.
|
||||
Entry_delay_time = 0; // Could get overwritten in mission read.
|
||||
fireball_preload(); // page in warphole bitmaps
|
||||
observer_init();
|
||||
flak_level_init(); // initialize flak - bitmaps, etc
|
||||
ct_level_init(); // initialize ships contrails, etc
|
||||
@@ -1063,7 +1061,7 @@ void game_level_init(int seed)
|
||||
Game_no_clear = 0;
|
||||
|
||||
// campaign wasn't ended
|
||||
Campaign_ended_in_mission = 0;
|
||||
Campaign_ending_via_supernova = 0;
|
||||
|
||||
Env_cubemap_drawn = false;
|
||||
|
||||
@@ -1246,8 +1244,7 @@ void game_loading_callback_init()
|
||||
if (Game_loading_background < 0)
|
||||
Game_loading_background = bm_load(Game_loading_bground_fname[gr_screen.res]);
|
||||
|
||||
strcpy_s(Game_loading_ani.filename, Game_loading_ani_fname[gr_screen.res]);
|
||||
generic_anim_init(&Game_loading_ani, Game_loading_ani.filename);
|
||||
generic_anim_init(&Game_loading_ani, Game_loading_ani_fname[gr_screen.res]);
|
||||
generic_anim_load(&Game_loading_ani);
|
||||
Assertion( Game_loading_ani.num_frames > 0, "Load Screen animation %s not found, or corrupted. Needs to be an animation with at least 1 frame.", Game_loading_ani.filename );
|
||||
|
||||
@@ -1378,8 +1375,6 @@ void game_post_level_init()
|
||||
extern void game_environment_map_gen();
|
||||
game_environment_map_gen();
|
||||
|
||||
model_level_post_init();
|
||||
|
||||
HUD_init();
|
||||
hud_setup_escort_list();
|
||||
mission_hotkey_set_defaults(); // set up the default hotkeys (from mission file)
|
||||
@@ -2390,7 +2385,7 @@ void game_show_standalone_framerate()
|
||||
/**
|
||||
* Show the time remaining in a mission. Used only when the end-mission sexpression is used
|
||||
*
|
||||
* ::mission_end_time is a global from missionparse.cpp that contains the mission time at which the
|
||||
* mission_end_time is a global from missionparse.cpp that contains the mission time at which the
|
||||
* mission should end (in fixed seconds). There is code in missionparse.cpp which actually handles
|
||||
* checking how much time is left.
|
||||
*/
|
||||
@@ -2531,6 +2526,7 @@ void game_set_view_clip(float frametime)
|
||||
if (g3_in_frame() == 0) {
|
||||
// Ensure that the bars are black
|
||||
gr_set_color(0,0,0);
|
||||
gr_set_bitmap(0); // Valathil - Dont ask me why this has to be here but otherwise the black bars dont draw
|
||||
gr_rect(0, 0, gr_screen.max_w, yborder, false);
|
||||
gr_rect(0, gr_screen.max_h-yborder, gr_screen.max_w, yborder, false);
|
||||
} else {
|
||||
@@ -2945,16 +2941,19 @@ void say_view_target()
|
||||
|
||||
end_string_at_first_hash_symbol(view_target_name);
|
||||
if ( strlen(view_target_name) ) {
|
||||
HUD_fixed_printf(0.0f, XSTR( "Viewing %s%s\n", 185), (Viewer_mode & VM_OTHER_SHIP) ? XSTR( "from ", 186) : "", view_target_name);
|
||||
hud_set_iff_color(&Objects[Player_ai->target_objnum], 1);
|
||||
HUD_fixed_printf(0.0f, gr_screen.current_color, XSTR( "Viewing %s%s\n", 185), (Viewer_mode & VM_OTHER_SHIP) ? XSTR( "from ", 186) : "", view_target_name);
|
||||
Show_viewing_from_self = 1;
|
||||
}
|
||||
} else {
|
||||
color col;
|
||||
gr_init_color(&col, 0, 255, 0);
|
||||
if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_OBSERVER) && (Player_obj->type == OBJ_OBSERVER)){
|
||||
HUD_fixed_printf(2.0f,XSTR( "Viewing from observer\n", 187));
|
||||
HUD_fixed_printf(2.0f, col, XSTR( "Viewing from observer\n", 187));
|
||||
Show_viewing_from_self = 1;
|
||||
} else {
|
||||
if (Show_viewing_from_self)
|
||||
HUD_fixed_printf(2.0f, XSTR( "Viewing from self\n", 188));
|
||||
HUD_fixed_printf(2.0f, col, XSTR( "Viewing from self\n", 188));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3333,7 +3332,7 @@ camid game_render_frame_setup()
|
||||
say_view_target();
|
||||
|
||||
if ( Viewer_mode & VM_PADLOCK_ANY ) {
|
||||
player_display_packlock_view();
|
||||
player_display_padlock_view();
|
||||
}
|
||||
|
||||
if (Game_mode & GM_DEAD) {
|
||||
@@ -3998,7 +3997,7 @@ void game_simulation_frame()
|
||||
|
||||
physics_set_viewer( &Viewer_obj->phys_info, viewer_direction );
|
||||
} else {
|
||||
physics_set_viewer( NULL, PHYSICS_VIEWER_FRONT );
|
||||
physics_set_viewer( &Objects[Player->objnum].phys_info, PHYSICS_VIEWER_FRONT );
|
||||
}
|
||||
|
||||
// evaluate mission departures and arrivals before we process all objects.
|
||||
@@ -4075,7 +4074,7 @@ void game_simulation_frame()
|
||||
obj_snd_do_frame(); // update the object-linked persistant sounds
|
||||
|
||||
game_maybe_update_sound_environment();
|
||||
snd_update_listener(&View_position, &Player_obj->phys_info.vel, &Player_obj->orient);
|
||||
snd_update_listener(&Eye_position, &Player_obj->phys_info.vel, &Eye_matrix);
|
||||
|
||||
// AL: debug code used for testing ambient subspace sound (ie when enabling subspace through debug console)
|
||||
#ifndef NDEBUG
|
||||
@@ -4194,52 +4193,49 @@ void game_render_hud(camid cid)
|
||||
void game_reset_shade_frame()
|
||||
{
|
||||
Fade_type = FI_NONE;
|
||||
Fade_delta_time = 1.0f;
|
||||
gr_create_shader(&Viewer_shader, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void game_shade_frame(float frametime)
|
||||
{
|
||||
int alpha = 0;
|
||||
|
||||
// only do frame shade if we are actually in a game play state
|
||||
if ( !game_actually_playing() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Fade_type != FI_NONE)
|
||||
{
|
||||
if ( (Viewer_shader.c == 0) && (Fade_type != FI_FADEOUT) ) {
|
||||
return;
|
||||
}
|
||||
if (Fade_type != FI_NONE) {
|
||||
Assert(Fade_start_timestamp > 0);
|
||||
Assert(Fade_end_timestamp > 0);
|
||||
Assert(Fade_end_timestamp > Fade_start_timestamp);
|
||||
|
||||
alpha = Viewer_shader.c;
|
||||
|
||||
// Fade in or out if necessary
|
||||
if (Fade_type == FI_FADEOUT) {
|
||||
alpha += fl2i(frametime * (255.0f / Fade_delta_time) + 0.5f);
|
||||
} else if (Fade_type == FI_FADEIN) {
|
||||
alpha -= fl2i(frametime * (255.0f / Fade_delta_time) + 0.5f);
|
||||
}
|
||||
|
||||
// Limit and set fade type if done
|
||||
if (alpha < 0) {
|
||||
alpha = 0;
|
||||
|
||||
if (Fade_type == FI_FADEIN) {
|
||||
Fade_type = FI_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (alpha > 255) {
|
||||
alpha = 255;
|
||||
if( timestamp() >= Fade_start_timestamp ) {
|
||||
int startAlpha = 0;
|
||||
int endAlpha = 0;
|
||||
|
||||
if (Fade_type == FI_FADEOUT) {
|
||||
Fade_type = FI_NONE;
|
||||
endAlpha = 255;
|
||||
} else if (Fade_type == FI_FADEIN) {
|
||||
startAlpha = 255;
|
||||
}
|
||||
}
|
||||
|
||||
Viewer_shader.c = (ubyte)alpha;
|
||||
int alpha = 0;
|
||||
|
||||
if( timestamp() < Fade_end_timestamp ) {
|
||||
int duration = (Fade_end_timestamp - Fade_start_timestamp);
|
||||
int elapsed = (timestamp() - Fade_start_timestamp);
|
||||
|
||||
alpha = fl2i( (float)startAlpha + (((float)endAlpha - (float)startAlpha) / (float)duration) * (float)elapsed );
|
||||
} else {
|
||||
//Fade finished
|
||||
Fade_type = FI_NONE;
|
||||
Fade_start_timestamp = 0;
|
||||
Fade_end_timestamp = 0;
|
||||
|
||||
alpha = endAlpha;
|
||||
}
|
||||
|
||||
Viewer_shader.c = (ubyte)alpha;
|
||||
}
|
||||
}
|
||||
|
||||
gr_flash_alpha(Viewer_shader.r, Viewer_shader.g, Viewer_shader.b, Viewer_shader.c);
|
||||
@@ -4271,6 +4267,7 @@ void bars_do_frame(float frametime)
|
||||
if (g3_in_frame() == 0) {
|
||||
//Set rectangles
|
||||
gr_set_color(0,0,0);
|
||||
gr_set_bitmap(0); // Valathil - Dont ask me why this has to be here but otherwise the black bars dont draw
|
||||
gr_rect(0, 0, gr_screen.max_w, yborder, false);
|
||||
gr_rect(0, gr_screen.max_h-yborder, gr_screen.max_w, yborder, false);
|
||||
} else {
|
||||
@@ -4285,6 +4282,7 @@ void bars_do_frame(float frametime)
|
||||
|
||||
if (g3_in_frame() == 0) {
|
||||
gr_set_color(0,0,0);
|
||||
gr_set_bitmap(0); // Valathil - Dont ask me why this has to be here but otherwise the black bars dont draw
|
||||
gr_rect(0, 0, gr_screen.max_w, yborder, false);
|
||||
gr_rect(0, gr_screen.max_h-yborder, gr_screen.max_w, yborder, false);
|
||||
} else {
|
||||
@@ -4453,6 +4451,9 @@ void game_frame(int paused)
|
||||
|
||||
camid cid = game_render_frame_setup();
|
||||
game_render_frame( cid );
|
||||
|
||||
//Cutscene bars
|
||||
clip_frame_view();
|
||||
|
||||
// save the eye position and orientation
|
||||
if ( Game_mode & GM_MULTIPLAYER ) {
|
||||
@@ -4501,8 +4502,9 @@ void game_frame(int paused)
|
||||
}
|
||||
}
|
||||
|
||||
//Cutscene bars
|
||||
clip_frame_view();
|
||||
// Goober5000 - check if we should red-alert
|
||||
// (this is approximately where the red_alert_check_status() function tree began in the pre-HUD-overhaul code)
|
||||
red_alert_maybe_move_to_next_mission();
|
||||
|
||||
DEBUG_GET_TIME( render3_time2 )
|
||||
DEBUG_GET_TIME( render2_time1 )
|
||||
@@ -5169,7 +5171,14 @@ void game_process_event( int current_state, int event )
|
||||
break;
|
||||
|
||||
case GS_EVENT_DEBRIEF:
|
||||
gameseq_set_state(GS_STATE_DEBRIEF);
|
||||
// did we end the campaign in the main freespace 2 single player campaign?
|
||||
// (specifically, did we successfully jump out when the supernova was in progress
|
||||
// and the campaign was ending?)
|
||||
if (Campaign_ending_via_supernova && (Game_mode & GM_CAMPAIGN_MODE)/* && !stricmp(Campaign.filename, "freespace2")*/) {
|
||||
gameseq_post_event(GS_EVENT_END_CAMPAIGN);
|
||||
} else {
|
||||
gameseq_set_state(GS_STATE_DEBRIEF);
|
||||
}
|
||||
break;
|
||||
|
||||
case GS_EVENT_SHIP_SELECTION:
|
||||
@@ -5203,6 +5212,15 @@ void game_process_event( int current_state, int event )
|
||||
extern button_info Multi_ship_status_bi;
|
||||
memset(&Multi_ship_status_bi, 0, sizeof(button_info));
|
||||
|
||||
// Make hv.Player available in "On Gameplay Start" hook -zookeeper
|
||||
if(Player_obj)
|
||||
Script_system.SetHookObject("Player", Player_obj);
|
||||
|
||||
Script_system.RunCondition(CHA_GAMEPLAYSTART);
|
||||
|
||||
if (Player_obj)
|
||||
Script_system.RemHookVar("Player");
|
||||
|
||||
Start_time = f2fl(timer_get_approx_seconds());
|
||||
//Framecount = 0;
|
||||
mprintf(("Entering game at time = %7.3f\n", Start_time));
|
||||
@@ -7127,8 +7145,6 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdSh
|
||||
atexit(memblockinfo_output_memleak);
|
||||
#endif
|
||||
|
||||
DBUGFILE_INIT();
|
||||
|
||||
//=====================================================
|
||||
// Make sure we're running in the right directory.
|
||||
char exe_dir[1024];
|
||||
@@ -7169,8 +7185,6 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdSh
|
||||
|
||||
SCP_mspdbcs_Cleanup( );
|
||||
|
||||
DBUGFILE_DEINIT();
|
||||
|
||||
::CoUninitialize();
|
||||
|
||||
#ifndef _MINGW
|
||||
@@ -7196,8 +7210,6 @@ int main(int argc, char *argv[])
|
||||
strncpy(full_path, *argv, 1024);
|
||||
#endif
|
||||
|
||||
DBUGFILE_INIT();
|
||||
|
||||
// create user's directory
|
||||
snprintf(userdir, MAX_PATH - 1, "%s/%s/", detect_home(), Osreg_user_dir);
|
||||
_mkdir(userdir);
|
||||
@@ -7238,8 +7250,6 @@ int main(int argc, char *argv[])
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
DBUGFILE_DEINIT();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7322,7 +7332,6 @@ void game_shutdown(void)
|
||||
// load up common multiplayer icons
|
||||
multi_unload_common_icons();
|
||||
hud_close();
|
||||
shockwave_close(); // release any memory used by shockwave system
|
||||
fireball_close(); // free fireball system
|
||||
particle_close(); // close out the particle system
|
||||
weapon_close(); // free any memory that was allocated for the weapons
|
||||
@@ -7568,7 +7577,6 @@ void game_do_training_checks()
|
||||
wplp = Training_context_path;
|
||||
if (wplp->get_waypoints().size() > (uint) Training_context_goal_waypoint) {
|
||||
i = Training_context_goal_waypoint;
|
||||
Warning(LOCATION, "The following is very inefficient with the new waypoint code! Contact Goober5000 if you need to use it.");
|
||||
do {
|
||||
waypoint *wpt = find_waypoint_at_index(wplp, i);
|
||||
Assert(wpt != NULL);
|
||||
|
||||
@@ -336,8 +336,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,6,13,0000
|
||||
PRODUCTVERSION 3,6,13,0000
|
||||
FILEVERSION 3,6,14,9276
|
||||
PRODUCTVERSION 3,6,14,9276
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -354,12 +354,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Volition Inc."
|
||||
VALUE "FileDescription", "FreeSpace 2 Open"
|
||||
VALUE "FileVersion", "3.6.13.0000"
|
||||
VALUE "FileVersion", "3.6.14.9276"
|
||||
VALUE "InternalName", "FreeSpace 2 Open"
|
||||
VALUE "LegalCopyright", "Copyright © 1998"
|
||||
VALUE "OriginalFilename", "fs2.exe"
|
||||
VALUE "ProductName", "FreeSpace 2 Open"
|
||||
VALUE "ProductVersion", "3.6.13"
|
||||
VALUE "ProductVersion", "3.6.14"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -34,14 +34,6 @@ extern void mflash_page_in(bool);
|
||||
// loaded mission. Call game_busy() occasionally...
|
||||
void level_page_in()
|
||||
{
|
||||
|
||||
// moved to freespace.cpp on 2005/04/18 - taylor
|
||||
// mprintf(( "Beginning level bitmap paging...\n" ));
|
||||
//
|
||||
// if(!(Game_mode & GM_STANDALONE_SERVER)){
|
||||
// bm_page_in_start();
|
||||
// }
|
||||
|
||||
// Most important ones first
|
||||
game_busy( NOX("*** paging in ships ***") );
|
||||
ship_page_in();
|
||||
@@ -53,7 +45,6 @@ void level_page_in()
|
||||
particle_page_in();
|
||||
debris_page_in();
|
||||
hud_page_in();
|
||||
training_mission_page_in();
|
||||
stars_page_in();
|
||||
shockwave_page_in();
|
||||
shield_hit_page_in();
|
||||
|
||||
@@ -1336,7 +1336,9 @@ void parse_menumusic()
|
||||
Warning(LOCATION, "Could not load spooled music file after '%s' as maximum number of spooled music was reached (Max is %d)", Spooled_music[Num_music_files - 1].name, MAX_SPOOLED_MUSIC);
|
||||
}
|
||||
|
||||
Assertion(skip_to_start_of_string_either("$Name:", "#Menu Music End"), "Couldn't find $Name or #Menu Music End. Music.tbl or -mus.tbm is invalid.\n");
|
||||
if (!skip_to_start_of_string_either("$Name:", "#Menu Music End")) {
|
||||
Error(LOCATION, "Couldn't find $Name or #Menu Music End. Music.tbl or -mus.tbm is invalid.\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1401,11 +1403,10 @@ void event_music_parse_musictbl(char *filename)
|
||||
}
|
||||
if ( optional_string("#Menu Music Start") )
|
||||
{
|
||||
while ( check_for_string( "$Name:" ) )
|
||||
while ( required_string_either("$Name", "#Menu Music End") == 0 )
|
||||
{
|
||||
parse_menumusic( );
|
||||
}
|
||||
required_string("#Menu Music End");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+300
-231
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
void gamesnd_parse_soundstbl(); // Loads in general game sounds from sounds.tbl
|
||||
void gamesnd_init_sounds(); // initializes the Snds[] and Snds_iface[] array
|
||||
void gamesnd_init_sounds(); // Initializes the Snds and Snds_iface STL vectors
|
||||
void gamesnd_close(); // close out gamesnd... only call from game_shutdown()!
|
||||
void gamesnd_load_gameplay_sounds();
|
||||
void gamesnd_unload_gameplay_sounds();
|
||||
@@ -37,242 +37,311 @@ void parse_sound(char* tag, int *idx_dest, char* object_name);
|
||||
// this is a callback, so it needs to be a real function
|
||||
void common_play_highlight_sound();
|
||||
|
||||
|
||||
// match original values by default, grow from this
|
||||
#define MIN_GAME_SOUNDS 202
|
||||
#define MIN_INTERFACE_SOUNDS 70
|
||||
|
||||
extern SCP_vector<game_snd> Snds;
|
||||
extern SCP_vector<game_snd> Snds_iface;
|
||||
|
||||
/**
|
||||
* symbolic names for misc. game sounds.
|
||||
*
|
||||
* The order here must match the order in sounds.tbl
|
||||
*
|
||||
* INSTRUCTIONS FOR ADDING A NEW SOUND:
|
||||
* Add interface (ie non-gameplay) sounds to the end of the interface list of sounds.
|
||||
* Add gameplay sounds to the correct portion of the gameplay sounds section (ie Misc, Weapons, or Ship).
|
||||
*
|
||||
* Then add a symbolic name to the appropriate position in the enum below
|
||||
* and add an entry to sounds.tbl. If there is no .wav file for the sound yet, specify sound_hook.wav in sounds.tbl.
|
||||
*/
|
||||
enum GameSoundsIndex {
|
||||
SND_MISSILE_TRACKING = 0, //!< Missle tracking to acquire a lock (looped)
|
||||
SND_MISSILE_LOCK = 1, //!< Missle lock (non-looping)
|
||||
SND_PRIMARY_CYCLE = 2, //!< cycle primary weapon
|
||||
SND_SECONDARY_CYCLE = 3, //!< cycle secondary weapon
|
||||
SND_ENGINE = 4, //!< engine sound (as heard in cockpit)
|
||||
SND_CARGO_REVEAL = 5, //!< cargo revealed
|
||||
SND_DEATH_ROLL = 6, //!< ship death roll
|
||||
SND_SHIP_EXPLODE_1 = 7, //!< ship explosion 1
|
||||
SND_TARGET_ACQUIRE = 8, //!< target acquried
|
||||
SND_ENERGY_ADJUST = 9, //!< energy level change success
|
||||
SND_ENERGY_ADJUST_FAIL = 10, //!< energy level change fail
|
||||
SND_ENERGY_TRANS = 11, //!< energy transfer success
|
||||
SND_ENERGY_TRANS_FAIL = 12, //!< energy transfer fail
|
||||
SND_FULL_THROTTLE = 13, //!< set full throttle
|
||||
SND_ZERO_THROTTLE = 14, //!< set zero throttle
|
||||
SND_THROTTLE_UP = 15, //!< set 1/3 or 2/3 throttle (up)
|
||||
SND_THROTTLE_DOWN = 16, //!< set 1/3 or 2/3 throttle (down)
|
||||
SND_DOCK_APPROACH = 17, //!< dock approach retros
|
||||
SND_DOCK_ATTACH = 18, //!< dock attach
|
||||
SND_DOCK_DETACH = 19, //!< dock detach
|
||||
SND_DOCK_DEPART = 20, //!< dock depart retros
|
||||
SND_ABURN_ENGAGE = 21, //!< afterburner engage
|
||||
SND_ABURN_LOOP = 22, //!< afterburner burn sound (looped)
|
||||
SND_VAPORIZED = 23, //!< Destroyed by a beam (vaporized)
|
||||
SND_ABURN_FAIL = 24, //!< afterburner fail (no fuel when aburn pressed)
|
||||
SND_HEATLOCK_WARN = 25, //!< heat-seeker launch warning
|
||||
SND_OUT_OF_MISSLES = 26, //!< tried to fire a missle when none are left
|
||||
SND_OUT_OF_WEAPON_ENERGY = 27, //!< tried to fire lasers when not enough energy left
|
||||
SND_TARGET_FAIL = 28, //!< target fail sound (i.e. press targeting key, but nothing happens)
|
||||
SND_SQUADMSGING_ON = 29, //!< squadmate message menu appears
|
||||
SND_SQUADMSGING_OFF = 30, //!< squadmate message menu disappears
|
||||
SND_DEBRIS = 31, //!< debris sound (persistant, looping)
|
||||
SND_SUBSYS_DIE_1 = 32, //!< subsystem gets destroyed on player ship
|
||||
SND_MISSILE_START_LOAD = 33, //!< missle start load (during rearm/repair)
|
||||
SND_MISSILE_LOAD = 34, //!< missle load (during rearm/repair)
|
||||
SND_SHIP_REPAIR = 35, //!< ship is being repaired (during rearm/repair)
|
||||
SND_PLAYER_HIT_LASER = 36, //!< player ship is hit by laser fire
|
||||
SND_PLAYER_HIT_MISSILE = 37, //!< player ship is hit by missile
|
||||
SND_CMEASURE_CYCLE = 38, //!< countermeasure cycle
|
||||
SND_SHIELD_HIT = 39, //!< shield hit
|
||||
SND_SHIELD_HIT_YOU = 40, //!< player shield is hit
|
||||
SND_GAME_MOUSE_CLICK = 41, //!< mouse click
|
||||
SND_ASPECTLOCK_WARN = 42, //!< aspect launch warning
|
||||
SND_SHIELD_XFER_OK = 43, //!< shield quadrant transfer successful
|
||||
SND_ENGINE_WASH = 44, //!< Engine wash (looped)
|
||||
SND_WARP_IN = 45, //!< warp hole opening up for arriving
|
||||
SND_WARP_OUT = 46, //!< warp hole opening up for departing (Same as warp in for now)
|
||||
SND_PLAYER_WARP_FAIL = 47, //!< player warp has failed
|
||||
SND_STATIC = 48, //!< hud gauge static
|
||||
SND_SHIP_EXPLODE_2 = 49, //!< ship explosion 2
|
||||
SND_PLAYER_WARP_OUT = 50, //!< ship is warping out in 3rd person
|
||||
SND_SHIP_SHIP_HEAVY = 51, //!< heavy ship-ship collide sound
|
||||
SND_SHIP_SHIP_LIGHT = 52, //!< light ship-ship collide sound
|
||||
SND_SHIP_SHIP_SHIELD = 53, //!< shield ship-ship collide overlay sound
|
||||
SND_THREAT_FLASH = 54, //!< missile threat indicator flashes
|
||||
SND_PROXIMITY_WARNING = 55, //!< proximity warning (heat seeker)
|
||||
SND_PROXIMITY_ASPECT_WARNING = 56, //!< proximity warning (aspect)
|
||||
SND_DIRECTIVE_COMPLETE = 57, //!< directive complete
|
||||
SND_SUBSYS_EXPLODE = 58, //!< other ship subsystem destroyed
|
||||
SND_CAPSHIP_EXPLODE = 59, //!< captial ship explosion
|
||||
SND_CAPSHIP_SUBSYS_EXPLODE = 60, //!< captial ship subsystem destroyed
|
||||
SND_LARGESHIP_WARPOUT = 61, //!< large ship warps out
|
||||
SND_ASTEROID_EXPLODE_LARGE = 62, //!< large asteroid blows up
|
||||
SND_ASTEROID_EXPLODE_SMALL = 63, //!< small asteroid blows up
|
||||
SND_CUE_VOICE = 64, //!< sound to indicate voice is about to start
|
||||
SND_END_VOICE = 65, //!< sound to indicate voice has ended
|
||||
SND_CARGO_SCAN = 66, //!< cargo scanning (looped)
|
||||
SND_WEAPON_FLYBY = 67, //!< weapon flyby sound
|
||||
SND_ASTEROID = 68, //!< asteroid sound (persistant, looped)
|
||||
SND_CAPITAL_WARP_IN = 69, //!< capital warp hole opening
|
||||
SND_CAPITAL_WARP_OUT = 70, //!< capital warp hole closing
|
||||
SND_ENGINE_LOOP_LARGE = 71, //!< LARGE engine ambient
|
||||
SND_SUBSPACE_LEFT_CHANNEL = 72, //!< subspace ambient sound (left channel) (looped)
|
||||
SND_SUBSPACE_RIGHT_CHANNEL = 73, //!< subspace ambient sound (right channel) (looped)
|
||||
SND_MISSILE_EVADED_POPUP = 74, //!< "evaded" HUD popup
|
||||
SND_ENGINE_LOOP_HUGE = 75, //!< HUGE engine ambient
|
||||
//Weapons section
|
||||
SND_LIGHT_LASER_FIRE = 76, //!< SD-4 Sidearm laser fired
|
||||
SND_LIGHT_LASER_IMPACT = 77, //!< DR-2 Scalpel fired
|
||||
SND_HVY_LASER_FIRE = 78, //!< Flail II fired
|
||||
SND_HVY_LASER_IMPACT = 79, //!< Prometheus R laser fired
|
||||
SND_MASSDRV_FIRED = 80, //!< Prometheus S laser fired
|
||||
SND_MASSDRV_IMPACT = 81, //!< GTW-66 Newton Cannon fired
|
||||
SND_FLAIL_FIRED = 82, //!< UD-8 Kayser Laser fired
|
||||
SND_FLAIL_IMPACT = 83, //!< GTW-19 Circe laser fired
|
||||
SND_NEUTRON_FLUX_FIRED = 84, //!< GTW-83 Lich laser fired
|
||||
SND_NEUTRON_FLUX_IMPACT = 85, //!< Laser impact
|
||||
SND_DEBUG_LASER_FIRED = 86, //!< Subach-HLV Vasudan laser
|
||||
SND_ROCKEYE_FIRED = 87, //!< rockeye missile launch
|
||||
SND_MISSILE_IMPACT1 = 88, //!< missile impact 1
|
||||
SND_MAG_MISSILE_LAUNCH = 89, //!< mag pulse missile launch
|
||||
SND_FURY_MISSILE_LAUNCH = 90, //!< fury missile launch
|
||||
SND_SHRIKE_MISSILE_LAUNCH = 91, //!< shrike missile launch
|
||||
SND_ANGEL_MISSILE_LAUNCH = 92, //!< angel fire missile launch
|
||||
SND_CLUSTER_MISSILE_LAUNCH = 93, //!< cluster bomb launch
|
||||
SND_CLUSTERB_MISSILE_LAUNCH = 94, //!< cluster baby bomb launch
|
||||
SND_STILETTO_MISSILE_LAUNCH = 95, //!< stiletto bomb launch
|
||||
SND_TSUNAMI_MISSILE_LAUNCH = 96, //!< tsunami bomb launch
|
||||
SND_HARBINGER_MISSILE_LAUNCH = 97, //!< harbinger bomb launch
|
||||
SND_MEGAWOKKA_MISSILE_LAUNCH = 98, //!< mega wokka launch
|
||||
SND_CMEASURE1_LAUNCH = 99, //!< countermeasure 1 launch
|
||||
SND_SHIVAN_LIGHT_LASER_FIRE = 100,//!< Shivan light laser
|
||||
SND_SHOCKWAVE_EXPLODE = 101,//!< shockwave ignition
|
||||
SND_SWARM_MISSILE_LAUNCH = 102,//!< swarm missile sound
|
||||
SND_UNDEFINED_103 = 103,//!< Shivan heavy laser
|
||||
SND_UNDEFINED_104 = 104,//!< Vasudan SuperCap engine
|
||||
SND_UNDEFINED_105 = 105,//!< Shivan SuperCap engine
|
||||
SND_UNDEFINED_106 = 106,//!< Terran SuperCap engine
|
||||
SND_UNDEFINED_107 = 107,//!< Vasudan light laser fired
|
||||
SND_UNDEFINED_108 = 108,//!< Shivan heavy laser
|
||||
SND_SHOCKWAVE_IMPACT = 109,//!< shockwave impact
|
||||
SND_UNDEFINED_110 = 110,//!< TERRAN TURRET 1
|
||||
SND_UNDEFINED_111 = 111,//!< TERRAN TURRET 2
|
||||
SND_UNDEFINED_112 = 112,//!< VASUDAN TURRET 1
|
||||
SND_UNDEFINED_113 = 113,//!< VASUDAN TURRET 2
|
||||
SND_UNDEFINED_114 = 114,//!< SHIVAN TURRET 1
|
||||
SND_TARG_LASER_LOOP = 115,//!< targeting laser loop sound
|
||||
SND_FLAK_FIRE = 116,//!< Flak Gun Launch
|
||||
SND_SHIELD_BREAKER = 117,//!< Flak Gun Impact
|
||||
SND_EMP_MISSILE = 118,//!< EMP Missle
|
||||
SND_AUTOCANNON_LOOP = 119,//!< Escape Pod Drone
|
||||
SND_AUTOCANNON_SHOT = 120,//!< Beam Hit 1
|
||||
SND_BEAM_LOOP = 121,//!< beam loop
|
||||
SND_BEAM_UP = 122,//!< beam power up
|
||||
SND_BEAM_DOWN = 123,//!< beam power down
|
||||
SND_BEAM_SHOT = 124,//!< Beam shot 1
|
||||
SND_BEAM_VAPORIZE = 125,//!< Beam shot 2
|
||||
//Ship Engine Sounds section
|
||||
SND_TERRAN_FIGHTER_ENG = 126,//!< Terran fighter engine
|
||||
SND_TERRAN_BOMBER_ENG = 127,//!< Terran bomber engine
|
||||
SND_TERRAN_CAPITAL_ENG = 128,//!< Terran cruiser engine
|
||||
SND_SPECIESB_FIGHTER_ENG = 129,//!< Vasudan fighter engine
|
||||
SND_SPECIESB_BOMBER_ENG = 130,//!< Vasudan bomber engine
|
||||
SND_SPECIESB_CAPITAL_ENG = 131,//!< Vasudan cruiser engine
|
||||
SND_SHIVAN_FIGHTER_ENG = 132,//!< Shivan fighter engine
|
||||
SND_SHIVAN_BOMBER_ENG = 133,//!< Shivan bomber engine
|
||||
SND_SHIVAN_CAPITAL_ENG = 134,//!< Shivan cruiser engine
|
||||
SND_REPAIR_SHIP_ENG = 135,//!< Repair ship beacon/engine sound
|
||||
SND_UNDEFINED_136 = 136,//!< Terran capital engine
|
||||
SND_UNDEFINED_137 = 137,//!< Vasudan capital engine
|
||||
SND_UNDEFINED_138 = 138,//!< Shivan capital engine
|
||||
// Electrical arc sound fx on the debris pieces
|
||||
SND_DEBRIS_ARC_01 = 139,//!< 0.10 second spark sound effect
|
||||
SND_DEBRIS_ARC_02 = 140,//!< 0.25 second spark sound effect
|
||||
SND_DEBRIS_ARC_03 = 141,//!< 0.50 second spark sound effect
|
||||
SND_DEBRIS_ARC_04 = 142,//!< 0.75 second spark sound effect
|
||||
SND_DEBRIS_ARC_05 = 143,//!< 1.00 second spark sound effect
|
||||
// Beam Sounds
|
||||
SND_UNDEFINED_144 = 144,//!< LTerSlash beam loop
|
||||
SND_UNDEFINED_145 = 145,//!< TerSlash beam loop
|
||||
SND_UNDEFINED_146 = 146,//!< SGreen beam loop
|
||||
SND_UNDEFINED_147 = 147,//!< BGreen beem loop
|
||||
SND_UNDEFINED_148 = 148,//!< BFGreen been loop
|
||||
SND_UNDEFINED_149 = 149,//!< Antifighter beam loop
|
||||
SND_UNDEFINED_150 = 150,//!< 1 sec warm up
|
||||
SND_UNDEFINED_151 = 151,//!< 1.5 sec warm up
|
||||
SND_UNDEFINED_152 = 152,//!< 2.5 sec warm up
|
||||
SND_UNDEFINED_153 = 153,//!< 3 sec warm up
|
||||
SND_UNDEFINED_154 = 154,//!< 3.5 sec warm up
|
||||
SND_UNDEFINED_155 = 155,//!< 5 sec warm up
|
||||
SND_UNDEFINED_156 = 156,//!< LTerSlash warm down
|
||||
SND_UNDEFINED_157 = 157,//!< TerSlash warm down
|
||||
SND_UNDEFINED_158 = 158,//!< SGreen warm down
|
||||
SND_UNDEFINED_159 = 159,//!< BGreen warm down
|
||||
SND_UNDEFINED_160 = 160,//!< BFGreen warm down
|
||||
SND_UNDEFINED_161 = 161,//!< T_AntiFtr warm down
|
||||
|
||||
// symbolic names for misc. game sounds. The order here must match the order in
|
||||
// sounds.tbl
|
||||
//
|
||||
// INSTRUCTIONS FOR ADDING A NEW SOUND:
|
||||
//
|
||||
// Add interface (ie non-gameplay) sounds to the end of the interface list of sounds.
|
||||
// Add gameplay sounds to the correct portion of the gameplay sounds section (ie Misc,
|
||||
// Weapons, or Ship).
|
||||
//
|
||||
// Then add a symbolic name to the appropriate position in the #define list below
|
||||
// and add an entry to sounds.tbl. If there is no .wav file for the sound yet,
|
||||
// specify sound_hook.wav in sounds.tbl.
|
||||
//
|
||||
//
|
||||
SND_COPILOT = 162,//!< copilot (SCP)
|
||||
SND_UNDEFINED_163 = 163,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_164 = 164,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_165 = 165,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_166 = 166,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_167 = 167,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_168 = 168,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_169 = 169,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_170 = 170,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_171 = 171,//!< (Empty in Retail)
|
||||
SND_UNDEFINED_172 = 172,//!< (Empty in Retail)
|
||||
SND_SUPERNOVA_1 = 173,//!< SuperNova (distant)
|
||||
SND_SUPERNOVA_2 = 174,//!< SuperNova (shockwave)
|
||||
SND_UNDEFINED_175 = 175,//!< Shivan large engine
|
||||
SND_UNDEFINED_176 = 176,//!< Shivan large engine
|
||||
SND_UNDEFINED_177 = 177,//!< SRed beam loop
|
||||
SND_UNDEFINED_178 = 178,//!< LRed beam loop
|
||||
SND_UNDEFINED_179 = 179,//!< Antifighter beam loop
|
||||
SND_LIGHTNING_1 = 180,//!< Thunder 1 sound in neblua
|
||||
SND_LIGHTNING_2 = 181,//!< Thunder 2 sound in neblua
|
||||
SND_UNDEFINED_182 = 182,//!< 1 sec warm up
|
||||
SND_UNDEFINED_183 = 183,//!< 1.5 sec warm up
|
||||
SND_UNDEFINED_184 = 184,//!< 3 sec warm up
|
||||
SND_UNDEFINED_185 = 185,//!< Shivan Commnode
|
||||
SND_UNDEFINED_186 = 186,//!< Volition PirateShip
|
||||
SND_UNDEFINED_187 = 187,//!< SRed warm down
|
||||
SND_UNDEFINED_188 = 188,//!< LRed warm down
|
||||
SND_UNDEFINED_189 = 189,//!< AntiFtr warm down
|
||||
SND_UNDEFINED_190 = 190,//!< Instellation 1
|
||||
SND_UNDEFINED_191 = 191,//!< Instellation 2
|
||||
SND_UNDEFINED_192 = 192,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_193 = 193,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_194 = 194,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_195 = 195,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_196 = 196,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_197 = 197,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_198 = 198,//!< (Undefined in Retail)
|
||||
SND_UNDEFINED_199 = 199,//!< (Undefined in Retail)
|
||||
|
||||
//---------------------------------------------------
|
||||
// Misc Sounds
|
||||
//---------------------------------------------------
|
||||
#define SND_MISSILE_TRACKING 0
|
||||
#define SND_MISSILE_LOCK 1
|
||||
#define SND_PRIMARY_CYCLE 2
|
||||
#define SND_SECONDARY_CYCLE 3
|
||||
#define SND_ENGINE 4
|
||||
#define SND_CARGO_REVEAL 5
|
||||
#define SND_DEATH_ROLL 6
|
||||
#define SND_SHIP_EXPLODE_1 7
|
||||
#define SND_TARGET_ACQUIRE 8
|
||||
#define SND_ENERGY_ADJUST 9
|
||||
#define SND_ENERGY_ADJUST_FAIL 10
|
||||
#define SND_ENERGY_TRANS 11
|
||||
#define SND_ENERGY_TRANS_FAIL 12
|
||||
#define SND_FULL_THROTTLE 13
|
||||
#define SND_ZERO_THROTTLE 14
|
||||
#define SND_THROTTLE_UP 15
|
||||
#define SND_THROTTLE_DOWN 16
|
||||
#define SND_DOCK_APPROACH 17
|
||||
#define SND_DOCK_ATTACH 18
|
||||
#define SND_DOCK_DETACH 19
|
||||
#define SND_DOCK_DEPART 20
|
||||
#define SND_ABURN_ENGAGE 21
|
||||
#define SND_ABURN_LOOP 22
|
||||
#define SND_VAPORIZED 23
|
||||
#define SND_ABURN_FAIL 24
|
||||
#define SND_HEATLOCK_WARN 25
|
||||
#define SND_OUT_OF_MISSLES 26
|
||||
#define SND_OUT_OF_WEAPON_ENERGY 27
|
||||
#define SND_TARGET_FAIL 28
|
||||
#define SND_SQUADMSGING_ON 29
|
||||
#define SND_SQUADMSGING_OFF 30
|
||||
#define SND_DEBRIS 31
|
||||
#define SND_SUBSYS_DIE_1 32
|
||||
#define SND_MISSILE_START_LOAD 33
|
||||
#define SND_MISSILE_LOAD 34
|
||||
#define SND_SHIP_REPAIR 35
|
||||
#define SND_PLAYER_HIT_LASER 36
|
||||
#define SND_PLAYER_HIT_MISSILE 37
|
||||
#define SND_CMEASURE_CYCLE 38
|
||||
#define SND_SHIELD_HIT 39
|
||||
#define SND_SHIELD_HIT_YOU 40
|
||||
#define SND_GAME_MOUSE_CLICK 41
|
||||
#define SND_ASPECTLOCK_WARN 42
|
||||
#define SND_SHIELD_XFER_OK 43
|
||||
#define SND_ENGINE_WASH 44
|
||||
#define SND_WARP_IN 45
|
||||
#define SND_WARP_OUT 46 // Same as warp in for now
|
||||
#define SND_PLAYER_WARP_FAIL 47
|
||||
#define SND_STATIC 48
|
||||
#define SND_SHIP_EXPLODE_2 49
|
||||
#define SND_PLAYER_WARP_OUT 50
|
||||
#define SND_SHIP_SHIP_HEAVY 51
|
||||
#define SND_SHIP_SHIP_LIGHT 52
|
||||
#define SND_SHIP_SHIP_SHIELD 53
|
||||
#define SND_THREAT_FLASH 54
|
||||
#define SND_PROXIMITY_WARNING 55
|
||||
#define SND_PROXIMITY_ASPECT_WARNING 56
|
||||
#define SND_DIRECTIVE_COMPLETE 57
|
||||
#define SND_SUBSYS_EXPLODE 58
|
||||
#define SND_CAPSHIP_EXPLODE 59
|
||||
#define SND_CAPSHIP_SUBSYS_EXPLODE 60
|
||||
#define SND_LARGESHIP_WARPOUT 61
|
||||
#define SND_ASTEROID_EXPLODE_LARGE 62
|
||||
#define SND_ASTEROID_EXPLODE_SMALL 63
|
||||
#define SND_CUE_VOICE 64
|
||||
#define SND_END_VOICE 65
|
||||
#define SND_CARGO_SCAN 66
|
||||
#define SND_WEAPON_FLYBY 67
|
||||
#define SND_ASTEROID 68
|
||||
#define SND_CAPITAL_WARP_IN 69
|
||||
#define SND_CAPITAL_WARP_OUT 70
|
||||
#define SND_ENGINE_LOOP_LARGE 71
|
||||
#define SND_SUBSPACE_LEFT_CHANNEL 72
|
||||
#define SND_SUBSPACE_RIGHT_CHANNEL 73
|
||||
#define SND_MISSILE_EVADED_POPUP 74
|
||||
#define SND_ENGINE_LOOP_HUGE 75
|
||||
SND_BALLISTIC_START_LOAD = 200,//!< (SCP)
|
||||
SND_BALLISTIC_LOAD = 201,//!< (SCP)
|
||||
|
||||
// Weapon sounds
|
||||
#define SND_LIGHT_LASER_FIRE 76
|
||||
#define SND_LIGHT_LASER_IMPACT 77
|
||||
#define SND_HVY_LASER_FIRE 78
|
||||
#define SND_HVY_LASER_IMPACT 79
|
||||
#define SND_MASSDRV_FIRED 80
|
||||
#define SND_MASSDRV_IMPACT 81
|
||||
#define SND_FLAIL_FIRED 82
|
||||
#define SND_FLAIL_IMPACT 83
|
||||
#define SND_NEUTRON_FLUX_FIRED 84
|
||||
#define SND_NEUTRON_FLUX_IMPACT 85
|
||||
#define SND_DEBUG_LASER_FIRED 86
|
||||
#define SND_ROCKEYE_FIRED 87
|
||||
#define SND_MISSILE_IMPACT1 88
|
||||
#define SND_MAG_MISSILE_LAUNCH 89
|
||||
#define SND_FURY_MISSILE_LAUNCH 90
|
||||
#define SND_SHRIKE_MISSILE_LAUNCH 91
|
||||
#define SND_ANGEL_MISSILE_LAUNCH 92
|
||||
#define SND_CLUSTER_MISSILE_LAUNCH 93
|
||||
#define SND_CLUSTERB_MISSILE_LAUNCH 94
|
||||
#define SND_STILETTO_MISSILE_LAUNCH 95
|
||||
#define SND_TSUNAMI_MISSILE_LAUNCH 96
|
||||
#define SND_HARBINGER_MISSILE_LAUNCH 97
|
||||
#define SND_MEGAWOKKA_MISSILE_LAUNCH 98
|
||||
#define SND_CMEASURE1_LAUNCH 99
|
||||
#define SND_SHIVAN_LIGHT_LASER_FIRE 100
|
||||
#define SND_SHOCKWAVE_EXPLODE 101
|
||||
#define SND_SWARM_MISSILE_LAUNCH 102
|
||||
#define SND_SHOCKWAVE_IMPACT 109
|
||||
/**
|
||||
* Keep this below all defined enum values
|
||||
*/
|
||||
MIN_GAME_SOUNDS = 202
|
||||
};
|
||||
|
||||
#define SND_TARG_LASER_LOOP 115
|
||||
#define SND_FLAK_FIRE 116
|
||||
#define SND_SHIELD_BREAKER 117
|
||||
#define SND_EMP_MISSILE 118
|
||||
#define SND_AUTOCANNON_LOOP 119
|
||||
#define SND_AUTOCANNON_SHOT 120
|
||||
#define SND_BEAM_LOOP 121
|
||||
#define SND_BEAM_UP 122
|
||||
#define SND_BEAM_DOWN 123
|
||||
#define SND_BEAM_SHOT 124
|
||||
#define SND_BEAM_VAPORIZE 125
|
||||
/**
|
||||
* Interface sounds
|
||||
*/
|
||||
enum InterfaceSoundsIndex {
|
||||
SND_IFACE_MOUSE_CLICK =0, //!< mouse click
|
||||
SND_ICON_PICKUP =1, //!< pick up a ship icon (Empty in Retail)
|
||||
SND_ICON_DROP_ON_WING =2, //!< drop a ship icon on a wing slot
|
||||
SND_ICON_DROP =3, //!< drop a ship icon back to the list
|
||||
SND_SCREEN_MODE_PRESSED =4, //!< press briefing, ship selection or weapons bar (top-left)
|
||||
SND_SWITCH_SCREENS =5, //!< Switching to a new screen, but not commit
|
||||
SND_HELP_PRESSED =6, //!< help pressed
|
||||
SND_COMMIT_PRESSED =7, //!< commit pressed
|
||||
SND_PREV_NEXT_PRESSED =8, //!< prev/next pressed
|
||||
SND_SCROLL =9, //!< scroll pressed (and scroll)
|
||||
SND_GENERAL_FAIL =10,//!< general failure sound for any event
|
||||
SND_SHIP_ICON_CHANGE =11,//!< ship animation starts (ie text and ship first appear)
|
||||
SND_MAIN_HALL_AMBIENT =12,//!< ambient sound for the Terran main hall (looping)
|
||||
SND_BTN_SLIDE =13,//!< ambient sound for the Vasudan main hall (looping)
|
||||
SND_BRIEF_STAGE_CHG =14,//!< brief stage change
|
||||
SND_BRIEF_STAGE_CHG_FAIL =15,//!< brief stage change fail
|
||||
SND_BRIEF_ICON_SELECT =16,//!< selet brief icon
|
||||
SND_USER_OVER =17,//!< user_over (mouse over a control)
|
||||
SND_USER_SELECT =18,//!< user_click (mouse selects a control)
|
||||
SND_RESET_PRESSED =19,//!< reset (or similar button) pressed
|
||||
SND_BRIEF_TEXT_WIPE =20,//!< briefing text wipe
|
||||
SND_VASUDAN_PA_1 =21,//!< main hall - elevator
|
||||
SND_WEAPON_ANIM_START =22,//!< weapon animation starts
|
||||
SND_MAIN_HALL_DOOR_OPEN =23,//!< door in main hall opens
|
||||
SND_MAIN_HALL_DOOR_CLOSE =24,//!< door in main hall closes
|
||||
SND_GLOW_OPEN =25,//!< glow in main hall opens
|
||||
SND_VASUDAN_PA_2 =26,//!< main hall - crane 1
|
||||
SND_AMBIENT_MENU =27,//!< ambient sound for menus off the main hall (looping)
|
||||
SND_POPUP_APPEAR =28,//!< popup dialog box appeared
|
||||
SND_POPUP_DISAPPEAR =29,//!< popup dialog box goes away
|
||||
SND_VOICE_SLIDER_CLIP =30,//!< voice clip played when volume slider changes
|
||||
SND_VASUDAN_PA_3 =31,//!< main hall - crane 2
|
||||
SND_MAIN_HALL_GET_PEPSI =32,//!< main hall options - mouse on
|
||||
SND_MAIN_HALL_LIFT_UP =33,//!< main hall options - mouse off
|
||||
SND_MAIN_HALL_WELD1 =34,//!< main hall tech room - mouse on
|
||||
SND_MAIN_HALL_WELD2 =35,//!< main hall tech room - mouse off
|
||||
SND_MAIN_HALL_WELD3 =36,//!< main hall exit open
|
||||
SND_MAIN_HALL_WELD4 =37,//!< main hall exit close
|
||||
SND_MAIN_HALL_INT1 =38,//!< main hall random intercom 1
|
||||
SND_MAIN_HALL_INT2 =39,//!< main hall random intercom 2
|
||||
SND_MAIN_HALL_INT3 =40,//!< main hall random intercom 3
|
||||
SND_ICON_HIGHLIGHT =41,//!< spinning highlight in briefing
|
||||
SND_BRIEFING_STATIC =42,//!< static in a briefing stage cut
|
||||
SND_MAIN_HALL2_CRANE1_1 =43,//!< main hall campaign - mouse on
|
||||
SND_MAIN_HALL2_CRANE1_2 =44,//!< main hall campaign - mouse off
|
||||
SND_MAIN_HALL2_CRANE2_1 =45,//!< vasudan hall - hatch open
|
||||
SND_MAIN_HALL2_CRANE2_2 =46,//!< vasudan hall - hatch close
|
||||
SND_MAIN_HALL2_CAR1 =47,//!< vasudan hall - roll open
|
||||
SND_MAIN_HALL2_CAR2 =48,//!< vasudan hall - roll close
|
||||
SND_MAIN_HALL2_INT1 =49,//!< vasudan hall - lift up
|
||||
SND_MAIN_HALL2_INT2 =50,//!< vasudan hall - lift down
|
||||
SND_MAIN_HALL2_INT3 =51,//!< vasudan hall - glow on
|
||||
SND_INTERFACE_UNDEFINED_52 =52,//!< vasudan hall - glow off
|
||||
SND_INTERFACE_UNDEFINED_53 =53,//!< vasudan hall - skiff loop
|
||||
SND_INTERFACE_UNDEFINED_54 =54,//!< vasudan hall - screen on
|
||||
SND_INTERFACE_UNDEFINED_55 =55,//!< vasudan hall - screen off
|
||||
SND_INTERFACE_UNDEFINED_56 =56,//!< vasudan hall - vasudan greeting
|
||||
SND_INTERFACE_UNDEFINED_57 =57,//!< vasudan hall - vasudan bye
|
||||
SND_INTERFACE_UNDEFINED_58 =58,//!< vasudan hall - vasudan pa 1
|
||||
SND_INTERFACE_UNDEFINED_59 =59,//!< vasudan hall - vasudan pa 2
|
||||
SND_INTERFACE_UNDEFINED_60 =60,//!< vasudan hall - vasudan pa 3
|
||||
SND_VASUDAN_BUP =61,//!< bup bup bup-bup bup bup
|
||||
SND_INTERFACE_UNDEFINED_62 =62,//!< thankyou
|
||||
SND_INTERFACE_UNDEFINED_63 =62,//!< vasudan hall - exit open
|
||||
SND_INTERFACE_UNDEFINED_64 =62,//!< vasudan hall - exit close
|
||||
|
||||
// Ship engine sounds
|
||||
#define SND_TERRAN_FIGHTER_ENG 126
|
||||
#define SND_TERRAN_BOMBER_ENG 127
|
||||
#define SND_TERRAN_CAPITAL_ENG 128
|
||||
#define SND_SPECIESB_FIGHTER_ENG 129
|
||||
#define SND_SPECIESB_BOMBER_ENG 130
|
||||
#define SND_SPECIESB_CAPITAL_ENG 131
|
||||
#define SND_SHIVAN_FIGHTER_ENG 132
|
||||
#define SND_SHIVAN_BOMBER_ENG 133
|
||||
#define SND_SHIVAN_CAPITAL_ENG 134
|
||||
#define SND_REPAIR_SHIP_ENG 135
|
||||
/**
|
||||
* Keep this below all defined enum values
|
||||
*/
|
||||
MIN_INTERFACE_SOUNDS =70 //!< MIN_INTERFACE_SOUNDS
|
||||
};
|
||||
|
||||
// Debris electric arcing sounds
|
||||
#define SND_DEBRIS_ARC_01 139 // 0.10 second spark sound effect (3d sound)
|
||||
#define SND_DEBRIS_ARC_02 140 // 0.25 second spark sound effect (3d sound)
|
||||
#define SND_DEBRIS_ARC_03 141 // 0.50 second spark sound effect (3d sound)
|
||||
#define SND_DEBRIS_ARC_04 142 // 0.75 second spark sound effect (3d sound)
|
||||
#define SND_DEBRIS_ARC_05 143 // 1.00 second spark sound effect (3d sound)
|
||||
|
||||
// copilot
|
||||
#define SND_COPILOT 162
|
||||
|
||||
// supernova 1 and supernova 2
|
||||
#define SND_SUPERNOVA_1 173
|
||||
#define SND_SUPERNOVA_2 174
|
||||
|
||||
// lightning sounds
|
||||
#define SND_LIGHTNING_1 180
|
||||
#define SND_LIGHTNING_2 181
|
||||
|
||||
// added for ballistic primaries - Goober5000
|
||||
#define SND_BALLISTIC_START_LOAD 200
|
||||
#define SND_BALLISTIC_LOAD 201
|
||||
|
||||
//---------------------------------------------------
|
||||
// Interface sounds
|
||||
//---------------------------------------------------
|
||||
#define SND_IFACE_MOUSE_CLICK 0
|
||||
#define SND_ICON_PICKUP 1
|
||||
#define SND_ICON_DROP_ON_WING 2
|
||||
#define SND_ICON_DROP 3
|
||||
#define SND_SCREEN_MODE_PRESSED 4
|
||||
#define SND_SWITCH_SCREENS 5
|
||||
#define SND_HELP_PRESSED 6
|
||||
#define SND_COMMIT_PRESSED 7
|
||||
#define SND_PREV_NEXT_PRESSED 8
|
||||
#define SND_SCROLL 9
|
||||
#define SND_GENERAL_FAIL 10
|
||||
#define SND_SHIP_ICON_CHANGE 11
|
||||
#define SND_MAIN_HALL_AMBIENT 12
|
||||
#define SND_BTN_SLIDE 13
|
||||
#define SND_BRIEF_STAGE_CHG 14
|
||||
#define SND_BRIEF_STAGE_CHG_FAIL 15
|
||||
#define SND_BRIEF_ICON_SELECT 16
|
||||
#define SND_USER_OVER 17
|
||||
#define SND_USER_SELECT 18
|
||||
#define SND_RESET_PRESSED 19
|
||||
#define SND_BRIEF_TEXT_WIPE 20
|
||||
#define SND_VASUDAN_PA_1 21 // vasudan pa 1
|
||||
#define SND_WEAPON_ANIM_START 22
|
||||
#define SND_MAIN_HALL_DOOR_OPEN 23
|
||||
#define SND_MAIN_HALL_DOOR_CLOSE 24
|
||||
#define SND_GLOW_OPEN 25
|
||||
#define SND_VASUDAN_PA_2 26 // vasudan pa 2
|
||||
#define SND_AMBIENT_MENU 27
|
||||
#define SND_POPUP_APPEAR 28
|
||||
#define SND_POPUP_DISAPPEAR 29
|
||||
#define SND_VOICE_SLIDER_CLIP 30
|
||||
#define SND_VASUDAN_PA_3 31 // vasudan pa 3
|
||||
#define SND_MAIN_HALL_GET_PEPSI 32
|
||||
#define SND_MAIN_HALL_LIFT_UP 33
|
||||
#define SND_MAIN_HALL_WELD1 34
|
||||
#define SND_MAIN_HALL_WELD2 35
|
||||
#define SND_MAIN_HALL_WELD3 36
|
||||
#define SND_MAIN_HALL_WELD4 37
|
||||
#define SND_MAIN_HALL_INT1 38 // random intercom message 1
|
||||
#define SND_MAIN_HALL_INT2 39 // random intercom message 2
|
||||
#define SND_MAIN_HALL_INT3 40 // random intercom message 3
|
||||
#define SND_ICON_HIGHLIGHT 41
|
||||
#define SND_BRIEFING_STATIC 42
|
||||
#define SND_MAIN_HALL2_CRANE1_1 43
|
||||
#define SND_MAIN_HALL2_CRANE1_2 44
|
||||
#define SND_MAIN_HALL2_CRANE2_1 45
|
||||
#define SND_MAIN_HALL2_CRANE2_2 46
|
||||
#define SND_MAIN_HALL2_CAR1 47
|
||||
#define SND_MAIN_HALL2_CAR2 48
|
||||
#define SND_MAIN_HALL2_INT1 49
|
||||
#define SND_MAIN_HALL2_INT2 50
|
||||
#define SND_MAIN_HALL2_INT3 51
|
||||
|
||||
#define SND_VASUDAN_BUP 61
|
||||
|
||||
#endif /* __GAMESND_H__ */
|
||||
#endif
|
||||
+116
-103
@@ -39,6 +39,8 @@ extern char* Default_post_vertex_shader;
|
||||
extern char* Default_fxaa_prepass_shader;
|
||||
extern char* Default_particle_vertex_shader;
|
||||
extern char* Default_particle_fragment_shader;
|
||||
extern char* Default_video_vertex_shader;
|
||||
extern char* Default_video_fragment_shader;
|
||||
//**********
|
||||
|
||||
//:PART 2:
|
||||
@@ -63,7 +65,9 @@ def_file Default_files[] =
|
||||
{ "post-v.sdr", Default_post_vertex_shader},
|
||||
{ "fxaapre-f.sdr", Default_fxaa_prepass_shader},
|
||||
{ "soft-v.sdr", Default_particle_vertex_shader},
|
||||
{ "soft-f.sdr", Default_particle_fragment_shader}
|
||||
{ "soft-f.sdr", Default_particle_fragment_shader},
|
||||
{ "video-v.sdr", Default_video_vertex_shader},
|
||||
{ "video-f.sdr", Default_video_fragment_shader}
|
||||
};
|
||||
|
||||
static int Num_default_files = sizeof(Default_files) / sizeof(def_file);
|
||||
@@ -1196,7 +1200,7 @@ char* Default_main_vertex_shader =
|
||||
"varying vec3 lNormal;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
|
||||
" gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
|
||||
" gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n"
|
||||
" gl_FrontColor = gl_Color;\n"
|
||||
" gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||
@@ -1219,11 +1223,8 @@ char* Default_main_vertex_shader =
|
||||
" #ifdef FLAG_FOG\n"
|
||||
" fogDist = clamp((gl_Position.z - gl_Fog.start) * 0.75 * gl_Fog.scale, 0.0, 1.0);\n"
|
||||
" #endif\n"
|
||||
" #ifdef __GLSL_CG_DATA_TYPES\n"
|
||||
" // Check necessary for ATI specific behavior\n"
|
||||
" gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);\n"
|
||||
" #endif\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char *Default_main_fragment_shader =
|
||||
"#ifdef FLAG_LIGHT\n"
|
||||
@@ -1431,7 +1432,7 @@ char *Default_main_fragment_shader =
|
||||
" #else\n"
|
||||
" gl_FragColor = fragmentColor;\n"
|
||||
" #endif\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char* Default_fxaa_vertex_shader =
|
||||
"#extension GL_EXT_gpu_shader4 : enable\n"
|
||||
@@ -1443,7 +1444,7 @@ char* Default_fxaa_vertex_shader =
|
||||
" gl_Position = gl_Vertex;\n"
|
||||
" v_rcpFrame = vec2(1.0/rt_w, 1.0/rt_h);\n"
|
||||
" v_pos = gl_Vertex.xy*0.5 + 0.5;\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char* Default_fxaa_fragment_shader =
|
||||
"#extension GL_EXT_gpu_shader4 : enable\n"
|
||||
@@ -1963,7 +1964,7 @@ char* Default_fxaa_fragment_shader =
|
||||
"noperspective varying vec2 v_pos;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = FxaaPixelShader(v_pos, tex0, v_rcpFrame, FXAA_QUALITY__SUBPIX, FXAA_QUALITY__EDGE_THRESHOLD, FXAA_QUALITY__EDGE_THRESHOLD_MIN);\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char *Default_blur_fragment_shader =
|
||||
"varying float blurSize;\n"
|
||||
@@ -1997,7 +1998,7 @@ char *Default_blur_fragment_shader =
|
||||
" }\n"
|
||||
"#endif\n"
|
||||
" gl_FragColor = sum;\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char *Default_brightpass_fragment_shader =
|
||||
"uniform sampler2D tex;\n"
|
||||
@@ -2012,7 +2013,7 @@ char *Default_brightpass_fragment_shader =
|
||||
" ColorOut -= 6.0;\n"
|
||||
" ColorOut /= (10.0 + ColorOut);\n"
|
||||
" gl_FragColor = ColorOut;\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char *Default_post_fragment_shader =
|
||||
"uniform sampler2D tex;\n"
|
||||
@@ -2126,7 +2127,7 @@ char *Default_post_fragment_shader =
|
||||
" #endif\n"
|
||||
" color_out.a = 1.0;\n"
|
||||
" gl_FragColor = color_out;\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char *Default_post_vertex_shader =
|
||||
"varying float blurSize;\n"
|
||||
@@ -2142,102 +2143,114 @@ char *Default_post_vertex_shader =
|
||||
" #ifdef __GLSL_CG_DATA_TYPES\n"
|
||||
" gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);\n"
|
||||
" #endif\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char* Default_fxaa_prepass_shader =
|
||||
"uniform sampler2D tex;\n"
|
||||
"void main() {\n"
|
||||
" vec4 color = texture2D(tex, gl_TexCoord[0].xy);\n"
|
||||
" gl_FragColor = vec4(color.rgb, dot(color.rgb, vec3(0.299, 0.587, 0.114)) );\n"
|
||||
"}\n";
|
||||
"}";
|
||||
|
||||
char* Default_particle_vertex_shader = "\
|
||||
attribute float radius_in; \n\
|
||||
\n\
|
||||
varying float radius; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
radius = radius_in; \n\
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0; \n\
|
||||
gl_Position = ftransform(); \n\
|
||||
gl_FrontColor = gl_Color; \n\
|
||||
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0); \n\
|
||||
\n\
|
||||
#ifdef __GLSL_CG_DATA_TYPES \n\
|
||||
// Check necessary for ATI specific behavior \n\
|
||||
gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex); \n\
|
||||
#endif \n\
|
||||
} \n\
|
||||
";
|
||||
char* Default_particle_vertex_shader =
|
||||
"attribute float radius_in;\n"
|
||||
"varying float radius;\n"
|
||||
"#ifdef FLAG_DISTORTION\n"
|
||||
"attribute float offset_in;\n"
|
||||
"varying float offset_out;\n"
|
||||
"#endif\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" radius = radius_in;\n"
|
||||
" #ifdef FLAG_DISTORTION\n"
|
||||
" offset_out = offset_in;\n"
|
||||
" #endif\n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
|
||||
" gl_Position = ftransform();\n"
|
||||
" gl_FrontColor = gl_Color;\n"
|
||||
" gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||
" #ifdef __GLSL_CG_DATA_TYPES\n"
|
||||
" // Check necessary for ATI specific behavior\n"
|
||||
" gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);\n"
|
||||
" #endif\n"
|
||||
"}";
|
||||
|
||||
char* Default_particle_fragment_shader = "\
|
||||
uniform sampler2D baseMap; \n\
|
||||
uniform sampler2D depthMap; \n\
|
||||
uniform float window_width; \n\
|
||||
uniform float window_height; \n\
|
||||
uniform float nearZ; \n\
|
||||
uniform float farZ; \n\
|
||||
\n\
|
||||
varying float radius; \n\
|
||||
\n\
|
||||
#ifdef FLAG_DISTORTION \n\
|
||||
uniform sampler2D distMap; \n\
|
||||
uniform sampler2D frameBuffer; \n\
|
||||
#endif \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
#ifndef FLAG_DISTORTION \n\
|
||||
vec2 offset = vec2( \n\
|
||||
radius * abs(0.5 - gl_TexCoord[0].x) * 2.0, \n\
|
||||
radius * abs(0.5 - gl_TexCoord[0].y) * 2.0 \n\
|
||||
); \n\
|
||||
\n\
|
||||
float offset_len = length(offset); \n\
|
||||
\n\
|
||||
if(offset_len > radius) \n\
|
||||
{ \n\
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); \n\
|
||||
return; \n\
|
||||
} \n\
|
||||
\n\
|
||||
vec2 depthCoord = vec2( \n\
|
||||
gl_FragCoord.x / window_width, \n\
|
||||
gl_FragCoord.y / window_height \n\
|
||||
); \n\
|
||||
\n\
|
||||
vec4 sceneDepth = texture2D(depthMap, depthCoord); \n\
|
||||
\n\
|
||||
float sceneDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - sceneDepth.x * (farZ-nearZ) ); \n\
|
||||
float fragDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - gl_FragCoord.z * (farZ-nearZ) ); \n\
|
||||
\n\
|
||||
// assume UV of 0.5, 0.5 is the centroid of this sphere volume \n\
|
||||
float depthOffset = sqrt( \n\
|
||||
pow(radius, 2.0) - \n\
|
||||
pow(offset_len, 2.0) \n\
|
||||
); \n\
|
||||
\n\
|
||||
float frontDepth = fragDepthLinear - depthOffset; \n\
|
||||
float backDepth = fragDepthLinear + depthOffset; \n\
|
||||
\n\
|
||||
float ds = min(sceneDepthLinear, backDepth) - max(nearZ, frontDepth); \n\
|
||||
\n""\
|
||||
vec4 fragmentColor = texture2D(baseMap, gl_TexCoord[0].xy)*gl_Color.a; \n\
|
||||
fragmentColor = fragmentColor * ( ds / (depthOffset*2.0) ); \n\
|
||||
\n\
|
||||
gl_FragColor = fragmentColor; \n\
|
||||
#else \n\
|
||||
vec2 depthCoord = vec2( \n\
|
||||
gl_FragCoord.x / window_width, \n\
|
||||
gl_FragCoord.y / window_height \n\
|
||||
); \n\
|
||||
vec4 fragmentColor = texture2D(baseMap, gl_TexCoord[0].xy)*gl_Color.a; \n\
|
||||
vec2 distortion = texture2D(distMap, gl_TexCoord[0].xy).rg; \n\
|
||||
float alpha = clamp(dot(fragmentColor.rgb,vec3(0.3333))*10.0,0.0,1.0); \n\
|
||||
distortion = ((distortion - 0.5) * 0.01) * alpha; \n\
|
||||
gl_FragColor = texture2D(frameBuffer,depthCoord+distortion); \n\
|
||||
gl_FragColor.a = alpha; \n\
|
||||
#endif \n\
|
||||
} \n\
|
||||
";
|
||||
char* Default_particle_fragment_shader =
|
||||
"uniform sampler2D baseMap;\n"
|
||||
"uniform sampler2D depthMap;\n"
|
||||
"uniform float window_width;\n"
|
||||
"uniform float window_height;\n"
|
||||
"uniform float nearZ;\n"
|
||||
"uniform float farZ;\n"
|
||||
"varying float radius;\n"
|
||||
"#ifdef FLAG_DISTORTION\n"
|
||||
"uniform sampler2D distMap;\n"
|
||||
"uniform sampler2D frameBuffer;\n"
|
||||
"varying float offset_out;\n"
|
||||
"#endif\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" #ifndef FLAG_DISTORTION\n"
|
||||
" vec2 offset = vec2(\n"
|
||||
" radius * abs(0.5 - gl_TexCoord[0].x) * 2.0,\n"
|
||||
" radius * abs(0.5 - gl_TexCoord[0].y) * 2.0\n"
|
||||
" );\n"
|
||||
" float offset_len = length(offset);\n"
|
||||
" if (offset_len > radius)\n"
|
||||
" {\n"
|
||||
" gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" vec2 depthCoord = vec2(\n"
|
||||
" gl_FragCoord.x / window_width,\n"
|
||||
" gl_FragCoord.y / window_height\n"
|
||||
" );\n"
|
||||
" vec4 sceneDepth = texture2D(depthMap, depthCoord);\n"
|
||||
" float sceneDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - sceneDepth.x * (farZ-nearZ) );\n"
|
||||
" float fragDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - gl_FragCoord.z * (farZ-nearZ) );\n"
|
||||
" // assume UV of 0.5, 0.5 is the centroid of this sphere volume\n"
|
||||
" float depthOffset = sqrt(\n"
|
||||
" pow(radius, 2.0) -\n"
|
||||
" pow(offset_len, 2.0)\n"
|
||||
" );\n"
|
||||
" float frontDepth = fragDepthLinear - depthOffset;\n"
|
||||
" float backDepth = fragDepthLinear + depthOffset;\n"
|
||||
" float ds = min(sceneDepthLinear, backDepth) - max(nearZ, frontDepth);\n"
|
||||
" vec4 fragmentColor = texture2D(baseMap, gl_TexCoord[0].xy)*gl_Color.a;\n"
|
||||
" fragmentColor = fragmentColor * ( ds / (depthOffset*2.0) );\n"
|
||||
" gl_FragColor = fragmentColor;\n"
|
||||
" #else\n"
|
||||
" vec2 depthCoord = vec2(\n"
|
||||
" gl_FragCoord.x / window_width,\n"
|
||||
" gl_FragCoord.y / window_height\n"
|
||||
" );\n"
|
||||
" vec4 fragmentColor = texture2D(baseMap, gl_TexCoord[0].xy)*gl_Color.a;\n"
|
||||
" vec2 distortion = texture2D(distMap, gl_TexCoord[0].xy+vec2(0.0, offset_out)).rg;\n"
|
||||
" float alpha = clamp(dot(fragmentColor.rgb,vec3(0.3333))*10.0,0.0,1.0);\n"
|
||||
" distortion = ((distortion - 0.5) * 0.01) * alpha;\n"
|
||||
" gl_FragColor = texture2D(frameBuffer,depthCoord+distortion);\n"
|
||||
" gl_FragColor.a = alpha;\n"
|
||||
" #endif\n"
|
||||
"}";
|
||||
|
||||
char *Default_video_vertex_shader =
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
|
||||
" gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n"
|
||||
" gl_FrontColor = vec4(1.0);\n"
|
||||
" gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||
"}";
|
||||
|
||||
char * Default_video_fragment_shader =
|
||||
"uniform sampler2D ytex;\n"
|
||||
"uniform sampler2D utex;\n"
|
||||
"uniform sampler2D vtex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec3 val = vec3(texture2D(ytex, gl_TexCoord[0].st).r - 0.0625, texture2D(utex, gl_TexCoord[0].st).r - 0.5, texture2D(vtex, gl_TexCoord[0].st).r - 0.5);\n"
|
||||
" gl_FragColor.r = dot(val, vec3(1.1640625, 0.0, 1.59765625));\n"
|
||||
" gl_FragColor.g = dot(val, vec3(1.1640625, -0.390625, -0.8125));\n"
|
||||
" gl_FragColor.b = dot(val, vec3(1.1640625, 2.015625, 0.0));\n"
|
||||
" gl_FragColor.a = 1.0;\n"
|
||||
"}";
|
||||
@@ -18,7 +18,6 @@
|
||||
#define TIME_LENGTH 16
|
||||
#define DATE_TIME_LENGTH 48
|
||||
#define NOTES_LENGTH 1024
|
||||
// Kazan - this used to be 1024, now 4096
|
||||
#define MULTITEXT_LENGTH 4096
|
||||
#define FILESPEC_LENGTH 64
|
||||
#define MESSAGE_LENGTH 512
|
||||
@@ -27,20 +26,12 @@
|
||||
// from missionparse.h
|
||||
#define MISSION_DESC_LENGTH 512
|
||||
|
||||
|
||||
// from player.h
|
||||
#define CALLSIGN_LEN 28 // shortened from 32 to allow .plr to be attached without exceeding MAX_FILENAME_LEN
|
||||
#define SHORT_CALLSIGN_PIXEL_W 80 // max width of short_callsign[] in pixels
|
||||
|
||||
// from missionparse.h
|
||||
// This must be less than or equal to the number of bits in an int! If you really must have that many species,
|
||||
// then please update the support_ship_info struct.
|
||||
// 20060826 - made it dynamic -- taylor
|
||||
//#define MAX_SPECIES 8
|
||||
|
||||
#define MAX_IFFS 10
|
||||
|
||||
|
||||
// from ship.h
|
||||
#define MAX_SHIPS 400 // max number of ship instances there can be.DTP; bumped from 200 to 400
|
||||
#define SHIPS_LIMIT 400 // what MAX_SHIPS will be at release time (for error checking in debug mode); dtp Bumped from 200 to 400
|
||||
@@ -57,9 +48,6 @@
|
||||
#define MAX_SHIP_CLASSES 130
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_WINGS 75
|
||||
|
||||
#define MAX_SHIPS_PER_WING 6
|
||||
@@ -76,14 +64,11 @@
|
||||
#define MAX_SHIP_SECONDARY_BANKS 4
|
||||
#define MAX_SHIP_WEAPONS (MAX_SHIP_PRIMARY_BANKS+MAX_SHIP_SECONDARY_BANKS)
|
||||
|
||||
|
||||
// Goober5000 - moved from hudescort.cpp
|
||||
// size of complete escort list, including all those wanting to get onto list but without space
|
||||
#define MAX_COMPLETE_ESCORT_LIST 20
|
||||
|
||||
|
||||
// from weapon.h
|
||||
// upped 5/6/98 from 200 - DB
|
||||
#define MAX_WEAPONS 700
|
||||
|
||||
#ifdef INF_BUILD
|
||||
@@ -92,7 +77,6 @@
|
||||
#define MAX_WEAPON_TYPES 200
|
||||
#endif
|
||||
|
||||
|
||||
// from model.h
|
||||
|
||||
#define MAX_MODEL_TEXTURES 64
|
||||
@@ -103,11 +87,9 @@
|
||||
#define MAX_POLYGON_MODELS 128 //DTP reset from 198 to original value of 128
|
||||
#endif
|
||||
|
||||
|
||||
// from scoring.h
|
||||
// ARGH. IMPORTANT : do not change NUM_MEDALS without talking to DaveB first. It will affect the size of the scoring struct and hence, will break
|
||||
// a lot of PXO related stuff. SEE ALSO : MAX_SHIP_CLASSES
|
||||
|
||||
#define MAX_MEDALS 18
|
||||
#define NUM_MEDALS_FS1 16
|
||||
extern int Num_medals;
|
||||
|
||||
+348
-348
@@ -1,349 +1,349 @@
|
||||
/* This file contains debugging utilities used only under VC2005+
|
||||
* Maintained by: portej05 (please run patches past him before committing here!)
|
||||
*/
|
||||
|
||||
/* Based on the ATL headers, however, updated to fix one or two bugs in the ATL headers
|
||||
* and moved to the Sym*64 functions
|
||||
*/
|
||||
|
||||
#if defined(PDB_DEBUGGING)
|
||||
|
||||
/* Windows */
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
/* SCP */
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/mspdb_callstack.h"
|
||||
|
||||
/* Link the library that we need */
|
||||
#pragma comment( lib, "dbghelp.lib" )
|
||||
|
||||
HRESULT SCP_DumpStack( SCP_IDumpHandler* pISH );
|
||||
BOOL SCP_mspdbcs_ResolveSymbol( HANDLE hProcess, UINT_PTR dwAddress, SCP_mspdbcs_SDumpStackSymbolInfo& siSymbol );
|
||||
LPVOID __stdcall SCP_mspdbcs_FunctionTableAccess( HANDLE hProcess, DWORD64 dwPCAddress );
|
||||
DWORD64 __stdcall SCP_mspdbcs_GetModuleBase( HANDLE hProcess, DWORD64 returnAddress );
|
||||
DWORD WINAPI SCP_mspdbcs_DumpStackThread( LPVOID pv );
|
||||
void SCP_mspdbcs_Initialise( );
|
||||
void SCP_mspdbcs_Cleanup( );
|
||||
|
||||
static bool SCP_mspdbcs_initialised = false;
|
||||
static CRITICAL_SECTION SCP_mspdbcs_cs;
|
||||
|
||||
BOOL SCP_mspdbcs_ResolveSymbol( HANDLE hProcess, UINT_PTR dwAddress, SCP_mspdbcs_SDumpStackSymbolInfo& siSymbol )
|
||||
{
|
||||
BOOL retVal = TRUE;
|
||||
|
||||
char szUndec[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
char szWithOffset[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
char* pszSymbol = NULL;
|
||||
IMAGEHLP_MODULE64 mi;
|
||||
|
||||
memset( &siSymbol, 0, sizeof( SCP_mspdbcs_SDumpStackSymbolInfo ) );
|
||||
mi.SizeOfStruct = sizeof( IMAGEHLP_MODULE64 );
|
||||
|
||||
siSymbol.dwAddress = dwAddress;
|
||||
|
||||
if ( !SymGetModuleInfo64( hProcess, dwAddress, &mi ) )
|
||||
{
|
||||
/* Unneeded */
|
||||
/*printf("Error: %x\n", HRESULT_FROM_WIN32( GetLastError( ) ));*/
|
||||
strcpy_s( siSymbol.szModule, "<no module>" );
|
||||
}
|
||||
else
|
||||
{
|
||||
char* pszLastModule = strchr( mi.ImageName, '\\' );
|
||||
|
||||
if ( pszLastModule == NULL )
|
||||
pszLastModule = mi.ImageName;
|
||||
else
|
||||
pszLastModule++; /* move off the backslash */
|
||||
|
||||
strncpy_s( siSymbol.szModule, pszLastModule, _TRUNCATE );
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
union
|
||||
{
|
||||
CHAR rgchSymbol[ sizeof(IMAGEHLP_SYMBOL64) + SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
IMAGEHLP_SYMBOL64 sym;
|
||||
} sym;
|
||||
|
||||
memset( &sym.sym, 0, sizeof( sym.sym ) );
|
||||
sym.sym.SizeOfStruct = sizeof( IMAGEHLP_SYMBOL64 );
|
||||
|
||||
#ifdef _WIN64
|
||||
sym.sym.Address = dwAddress;
|
||||
#else
|
||||
sym.sym.Address = (DWORD)dwAddress;
|
||||
#endif
|
||||
sym.sym.MaxNameLength = SCP_MSPDBCS_MAX_SYMBOL_LENGTH;
|
||||
|
||||
#ifdef _WIN64
|
||||
if ( SymGetSymFromAddr64( hProcess, dwAddress, &(siSymbol.dwOffset), &sym.sym ) )
|
||||
#else
|
||||
if ( SymGetSymFromAddr64( hProcess, (DWORD)dwAddress, &(siSymbol.dwOffset), &sym.sym ) )
|
||||
#endif
|
||||
{
|
||||
pszSymbol = sym.sym.Name;
|
||||
|
||||
if ( UnDecorateSymbolName( sym.sym.Name, szUndec, sizeof( szUndec )/sizeof( szUndec[0] ),
|
||||
UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS ) )
|
||||
{
|
||||
pszSymbol = szUndec;
|
||||
}
|
||||
else if ( SymUnDName64( &sym.sym, szUndec, sizeof( szUndec )/sizeof( szUndec[0] ) ) )
|
||||
{
|
||||
pszSymbol = szUndec;
|
||||
}
|
||||
|
||||
if ( siSymbol.dwOffset != 0 )
|
||||
{
|
||||
sprintf_s( szWithOffset, SCP_MSPDBCS_MAX_SYMBOL_LENGTH, "%s + %d bytes", pszSymbol, siSymbol.dwOffset );
|
||||
szWithOffset[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH - 1 ] = '\0'; /* Because sprintf doesn't guarantee NULL terminating */
|
||||
pszSymbol = szWithOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
pszSymbol = "<no symbol>";
|
||||
}
|
||||
__except( EXCEPTION_ACCESS_VIOLATION == GetExceptionCode( ) )
|
||||
{
|
||||
pszSymbol = "<EX: no symbol>";
|
||||
siSymbol.dwOffset = dwAddress - mi.BaseOfImage;
|
||||
}
|
||||
|
||||
strncpy_s( siSymbol.szSymbol, pszSymbol, _TRUNCATE );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
LPVOID __stdcall SCP_mspdbcs_FunctionTableAccess( HANDLE hProcess, DWORD64 dwPCAddress )
|
||||
{
|
||||
return SymFunctionTableAccess64( hProcess, dwPCAddress );
|
||||
}
|
||||
|
||||
DWORD64 __stdcall SCP_mspdbcs_GetModuleBase( HANDLE hProcess, DWORD64 returnAddress )
|
||||
{
|
||||
IMAGEHLP_MODULE moduleInfo;
|
||||
moduleInfo.SizeOfStruct = sizeof( IMAGEHLP_MODULE );
|
||||
|
||||
/* The ATL headers do it this way */
|
||||
#ifdef _WIN64
|
||||
if ( SymGetModuleInfo( hProcess, returnAddress, &moduleInfo ) )
|
||||
#else
|
||||
if ( SymGetModuleInfo( hProcess, (ULONG)returnAddress, &moduleInfo ) )
|
||||
#endif
|
||||
{
|
||||
return moduleInfo.BaseOfImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION memoryBasicInfo;
|
||||
|
||||
if ( VirtualQueryEx( hProcess, (LPVOID)returnAddress,
|
||||
&memoryBasicInfo, sizeof( MEMORY_BASIC_INFORMATION ) ) )
|
||||
{
|
||||
DWORD cch = 0;
|
||||
char szFile[ _MAX_PATH ] = {0}; /* Initialise the file path */
|
||||
cch = GetModuleFileNameA( (HINSTANCE)memoryBasicInfo.AllocationBase, szFile, MAX_PATH );
|
||||
SymLoadModule( hProcess, NULL, ((cch)?szFile:NULL),
|
||||
#ifdef _WIN64
|
||||
NULL, (DWORD_PTR)memoryBasicInfo.AllocationBase, 0 );
|
||||
#else
|
||||
NULL, (DWORD)(DWORD_PTR)memoryBasicInfo.AllocationBase, 0 );
|
||||
#endif
|
||||
return (DWORD_PTR)memoryBasicInfo.AllocationBase;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD WINAPI SCP_mspdbcs_DumpStackThread( LPVOID pv )
|
||||
{
|
||||
CONTEXT context;
|
||||
memset( &context, 0, sizeof( CONTEXT ) );
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
SCP_mspdbcs_SDumpStackThreadInfo* pdsti =
|
||||
reinterpret_cast< SCP_mspdbcs_SDumpStackThreadInfo* >( pv );
|
||||
|
||||
/* We're going to walk the stack here */
|
||||
|
||||
/* Suspend the running thread */
|
||||
SuspendThread( pdsti->hThread );
|
||||
|
||||
pdsti->pIDS->OnBegin( );
|
||||
|
||||
/* Retrieve the context (processor state) of the suspended thread */
|
||||
GetThreadContext( pdsti->hThread, &context );
|
||||
|
||||
/* Set name decoration handling */
|
||||
DWORD dw = SymGetOptions( );
|
||||
dw = dw & ~SYMOPT_UNDNAME;
|
||||
SymSetOptions( dw );
|
||||
|
||||
/* Initialise the stackframe */
|
||||
STACKFRAME64 stackFrame;
|
||||
memset( &stackFrame, 0, sizeof( STACKFRAME64 ) );
|
||||
stackFrame.AddrPC.Mode = AddrModeFlat;
|
||||
stackFrame.AddrFrame.Mode = AddrModeFlat;
|
||||
stackFrame.AddrStack.Mode = AddrModeFlat;
|
||||
stackFrame.AddrReturn.Mode = AddrModeFlat;
|
||||
stackFrame.AddrBStore.Mode = AddrModeFlat;
|
||||
|
||||
DWORD dwMachType;
|
||||
|
||||
/* Determine the machine type based on the compilation.
|
||||
* Initialise stackFrame accordingly
|
||||
* We will only handle the types of _M_IX86 or _M_AMD64
|
||||
* We're not intending to be compatible with IA64 or any other architectures
|
||||
* under windows
|
||||
*/
|
||||
#if defined(_M_IX86)
|
||||
dwMachType = IMAGE_FILE_MACHINE_I386;
|
||||
stackFrame.AddrPC.Offset = context.Eip;
|
||||
stackFrame.AddrStack.Offset = context.Esp;
|
||||
stackFrame.AddrFrame.Offset = context.Ebp;
|
||||
#elif defined(_M_AMD64)
|
||||
dwMachType = IMAGE_FILE_MACHINE_AMD64;
|
||||
stackFrame.AddrPC.Offset = context.Rip;
|
||||
stackFrame.AddrStack = context.Rsp;
|
||||
#else
|
||||
# error UNKNOWN ARCHITECTURE
|
||||
#endif
|
||||
|
||||
/* All the discovered addresses will be stored in an array */
|
||||
SCP_vector< void* > addresses;
|
||||
|
||||
/* Walk the stack */
|
||||
for ( int currFrame = 0; currFrame < SCP_MSPDBCS_MAX_STACK_FRAMES; currFrame++ )
|
||||
{
|
||||
if ( !StackWalk64( dwMachType, pdsti->hProcess, pdsti->hThread,
|
||||
&stackFrame, &context, NULL,
|
||||
SCP_mspdbcs_FunctionTableAccess, SCP_mspdbcs_GetModuleBase, NULL ) )
|
||||
{
|
||||
break; /* No more stack frames to walk */
|
||||
}
|
||||
|
||||
/* Found a useful address? */
|
||||
if ( stackFrame.AddrPC.Offset != 0 )
|
||||
{
|
||||
if ( pdsti->pIDS->ResolveSymbols( ) )
|
||||
addresses.push_back( (void*)(DWORD_PTR)stackFrame.AddrPC.Offset );
|
||||
else
|
||||
pdsti->pIDS->OnEntry( (void*)(DWORD_PTR)stackFrame.AddrPC.Offset, NULL, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pdsti->pIDS->ResolveSymbols( ) )
|
||||
{
|
||||
/* Dump the stack information that we have */
|
||||
for ( size_t i = 0; i < addresses.size( ); i++ )
|
||||
{
|
||||
SCP_mspdbcs_SDumpStackSymbolInfo info;
|
||||
const char* szModule = NULL;
|
||||
const char* szSymbol = NULL;
|
||||
|
||||
if ( SCP_mspdbcs_ResolveSymbol( pdsti->hProcess, (UINT_PTR)addresses[ i ], info ) )
|
||||
{
|
||||
szModule = info.szModule;
|
||||
szSymbol = info.szSymbol;
|
||||
}
|
||||
|
||||
pdsti->pIDS->OnEntry( addresses[ i ], szModule, szSymbol );
|
||||
}
|
||||
}
|
||||
|
||||
pdsti->pIDS->OnEnd( );
|
||||
ResumeThread( pdsti->hThread );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
HRESULT SCP_DumpStack( SCP_IDumpHandler* pIDH )
|
||||
{
|
||||
if ( !pIDH )
|
||||
return E_POINTER;
|
||||
|
||||
/* Retrieve pseudo handles to the current thread and process */
|
||||
HANDLE hPseudoThread = GetCurrentThread( );
|
||||
HANDLE hPseudoProcess = GetCurrentProcess( );
|
||||
|
||||
/* Retrieve the real handle of this thread */
|
||||
HANDLE hThread = NULL;
|
||||
if ( !DuplicateHandle( hPseudoProcess, hPseudoThread, /* Source process and thread */
|
||||
hPseudoProcess, &hThread, /* Target process and thread */
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS ) ) /* Non-Inheritable, same access as current process/thread */
|
||||
return HRESULT_FROM_WIN32( GetLastError( ) ); /* Bugger */
|
||||
|
||||
DWORD dwID;
|
||||
|
||||
SCP_mspdbcs_SDumpStackThreadInfo info;
|
||||
info.hProcess = hPseudoProcess;
|
||||
info.hThread = hThread;
|
||||
info.pIDS = pIDH;
|
||||
|
||||
/* Calls to dbghelp.dll must be synchronised :( */
|
||||
EnterCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
/* This will fail if SymInitialize hasn't been called, so
|
||||
* this protects against uninitialised state */
|
||||
if ( !SCP_mspdbcs_initialised )
|
||||
{
|
||||
LeaveCriticalSection( &SCP_mspdbcs_cs );
|
||||
mprintf( ("Symbols not initialised\n") );
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
HANDLE workerThread = CreateThread( NULL, 0, SCP_mspdbcs_DumpStackThread,
|
||||
&info, 0, &dwID );
|
||||
|
||||
LeaveCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
if ( workerThread == NULL )
|
||||
return HRESULT_FROM_WIN32( GetLastError( ) ); /* Bugger */
|
||||
|
||||
while ( WaitForSingleObject( workerThread, 0 ) != WAIT_OBJECT_0 );
|
||||
|
||||
CloseHandle( workerThread );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif // PDB_DEBUGGING
|
||||
|
||||
void SCP_mspdbcs_Initialise( )
|
||||
{
|
||||
#ifdef PDB_DEBUGGING
|
||||
HANDLE hPseudoProcess = GetCurrentProcess( );
|
||||
if ( !SymInitialize( hPseudoProcess, NULL, TRUE ) )
|
||||
{
|
||||
mprintf( ("Could not initialise symbols - callstacks will fail: %x\n", HRESULT_FROM_WIN32( GetLastError( ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeCriticalSection( &SCP_mspdbcs_cs );
|
||||
SCP_mspdbcs_initialised = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SCP_mspdbcs_Cleanup( )
|
||||
{
|
||||
#ifdef PDB_DEBUGGING
|
||||
/* We enter the critical section to synchronise the check of
|
||||
* SCP_mspdbcs_initialised. Failure to do that could cause
|
||||
* SymCleanup to be called before SCP_dump_stack is finished
|
||||
*/
|
||||
EnterCriticalSection( &SCP_mspdbcs_cs );
|
||||
SCP_mspdbcs_initialised = false; /* stop problems at end of execution */
|
||||
LeaveCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
DeleteCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
HANDLE hPseudoProcess = GetCurrentProcess( );
|
||||
SymCleanup( hPseudoProcess );
|
||||
#endif
|
||||
/* This file contains debugging utilities used only under VC2005+
|
||||
* Maintained by: portej05 (please run patches past him before committing here!)
|
||||
*/
|
||||
|
||||
/* Based on the ATL headers, however, updated to fix one or two bugs in the ATL headers
|
||||
* and moved to the Sym*64 functions
|
||||
*/
|
||||
|
||||
#if defined(PDB_DEBUGGING)
|
||||
|
||||
/* Windows */
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
/* SCP */
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "globalincs/mspdb_callstack.h"
|
||||
|
||||
/* Link the library that we need */
|
||||
#pragma comment( lib, "dbghelp.lib" )
|
||||
|
||||
HRESULT SCP_DumpStack( SCP_IDumpHandler* pISH );
|
||||
BOOL SCP_mspdbcs_ResolveSymbol( HANDLE hProcess, UINT_PTR dwAddress, SCP_mspdbcs_SDumpStackSymbolInfo& siSymbol );
|
||||
LPVOID __stdcall SCP_mspdbcs_FunctionTableAccess( HANDLE hProcess, DWORD64 dwPCAddress );
|
||||
DWORD64 __stdcall SCP_mspdbcs_GetModuleBase( HANDLE hProcess, DWORD64 returnAddress );
|
||||
DWORD WINAPI SCP_mspdbcs_DumpStackThread( LPVOID pv );
|
||||
void SCP_mspdbcs_Initialise( );
|
||||
void SCP_mspdbcs_Cleanup( );
|
||||
|
||||
static bool SCP_mspdbcs_initialised = false;
|
||||
static CRITICAL_SECTION SCP_mspdbcs_cs;
|
||||
|
||||
BOOL SCP_mspdbcs_ResolveSymbol( HANDLE hProcess, UINT_PTR dwAddress, SCP_mspdbcs_SDumpStackSymbolInfo& siSymbol )
|
||||
{
|
||||
BOOL retVal = TRUE;
|
||||
|
||||
char szUndec[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
char szWithOffset[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
char* pszSymbol = NULL;
|
||||
IMAGEHLP_MODULE64 mi;
|
||||
|
||||
memset( &siSymbol, 0, sizeof( SCP_mspdbcs_SDumpStackSymbolInfo ) );
|
||||
mi.SizeOfStruct = sizeof( IMAGEHLP_MODULE64 );
|
||||
|
||||
siSymbol.dwAddress = dwAddress;
|
||||
|
||||
if ( !SymGetModuleInfo64( hProcess, dwAddress, &mi ) )
|
||||
{
|
||||
/* Unneeded */
|
||||
/*printf("Error: %x\n", HRESULT_FROM_WIN32( GetLastError( ) ));*/
|
||||
strcpy_s( siSymbol.szModule, "<no module>" );
|
||||
}
|
||||
else
|
||||
{
|
||||
char* pszLastModule = strchr( mi.ImageName, '\\' );
|
||||
|
||||
if ( pszLastModule == NULL )
|
||||
pszLastModule = mi.ImageName;
|
||||
else
|
||||
pszLastModule++; /* move off the backslash */
|
||||
|
||||
strncpy_s( siSymbol.szModule, pszLastModule, _TRUNCATE );
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
union
|
||||
{
|
||||
CHAR rgchSymbol[ sizeof(IMAGEHLP_SYMBOL64) + SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
IMAGEHLP_SYMBOL64 sym;
|
||||
} sym;
|
||||
|
||||
memset( &sym.sym, 0, sizeof( sym.sym ) );
|
||||
sym.sym.SizeOfStruct = sizeof( IMAGEHLP_SYMBOL64 );
|
||||
|
||||
#ifdef _WIN64
|
||||
sym.sym.Address = dwAddress;
|
||||
#else
|
||||
sym.sym.Address = (DWORD)dwAddress;
|
||||
#endif
|
||||
sym.sym.MaxNameLength = SCP_MSPDBCS_MAX_SYMBOL_LENGTH;
|
||||
|
||||
#ifdef _WIN64
|
||||
if ( SymGetSymFromAddr64( hProcess, dwAddress, &(siSymbol.dwOffset), &sym.sym ) )
|
||||
#else
|
||||
if ( SymGetSymFromAddr64( hProcess, (DWORD)dwAddress, &(siSymbol.dwOffset), &sym.sym ) )
|
||||
#endif
|
||||
{
|
||||
pszSymbol = sym.sym.Name;
|
||||
|
||||
if ( UnDecorateSymbolName( sym.sym.Name, szUndec, sizeof( szUndec )/sizeof( szUndec[0] ),
|
||||
UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS ) )
|
||||
{
|
||||
pszSymbol = szUndec;
|
||||
}
|
||||
else if ( SymUnDName64( &sym.sym, szUndec, sizeof( szUndec )/sizeof( szUndec[0] ) ) )
|
||||
{
|
||||
pszSymbol = szUndec;
|
||||
}
|
||||
|
||||
if ( siSymbol.dwOffset != 0 )
|
||||
{
|
||||
sprintf_s( szWithOffset, SCP_MSPDBCS_MAX_SYMBOL_LENGTH, "%s + %d bytes", pszSymbol, siSymbol.dwOffset );
|
||||
szWithOffset[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH - 1 ] = '\0'; /* Because sprintf doesn't guarantee NULL terminating */
|
||||
pszSymbol = szWithOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
pszSymbol = "<no symbol>";
|
||||
}
|
||||
__except( EXCEPTION_ACCESS_VIOLATION == GetExceptionCode( ) )
|
||||
{
|
||||
pszSymbol = "<EX: no symbol>";
|
||||
siSymbol.dwOffset = dwAddress - mi.BaseOfImage;
|
||||
}
|
||||
|
||||
strncpy_s( siSymbol.szSymbol, pszSymbol, _TRUNCATE );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
LPVOID __stdcall SCP_mspdbcs_FunctionTableAccess( HANDLE hProcess, DWORD64 dwPCAddress )
|
||||
{
|
||||
return SymFunctionTableAccess64( hProcess, dwPCAddress );
|
||||
}
|
||||
|
||||
DWORD64 __stdcall SCP_mspdbcs_GetModuleBase( HANDLE hProcess, DWORD64 returnAddress )
|
||||
{
|
||||
IMAGEHLP_MODULE moduleInfo;
|
||||
moduleInfo.SizeOfStruct = sizeof( IMAGEHLP_MODULE );
|
||||
|
||||
/* The ATL headers do it this way */
|
||||
#ifdef _WIN64
|
||||
if ( SymGetModuleInfo( hProcess, returnAddress, &moduleInfo ) )
|
||||
#else
|
||||
if ( SymGetModuleInfo( hProcess, (ULONG)returnAddress, &moduleInfo ) )
|
||||
#endif
|
||||
{
|
||||
return moduleInfo.BaseOfImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION memoryBasicInfo;
|
||||
|
||||
if ( VirtualQueryEx( hProcess, (LPVOID)returnAddress,
|
||||
&memoryBasicInfo, sizeof( MEMORY_BASIC_INFORMATION ) ) )
|
||||
{
|
||||
DWORD cch = 0;
|
||||
char szFile[ _MAX_PATH ] = {0}; /* Initialise the file path */
|
||||
cch = GetModuleFileNameA( (HINSTANCE)memoryBasicInfo.AllocationBase, szFile, MAX_PATH );
|
||||
SymLoadModule( hProcess, NULL, ((cch)?szFile:NULL),
|
||||
#ifdef _WIN64
|
||||
NULL, (DWORD_PTR)memoryBasicInfo.AllocationBase, 0 );
|
||||
#else
|
||||
NULL, (DWORD)(DWORD_PTR)memoryBasicInfo.AllocationBase, 0 );
|
||||
#endif
|
||||
return (DWORD_PTR)memoryBasicInfo.AllocationBase;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD WINAPI SCP_mspdbcs_DumpStackThread( LPVOID pv )
|
||||
{
|
||||
CONTEXT context;
|
||||
memset( &context, 0, sizeof( CONTEXT ) );
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
SCP_mspdbcs_SDumpStackThreadInfo* pdsti =
|
||||
reinterpret_cast< SCP_mspdbcs_SDumpStackThreadInfo* >( pv );
|
||||
|
||||
/* We're going to walk the stack here */
|
||||
|
||||
/* Suspend the running thread */
|
||||
SuspendThread( pdsti->hThread );
|
||||
|
||||
pdsti->pIDS->OnBegin( );
|
||||
|
||||
/* Retrieve the context (processor state) of the suspended thread */
|
||||
GetThreadContext( pdsti->hThread, &context );
|
||||
|
||||
/* Set name decoration handling */
|
||||
DWORD dw = SymGetOptions( );
|
||||
dw = dw & ~SYMOPT_UNDNAME;
|
||||
SymSetOptions( dw );
|
||||
|
||||
/* Initialise the stackframe */
|
||||
STACKFRAME64 stackFrame;
|
||||
memset( &stackFrame, 0, sizeof( STACKFRAME64 ) );
|
||||
stackFrame.AddrPC.Mode = AddrModeFlat;
|
||||
stackFrame.AddrFrame.Mode = AddrModeFlat;
|
||||
stackFrame.AddrStack.Mode = AddrModeFlat;
|
||||
stackFrame.AddrReturn.Mode = AddrModeFlat;
|
||||
stackFrame.AddrBStore.Mode = AddrModeFlat;
|
||||
|
||||
DWORD dwMachType;
|
||||
|
||||
/* Determine the machine type based on the compilation.
|
||||
* Initialise stackFrame accordingly
|
||||
* We will only handle the types of _M_IX86 or _M_AMD64
|
||||
* We're not intending to be compatible with IA64 or any other architectures
|
||||
* under windows
|
||||
*/
|
||||
#if defined(_M_IX86)
|
||||
dwMachType = IMAGE_FILE_MACHINE_I386;
|
||||
stackFrame.AddrPC.Offset = context.Eip;
|
||||
stackFrame.AddrStack.Offset = context.Esp;
|
||||
stackFrame.AddrFrame.Offset = context.Ebp;
|
||||
#elif defined(_M_AMD64)
|
||||
dwMachType = IMAGE_FILE_MACHINE_AMD64;
|
||||
stackFrame.AddrPC.Offset = context.Rip;
|
||||
stackFrame.AddrStack = context.Rsp;
|
||||
#else
|
||||
# error UNKNOWN ARCHITECTURE
|
||||
#endif
|
||||
|
||||
/* All the discovered addresses will be stored in an array */
|
||||
SCP_vector< void* > addresses;
|
||||
|
||||
/* Walk the stack */
|
||||
for ( int currFrame = 0; currFrame < SCP_MSPDBCS_MAX_STACK_FRAMES; currFrame++ )
|
||||
{
|
||||
if ( !StackWalk64( dwMachType, pdsti->hProcess, pdsti->hThread,
|
||||
&stackFrame, &context, NULL,
|
||||
SCP_mspdbcs_FunctionTableAccess, SCP_mspdbcs_GetModuleBase, NULL ) )
|
||||
{
|
||||
break; /* No more stack frames to walk */
|
||||
}
|
||||
|
||||
/* Found a useful address? */
|
||||
if ( stackFrame.AddrPC.Offset != 0 )
|
||||
{
|
||||
if ( pdsti->pIDS->ResolveSymbols( ) )
|
||||
addresses.push_back( (void*)(DWORD_PTR)stackFrame.AddrPC.Offset );
|
||||
else
|
||||
pdsti->pIDS->OnEntry( (void*)(DWORD_PTR)stackFrame.AddrPC.Offset, NULL, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pdsti->pIDS->ResolveSymbols( ) )
|
||||
{
|
||||
/* Dump the stack information that we have */
|
||||
for ( size_t i = 0; i < addresses.size( ); i++ )
|
||||
{
|
||||
SCP_mspdbcs_SDumpStackSymbolInfo info;
|
||||
const char* szModule = NULL;
|
||||
const char* szSymbol = NULL;
|
||||
|
||||
if ( SCP_mspdbcs_ResolveSymbol( pdsti->hProcess, (UINT_PTR)addresses[ i ], info ) )
|
||||
{
|
||||
szModule = info.szModule;
|
||||
szSymbol = info.szSymbol;
|
||||
}
|
||||
|
||||
pdsti->pIDS->OnEntry( addresses[ i ], szModule, szSymbol );
|
||||
}
|
||||
}
|
||||
|
||||
pdsti->pIDS->OnEnd( );
|
||||
ResumeThread( pdsti->hThread );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
HRESULT SCP_DumpStack( SCP_IDumpHandler* pIDH )
|
||||
{
|
||||
if ( !pIDH )
|
||||
return E_POINTER;
|
||||
|
||||
/* Retrieve pseudo handles to the current thread and process */
|
||||
HANDLE hPseudoThread = GetCurrentThread( );
|
||||
HANDLE hPseudoProcess = GetCurrentProcess( );
|
||||
|
||||
/* Retrieve the real handle of this thread */
|
||||
HANDLE hThread = NULL;
|
||||
if ( !DuplicateHandle( hPseudoProcess, hPseudoThread, /* Source process and thread */
|
||||
hPseudoProcess, &hThread, /* Target process and thread */
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS ) ) /* Non-Inheritable, same access as current process/thread */
|
||||
return HRESULT_FROM_WIN32( GetLastError( ) ); /* Bugger */
|
||||
|
||||
DWORD dwID;
|
||||
|
||||
SCP_mspdbcs_SDumpStackThreadInfo info;
|
||||
info.hProcess = hPseudoProcess;
|
||||
info.hThread = hThread;
|
||||
info.pIDS = pIDH;
|
||||
|
||||
/* Calls to dbghelp.dll must be synchronised :( */
|
||||
EnterCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
/* This will fail if SymInitialize hasn't been called, so
|
||||
* this protects against uninitialised state */
|
||||
if ( !SCP_mspdbcs_initialised )
|
||||
{
|
||||
LeaveCriticalSection( &SCP_mspdbcs_cs );
|
||||
mprintf( ("Symbols not initialised\n") );
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
HANDLE workerThread = CreateThread( NULL, 0, SCP_mspdbcs_DumpStackThread,
|
||||
&info, 0, &dwID );
|
||||
|
||||
LeaveCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
if ( workerThread == NULL )
|
||||
return HRESULT_FROM_WIN32( GetLastError( ) ); /* Bugger */
|
||||
|
||||
while ( WaitForSingleObject( workerThread, 0 ) != WAIT_OBJECT_0 );
|
||||
|
||||
CloseHandle( workerThread );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif // PDB_DEBUGGING
|
||||
|
||||
void SCP_mspdbcs_Initialise( )
|
||||
{
|
||||
#ifdef PDB_DEBUGGING
|
||||
HANDLE hPseudoProcess = GetCurrentProcess( );
|
||||
if ( !SymInitialize( hPseudoProcess, NULL, TRUE ) )
|
||||
{
|
||||
mprintf( ("Could not initialise symbols - callstacks will fail: %x\n", HRESULT_FROM_WIN32( GetLastError( ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeCriticalSection( &SCP_mspdbcs_cs );
|
||||
SCP_mspdbcs_initialised = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SCP_mspdbcs_Cleanup( )
|
||||
{
|
||||
#ifdef PDB_DEBUGGING
|
||||
/* We enter the critical section to synchronise the check of
|
||||
* SCP_mspdbcs_initialised. Failure to do that could cause
|
||||
* SymCleanup to be called before SCP_dump_stack is finished
|
||||
*/
|
||||
EnterCriticalSection( &SCP_mspdbcs_cs );
|
||||
SCP_mspdbcs_initialised = false; /* stop problems at end of execution */
|
||||
LeaveCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
DeleteCriticalSection( &SCP_mspdbcs_cs );
|
||||
|
||||
HANDLE hPseudoProcess = GetCurrentProcess( );
|
||||
SymCleanup( hPseudoProcess );
|
||||
#endif
|
||||
}
|
||||
@@ -1,76 +1,76 @@
|
||||
/* This file contains debugging utilities used only under VC2005+
|
||||
* Maintained by: portej05 (please run patches past him before committing here!)
|
||||
*/
|
||||
|
||||
/* You will need to define PDB_DEBUGGING in order to use these functions
|
||||
* Important note:
|
||||
* When you call SCP_DumpStack, your thread will be suspended until the stack is dumped
|
||||
* If you've got more than a single thread
|
||||
*/
|
||||
|
||||
/* Things you should be using from this header
|
||||
* SCP_IDumpHandler - implement this in order to receive symbols from DumpStack
|
||||
*/
|
||||
|
||||
#ifndef _MSPDB_CALLSTACK_H_INCLUDED_
|
||||
#define _MSPDB_CALLSTACK_H_INCLUDED_
|
||||
|
||||
#if defined(PDB_DEBUGGING)
|
||||
|
||||
/* Must have windows.h */
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef PURE
|
||||
# define PURE = 0
|
||||
#endif
|
||||
|
||||
/* PUBLIC - use these */
|
||||
|
||||
/* This interface will be used by the stack tracing code
|
||||
* to return symbols
|
||||
*/
|
||||
class SCP_IDumpHandler abstract
|
||||
{
|
||||
public:
|
||||
virtual bool ResolveSymbols( ) PURE;
|
||||
virtual void OnBegin( ) PURE;
|
||||
virtual void OnEntry( void* address, const char* module, const char* symbol ) PURE;
|
||||
virtual void OnError( const char* error ) PURE;
|
||||
virtual void OnEnd( ) PURE;
|
||||
};
|
||||
|
||||
extern HRESULT SCP_DumpStack( SCP_IDumpHandler* pISH );
|
||||
|
||||
/* INTERNAL - please don't use these */
|
||||
#define SCP_MSPDBCS_MAX_SYMBOL_LENGTH 1000
|
||||
#define SCP_MSPDBCS_MAX_MODULE_LENGTH _MAX_PATH
|
||||
#define SCP_MSPDBCS_MAX_STACK_FRAMES 100 /* arbitrary */
|
||||
|
||||
struct SCP_mspdbcs_SDumpStackThreadInfo
|
||||
{
|
||||
HANDLE hThread;
|
||||
HANDLE hProcess;
|
||||
SCP_IDumpHandler* pIDS;
|
||||
};
|
||||
|
||||
struct SCP_mspdbcs_SDumpStackSymbolInfo
|
||||
{
|
||||
ULONG_PTR dwAddress;
|
||||
DWORD64 dwOffset; /* Will be truncated to DWORD under Win32 */
|
||||
char szModule[ SCP_MSPDBCS_MAX_MODULE_LENGTH ];
|
||||
char szSymbol[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
};
|
||||
|
||||
/* INTERNAL FUNCTIONS */
|
||||
extern BOOL SCP_mspdbcs_ResolveSymbol( HANDLE hProcess, UINT_PTR dwAddress, SCP_mspdbcs_SDumpStackThreadInfo& siSymbol );
|
||||
extern LPVOID __stdcall SCP_mspdbcs_FunctionTableAccess( HANDLE hProcess, DWORD64 dwPCAddress );
|
||||
extern DWORD64 __stdcall SCP_mspdbcs_GetModuleBase( HANDLE hProcess, DWORD64 returnAddress );
|
||||
extern DWORD WINAPI SCP_mspdbcs_DumpStackThread( LPVOID pv );
|
||||
|
||||
#endif // PDB_DEBUGGING
|
||||
|
||||
/* Initialisation */
|
||||
extern void SCP_mspdbcs_Initialise( );
|
||||
extern void SCP_mspdbcs_Cleanup( );
|
||||
|
||||
/* This file contains debugging utilities used only under VC2005+
|
||||
* Maintained by: portej05 (please run patches past him before committing here!)
|
||||
*/
|
||||
|
||||
/* You will need to define PDB_DEBUGGING in order to use these functions
|
||||
* Important note:
|
||||
* When you call SCP_DumpStack, your thread will be suspended until the stack is dumped
|
||||
* If you've got more than a single thread
|
||||
*/
|
||||
|
||||
/* Things you should be using from this header
|
||||
* SCP_IDumpHandler - implement this in order to receive symbols from DumpStack
|
||||
*/
|
||||
|
||||
#ifndef _MSPDB_CALLSTACK_H_INCLUDED_
|
||||
#define _MSPDB_CALLSTACK_H_INCLUDED_
|
||||
|
||||
#if defined(PDB_DEBUGGING)
|
||||
|
||||
/* Must have windows.h */
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef PURE
|
||||
# define PURE = 0
|
||||
#endif
|
||||
|
||||
/* PUBLIC - use these */
|
||||
|
||||
/* This interface will be used by the stack tracing code
|
||||
* to return symbols
|
||||
*/
|
||||
class SCP_IDumpHandler abstract
|
||||
{
|
||||
public:
|
||||
virtual bool ResolveSymbols( ) PURE;
|
||||
virtual void OnBegin( ) PURE;
|
||||
virtual void OnEntry( void* address, const char* module, const char* symbol ) PURE;
|
||||
virtual void OnError( const char* error ) PURE;
|
||||
virtual void OnEnd( ) PURE;
|
||||
};
|
||||
|
||||
extern HRESULT SCP_DumpStack( SCP_IDumpHandler* pISH );
|
||||
|
||||
/* INTERNAL - please don't use these */
|
||||
#define SCP_MSPDBCS_MAX_SYMBOL_LENGTH 1000
|
||||
#define SCP_MSPDBCS_MAX_MODULE_LENGTH _MAX_PATH
|
||||
#define SCP_MSPDBCS_MAX_STACK_FRAMES 100 /* arbitrary */
|
||||
|
||||
struct SCP_mspdbcs_SDumpStackThreadInfo
|
||||
{
|
||||
HANDLE hThread;
|
||||
HANDLE hProcess;
|
||||
SCP_IDumpHandler* pIDS;
|
||||
};
|
||||
|
||||
struct SCP_mspdbcs_SDumpStackSymbolInfo
|
||||
{
|
||||
ULONG_PTR dwAddress;
|
||||
DWORD64 dwOffset; /* Will be truncated to DWORD under Win32 */
|
||||
char szModule[ SCP_MSPDBCS_MAX_MODULE_LENGTH ];
|
||||
char szSymbol[ SCP_MSPDBCS_MAX_SYMBOL_LENGTH ];
|
||||
};
|
||||
|
||||
/* INTERNAL FUNCTIONS */
|
||||
extern BOOL SCP_mspdbcs_ResolveSymbol( HANDLE hProcess, UINT_PTR dwAddress, SCP_mspdbcs_SDumpStackThreadInfo& siSymbol );
|
||||
extern LPVOID __stdcall SCP_mspdbcs_FunctionTableAccess( HANDLE hProcess, DWORD64 dwPCAddress );
|
||||
extern DWORD64 __stdcall SCP_mspdbcs_GetModuleBase( HANDLE hProcess, DWORD64 returnAddress );
|
||||
extern DWORD WINAPI SCP_mspdbcs_DumpStackThread( LPVOID pv );
|
||||
|
||||
#endif // PDB_DEBUGGING
|
||||
|
||||
/* Initialisation */
|
||||
extern void SCP_mspdbcs_Initialise( );
|
||||
extern void SCP_mspdbcs_Cleanup( );
|
||||
|
||||
#endif // _MSPDB_CALLSTACK_H_INCLUDED_
|
||||
@@ -0,0 +1,305 @@
|
||||
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006 Alexander Chemeris
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The name of the author may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_INTTYPES_H_ // [
|
||||
#define _MSC_INTTYPES_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
// 7.8 Format conversion of integer types
|
||||
|
||||
typedef struct {
|
||||
intmax_t quot;
|
||||
intmax_t rem;
|
||||
} imaxdiv_t;
|
||||
|
||||
// 7.8.1 Macros for format specifiers
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
|
||||
|
||||
// The fprintf macros for signed integers are:
|
||||
#define PRId8 "d"
|
||||
#define PRIi8 "i"
|
||||
#define PRIdLEAST8 "d"
|
||||
#define PRIiLEAST8 "i"
|
||||
#define PRIdFAST8 "d"
|
||||
#define PRIiFAST8 "i"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIdLEAST16 "hd"
|
||||
#define PRIiLEAST16 "hi"
|
||||
#define PRIdFAST16 "hd"
|
||||
#define PRIiFAST16 "hi"
|
||||
|
||||
#define PRId32 "I32d"
|
||||
#define PRIi32 "I32i"
|
||||
#define PRIdLEAST32 "I32d"
|
||||
#define PRIiLEAST32 "I32i"
|
||||
#define PRIdFAST32 "I32d"
|
||||
#define PRIiFAST32 "I32i"
|
||||
|
||||
#define PRId64 "I64d"
|
||||
#define PRIi64 "I64i"
|
||||
#define PRIdLEAST64 "I64d"
|
||||
#define PRIiLEAST64 "I64i"
|
||||
#define PRIdFAST64 "I64d"
|
||||
#define PRIiFAST64 "I64i"
|
||||
|
||||
#define PRIdMAX "I64d"
|
||||
#define PRIiMAX "I64i"
|
||||
|
||||
#define PRIdPTR "Id"
|
||||
#define PRIiPTR "Ii"
|
||||
|
||||
// The fprintf macros for unsigned integers are:
|
||||
#define PRIo8 "o"
|
||||
#define PRIu8 "u"
|
||||
#define PRIx8 "x"
|
||||
#define PRIX8 "X"
|
||||
#define PRIoLEAST8 "o"
|
||||
#define PRIuLEAST8 "u"
|
||||
#define PRIxLEAST8 "x"
|
||||
#define PRIXLEAST8 "X"
|
||||
#define PRIoFAST8 "o"
|
||||
#define PRIuFAST8 "u"
|
||||
#define PRIxFAST8 "x"
|
||||
#define PRIXFAST8 "X"
|
||||
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
#define PRIoLEAST16 "ho"
|
||||
#define PRIuLEAST16 "hu"
|
||||
#define PRIxLEAST16 "hx"
|
||||
#define PRIXLEAST16 "hX"
|
||||
#define PRIoFAST16 "ho"
|
||||
#define PRIuFAST16 "hu"
|
||||
#define PRIxFAST16 "hx"
|
||||
#define PRIXFAST16 "hX"
|
||||
|
||||
#define PRIo32 "I32o"
|
||||
#define PRIu32 "I32u"
|
||||
#define PRIx32 "I32x"
|
||||
#define PRIX32 "I32X"
|
||||
#define PRIoLEAST32 "I32o"
|
||||
#define PRIuLEAST32 "I32u"
|
||||
#define PRIxLEAST32 "I32x"
|
||||
#define PRIXLEAST32 "I32X"
|
||||
#define PRIoFAST32 "I32o"
|
||||
#define PRIuFAST32 "I32u"
|
||||
#define PRIxFAST32 "I32x"
|
||||
#define PRIXFAST32 "I32X"
|
||||
|
||||
#define PRIo64 "I64o"
|
||||
#define PRIu64 "I64u"
|
||||
#define PRIx64 "I64x"
|
||||
#define PRIX64 "I64X"
|
||||
#define PRIoLEAST64 "I64o"
|
||||
#define PRIuLEAST64 "I64u"
|
||||
#define PRIxLEAST64 "I64x"
|
||||
#define PRIXLEAST64 "I64X"
|
||||
#define PRIoFAST64 "I64o"
|
||||
#define PRIuFAST64 "I64u"
|
||||
#define PRIxFAST64 "I64x"
|
||||
#define PRIXFAST64 "I64X"
|
||||
|
||||
#define PRIoMAX "I64o"
|
||||
#define PRIuMAX "I64u"
|
||||
#define PRIxMAX "I64x"
|
||||
#define PRIXMAX "I64X"
|
||||
|
||||
#define PRIoPTR "Io"
|
||||
#define PRIuPTR "Iu"
|
||||
#define PRIxPTR "Ix"
|
||||
#define PRIXPTR "IX"
|
||||
|
||||
// The fscanf macros for signed integers are:
|
||||
#define SCNd8 "d"
|
||||
#define SCNi8 "i"
|
||||
#define SCNdLEAST8 "d"
|
||||
#define SCNiLEAST8 "i"
|
||||
#define SCNdFAST8 "d"
|
||||
#define SCNiFAST8 "i"
|
||||
|
||||
#define SCNd16 "hd"
|
||||
#define SCNi16 "hi"
|
||||
#define SCNdLEAST16 "hd"
|
||||
#define SCNiLEAST16 "hi"
|
||||
#define SCNdFAST16 "hd"
|
||||
#define SCNiFAST16 "hi"
|
||||
|
||||
#define SCNd32 "ld"
|
||||
#define SCNi32 "li"
|
||||
#define SCNdLEAST32 "ld"
|
||||
#define SCNiLEAST32 "li"
|
||||
#define SCNdFAST32 "ld"
|
||||
#define SCNiFAST32 "li"
|
||||
|
||||
#define SCNd64 "I64d"
|
||||
#define SCNi64 "I64i"
|
||||
#define SCNdLEAST64 "I64d"
|
||||
#define SCNiLEAST64 "I64i"
|
||||
#define SCNdFAST64 "I64d"
|
||||
#define SCNiFAST64 "I64i"
|
||||
|
||||
#define SCNdMAX "I64d"
|
||||
#define SCNiMAX "I64i"
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define SCNdPTR "I64d"
|
||||
# define SCNiPTR "I64i"
|
||||
#else // _WIN64 ][
|
||||
# define SCNdPTR "ld"
|
||||
# define SCNiPTR "li"
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// The fscanf macros for unsigned integers are:
|
||||
#define SCNo8 "o"
|
||||
#define SCNu8 "u"
|
||||
#define SCNx8 "x"
|
||||
#define SCNX8 "X"
|
||||
#define SCNoLEAST8 "o"
|
||||
#define SCNuLEAST8 "u"
|
||||
#define SCNxLEAST8 "x"
|
||||
#define SCNXLEAST8 "X"
|
||||
#define SCNoFAST8 "o"
|
||||
#define SCNuFAST8 "u"
|
||||
#define SCNxFAST8 "x"
|
||||
#define SCNXFAST8 "X"
|
||||
|
||||
#define SCNo16 "ho"
|
||||
#define SCNu16 "hu"
|
||||
#define SCNx16 "hx"
|
||||
#define SCNX16 "hX"
|
||||
#define SCNoLEAST16 "ho"
|
||||
#define SCNuLEAST16 "hu"
|
||||
#define SCNxLEAST16 "hx"
|
||||
#define SCNXLEAST16 "hX"
|
||||
#define SCNoFAST16 "ho"
|
||||
#define SCNuFAST16 "hu"
|
||||
#define SCNxFAST16 "hx"
|
||||
#define SCNXFAST16 "hX"
|
||||
|
||||
#define SCNo32 "lo"
|
||||
#define SCNu32 "lu"
|
||||
#define SCNx32 "lx"
|
||||
#define SCNX32 "lX"
|
||||
#define SCNoLEAST32 "lo"
|
||||
#define SCNuLEAST32 "lu"
|
||||
#define SCNxLEAST32 "lx"
|
||||
#define SCNXLEAST32 "lX"
|
||||
#define SCNoFAST32 "lo"
|
||||
#define SCNuFAST32 "lu"
|
||||
#define SCNxFAST32 "lx"
|
||||
#define SCNXFAST32 "lX"
|
||||
|
||||
#define SCNo64 "I64o"
|
||||
#define SCNu64 "I64u"
|
||||
#define SCNx64 "I64x"
|
||||
#define SCNX64 "I64X"
|
||||
#define SCNoLEAST64 "I64o"
|
||||
#define SCNuLEAST64 "I64u"
|
||||
#define SCNxLEAST64 "I64x"
|
||||
#define SCNXLEAST64 "I64X"
|
||||
#define SCNoFAST64 "I64o"
|
||||
#define SCNuFAST64 "I64u"
|
||||
#define SCNxFAST64 "I64x"
|
||||
#define SCNXFAST64 "I64X"
|
||||
|
||||
#define SCNoMAX "I64o"
|
||||
#define SCNuMAX "I64u"
|
||||
#define SCNxMAX "I64x"
|
||||
#define SCNXMAX "I64X"
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define SCNoPTR "I64o"
|
||||
# define SCNuPTR "I64u"
|
||||
# define SCNxPTR "I64x"
|
||||
# define SCNXPTR "I64X"
|
||||
#else // _WIN64 ][
|
||||
# define SCNoPTR "lo"
|
||||
# define SCNuPTR "lu"
|
||||
# define SCNxPTR "lx"
|
||||
# define SCNXPTR "lX"
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#endif // __STDC_FORMAT_MACROS ]
|
||||
|
||||
// 7.8.2 Functions for greatest-width integer types
|
||||
|
||||
// 7.8.2.1 The imaxabs function
|
||||
#define imaxabs _abs64
|
||||
|
||||
// 7.8.2.2 The imaxdiv function
|
||||
|
||||
// This is modified version of div() function from Microsoft's div.c found
|
||||
// in %MSVC.NET%\crt\src\div.c
|
||||
#ifdef STATIC_IMAXDIV // [
|
||||
static
|
||||
#else // STATIC_IMAXDIV ][
|
||||
_inline
|
||||
#endif // STATIC_IMAXDIV ]
|
||||
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
|
||||
{
|
||||
imaxdiv_t result;
|
||||
|
||||
result.quot = numer / denom;
|
||||
result.rem = numer % denom;
|
||||
|
||||
if (numer < 0 && result.rem > 0) {
|
||||
// did division wrong; must fix up
|
||||
++result.quot;
|
||||
result.rem -= denom;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7.8.2.3 The strtoimax and strtoumax functions
|
||||
#define strtoimax _strtoi64
|
||||
#define strtoumax _strtoui64
|
||||
|
||||
// 7.8.2.4 The wcstoimax and wcstoumax functions
|
||||
#define wcstoimax _wcstoi64
|
||||
#define wcstoumax _wcstoui64
|
||||
|
||||
|
||||
#endif // _MSC_INTTYPES_H_ ]
|
||||
@@ -0,0 +1,247 @@
|
||||
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006-2008 Alexander Chemeris
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The name of the author may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_STDINT_H_ // [
|
||||
#define _MSC_STDINT_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler give many errors like this:
|
||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
#ifdef __cplusplus
|
||||
extern "C++" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// 7.18.1 Integer types
|
||||
|
||||
// 7.18.1.1 Exact-width integer types
|
||||
|
||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
// realize that, e.g. char has the same size as __int8
|
||||
// so we give up on __intX for them.
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
// 7.18.1.2 Minimum-width integer types
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
// 7.18.1.3 Fastest minimum-width integer types
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
// 7.18.1.4 Integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else // _WIN64 ][
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.1.5 Greatest-width integer types
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
|
||||
// 7.18.2 Limits of specified-width integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||
|
||||
// 7.18.2.1 Limits of exact-width integer types
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
// 7.18.2.2 Limits of minimum-width integer types
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.2.5 Limits of greatest-width integer types
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
// 7.18.3 Limits of other integer types
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX // [
|
||||
# ifdef _WIN64 // [
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else // _WIN64 ][
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif // _WIN64 ]
|
||||
#endif // SIZE_MAX ]
|
||||
|
||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||
#ifndef WCHAR_MIN // [
|
||||
# define WCHAR_MIN 0
|
||||
#endif // WCHAR_MIN ]
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif // WCHAR_MAX ]
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif // __STDC_LIMIT_MACROS ]
|
||||
|
||||
|
||||
// 7.18.4 Limits of other integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||
|
||||
// 7.18.4.1 Macros for minimum-width integer constants
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
// 7.18.4.2 Macros for greatest-width integer constants
|
||||
#define INTMAX_C INT64_C
|
||||
#define UINTMAX_C UINT64_C
|
||||
|
||||
#endif // __STDC_CONSTANT_MACROS ]
|
||||
|
||||
|
||||
#endif // _MSC_STDINT_H_ ]
|
||||
@@ -247,8 +247,6 @@ extern int Global_error_count;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//#define Int3() _asm { int 3 }
|
||||
|
||||
#if defined(NDEBUG)
|
||||
// No debug version of Int3
|
||||
#define Int3() do { } while (0)
|
||||
|
||||
+100
-100
@@ -1,100 +1,100 @@
|
||||
#ifndef _SAFE_STRINGS_H_INCLUDED_
|
||||
#define _SAFE_STRINGS_H_INCLUDED_
|
||||
|
||||
/* It is a condition of use that safe_strings.cpp, safe_strings.h, safe_strings_test.cpp remain together.
|
||||
*
|
||||
* Maintained by portej05 - contact via PM on www.hard-light.net/forums
|
||||
* Why have we got this, what is it for?
|
||||
* VC2005+ define some safe string functions which check buffer sizes before doing anything
|
||||
* Unfortunately, GCC and MACOS do not provide these functions, therefore, we must!
|
||||
* (if only to reduce the amount of noise the static analysis tools are spitting out)
|
||||
* They are part of ISO/IEC TR 24731 and may find their way into the CRTs at some point, at which
|
||||
* point these functions must be removed from the engine.
|
||||
* While these functions do not add a huge amount of benefit for heap-allocated strings, they
|
||||
* can protect against a class of buffer overruns in stack allocated situations.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Include logic:
|
||||
* Used unless we have VC6
|
||||
*/
|
||||
|
||||
/* errno_t, EINVAL, ERANGE, etc.. */
|
||||
#include <errno.h>
|
||||
#include <stdlib.h> /* size_t */
|
||||
|
||||
/* Because errno_t is not (yet) standard, we define it here like this */
|
||||
typedef int errno_t;
|
||||
|
||||
#if ( !defined( _MSC_VER ) && !defined(NO_SAFE_STRINGS) ) || defined( _MSC_VER ) && _MSC_VER >= 1400 /*&& !defined(NDEBUG)*/ && !defined(NO_SAFE_STRINGS)
|
||||
|
||||
/* In order to compile safe_strings_test.cpp, you must have this defined on the command line */
|
||||
/* #define SAFESTRINGS_TEST_APP */
|
||||
|
||||
/* Unlike their CRT counterparts, these do not call the invalid parameter handler
|
||||
* However, they do call this macro
|
||||
*/
|
||||
#ifndef SAFESTRINGS_TEST_APP
|
||||
|
||||
# ifndef __safe_strings_error_handler
|
||||
# define __safe_strings_error_handler( val ) Error(file, line,"%s: String error. Please Report.\nTrying to put into %d byte buffer:\n%s", #val, sizeInBytes,strSource)
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
/* For testing only */
|
||||
# define __safe_strings_error_handler( errnoVal ) extern void error_handler( int errnoValue, const char* errnoStr, const char* file, const char* function, int line );\
|
||||
error_handler( errnoVal, #errnoVal, __FILE__, __FUNCTION__, __LINE__ );
|
||||
#endif
|
||||
|
||||
extern errno_t scp_strcpy_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource );
|
||||
extern errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource );
|
||||
|
||||
template< size_t size>
|
||||
inline
|
||||
errno_t scp_strcpy_s( const char* file, int line, char (&strDest)[ size ], const char* strSource )
|
||||
{
|
||||
return scp_strcpy_s( file, line, strDest, size, strSource );
|
||||
}
|
||||
|
||||
template< size_t size >
|
||||
inline
|
||||
errno_t scp_strcat_s( const char* file, int line, char (&strDest)[ size ], const char* strSource )
|
||||
{
|
||||
return scp_strcat_s( file, line, strDest, size, strSource );
|
||||
}
|
||||
|
||||
#define strcpy_s( ... ) scp_strcpy_s( __FILE__, __LINE__, __VA_ARGS__ )
|
||||
#define strcat_s( ... ) scp_strcat_s( __FILE__, __LINE__, __VA_ARGS__ )
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1400 || defined(NO_SAFE_STRINGS)
|
||||
|
||||
#pragma message("safe_strings disabled - this is not good!")
|
||||
|
||||
inline errno_t strcpy_s( char* strDest, size_t sizeInBytes, const char* strSource )
|
||||
{
|
||||
strcpy( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline errno_t strcat_s( char* strDest, size_t sizeInBytes, const char* strSource )
|
||||
{
|
||||
strcat( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline errno_t strcpy_s( char* strDest, const char* strSource )
|
||||
{
|
||||
strcpy( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline errno_t strcat_s( char* strDest, const char* strSource )
|
||||
{
|
||||
strcat( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _SAFE_STRINGS_H_INCLUDED_
|
||||
#ifndef _SAFE_STRINGS_H_INCLUDED_
|
||||
#define _SAFE_STRINGS_H_INCLUDED_
|
||||
|
||||
/* It is a condition of use that safe_strings.cpp, safe_strings.h, safe_strings_test.cpp remain together.
|
||||
*
|
||||
* Maintained by portej05 - contact via PM on www.hard-light.net/forums
|
||||
* Why have we got this, what is it for?
|
||||
* VC2005+ define some safe string functions which check buffer sizes before doing anything
|
||||
* Unfortunately, GCC and MACOS do not provide these functions, therefore, we must!
|
||||
* (if only to reduce the amount of noise the static analysis tools are spitting out)
|
||||
* They are part of ISO/IEC TR 24731 and may find their way into the CRTs at some point, at which
|
||||
* point these functions must be removed from the engine.
|
||||
* While these functions do not add a huge amount of benefit for heap-allocated strings, they
|
||||
* can protect against a class of buffer overruns in stack allocated situations.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Include logic:
|
||||
* Used unless we have VC6
|
||||
*/
|
||||
|
||||
/* errno_t, EINVAL, ERANGE, etc.. */
|
||||
#include <errno.h>
|
||||
#include <stdlib.h> /* size_t */
|
||||
|
||||
/* Because errno_t is not (yet) standard, we define it here like this */
|
||||
typedef int errno_t;
|
||||
|
||||
#if ( !defined( _MSC_VER ) && !defined(NO_SAFE_STRINGS) ) || defined( _MSC_VER ) && _MSC_VER >= 1400 /*&& !defined(NDEBUG)*/ && !defined(NO_SAFE_STRINGS)
|
||||
|
||||
/* In order to compile safe_strings_test.cpp, you must have this defined on the command line */
|
||||
/* #define SAFESTRINGS_TEST_APP */
|
||||
|
||||
/* Unlike their CRT counterparts, these do not call the invalid parameter handler
|
||||
* However, they do call this macro
|
||||
*/
|
||||
#ifndef SAFESTRINGS_TEST_APP
|
||||
|
||||
# ifndef __safe_strings_error_handler
|
||||
# define __safe_strings_error_handler( val ) Error(file, line,"%s: String error. Please Report.\nTrying to put into %d byte buffer:\n%s", #val, sizeInBytes,strSource)
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
/* For testing only */
|
||||
# define __safe_strings_error_handler( errnoVal ) extern void error_handler( int errnoValue, const char* errnoStr, const char* file, const char* function, int line );\
|
||||
error_handler( errnoVal, #errnoVal, __FILE__, __FUNCTION__, __LINE__ );
|
||||
#endif
|
||||
|
||||
extern errno_t scp_strcpy_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource );
|
||||
extern errno_t scp_strcat_s( const char* file, int line, char* strDest, size_t sizeInBytes, const char* strSource );
|
||||
|
||||
template< size_t size>
|
||||
inline
|
||||
errno_t scp_strcpy_s( const char* file, int line, char (&strDest)[ size ], const char* strSource )
|
||||
{
|
||||
return scp_strcpy_s( file, line, strDest, size, strSource );
|
||||
}
|
||||
|
||||
template< size_t size >
|
||||
inline
|
||||
errno_t scp_strcat_s( const char* file, int line, char (&strDest)[ size ], const char* strSource )
|
||||
{
|
||||
return scp_strcat_s( file, line, strDest, size, strSource );
|
||||
}
|
||||
|
||||
#define strcpy_s( ... ) scp_strcpy_s( __FILE__, __LINE__, __VA_ARGS__ )
|
||||
#define strcat_s( ... ) scp_strcat_s( __FILE__, __LINE__, __VA_ARGS__ )
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1400 || defined(NO_SAFE_STRINGS)
|
||||
|
||||
#pragma message("safe_strings disabled - this is not good!")
|
||||
|
||||
inline errno_t strcpy_s( char* strDest, size_t sizeInBytes, const char* strSource )
|
||||
{
|
||||
strcpy( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline errno_t strcat_s( char* strDest, size_t sizeInBytes, const char* strSource )
|
||||
{
|
||||
strcat( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline errno_t strcpy_s( char* strDest, const char* strSource )
|
||||
{
|
||||
strcpy( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline errno_t strcat_s( char* strDest, const char* strSource )
|
||||
{
|
||||
strcat( strDest, strSource );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _SAFE_STRINGS_H_INCLUDED_
|
||||
@@ -1,255 +1,255 @@
|
||||
/* It is a condition of use that safe_strings.cpp, safe_strings.h, safe_strings_test.cpp remain together.
|
||||
*
|
||||
* Maintained by portej05 - contact via PM on www.hard-light.net/forums
|
||||
* Why have we got this, what is it for?
|
||||
* VC2005+ define some safe string functions which check buffer sizes before doing anything
|
||||
* Unfortunately, GCC and MACOS do not provide these functions, therefore, we must!
|
||||
* (if only to reduce the amount of noise the static analysis tools are spitting out)
|
||||
* They are part of ISO/IEC TR 24731 and may find their way into the CRTs at some point, at which
|
||||
* point these functions must be removed from the engine.
|
||||
* While these functions do not add a huge amount of benefit for heap-allocated strings, they
|
||||
* can protect against a class of buffer overruns in stack allocated situations.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef SAFESTRINGS_TEST_APP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "safe_strings.h"
|
||||
|
||||
int last_errno = 0;
|
||||
void error_handler( int errnoValue, const char* errnoStr, const char* file, const char* function, int line )
|
||||
{
|
||||
last_errno = errnoValue;
|
||||
(errnoStr);
|
||||
(file);
|
||||
(function);
|
||||
(line);
|
||||
}
|
||||
|
||||
#define _RESET_ERRNO( ) last_errno = 0
|
||||
|
||||
#define _EXPECTED_ERRNO( errnoVal ) if ( last_errno != errnoVal ) printf("errno value of %d not found: %d %s(%d)\n",errnoVal,last_errno,__FILE__,__LINE__)
|
||||
#define _EXPECTED_LAST_ERRNO( errnoVal ) _EXPECTED_ERRNO( errnoVal )
|
||||
#define _EXPECTED_RETURN( value, function ) if ( function != value ) printf("expected value not received: %s(%d)\n", __FILE__,__LINE__)
|
||||
|
||||
#define _EXPECTED_STRING( str, value ) if ( !strcmp( str, value ) ) printf("strings do not match: %s(%d)\n", __FILE__, __LINE__)
|
||||
#define _EXPECTED_VALUE( val, value ) if ( val != value ) printf("values do not match: %s(%d)\n", __FILE__, __LINE__ )
|
||||
|
||||
/* Dumb memset (because we can't include string.h in this program) */
|
||||
void dumb_memset( void* buf, char val, size_t bytes )
|
||||
{
|
||||
char* p = (char*)buf;
|
||||
|
||||
while ( bytes-- )
|
||||
{
|
||||
*(p++) = val;
|
||||
}
|
||||
}
|
||||
|
||||
bool strcmp( const char* str1, const char* str2 )
|
||||
{
|
||||
while ( *str1 && *str2 )
|
||||
{
|
||||
if ( *str1 != *str2 )
|
||||
return false;
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
return ( !*str1 && !*str2 );
|
||||
}
|
||||
|
||||
void test_strcpy_s( )
|
||||
{
|
||||
#define _RESET_STRINGS( ) dumb_memset( strSource, 0, 15 );\
|
||||
dumb_memset( strDest, 0, 15 );
|
||||
|
||||
char strSource[ 15 ];
|
||||
char strDest[ 15 ];
|
||||
|
||||
/* strcpy_s tests
|
||||
* Must test both strcpy_s functions (even though one calls the other)
|
||||
* 1) Copy string into larger buffer
|
||||
* - Expecting buffer to contain string + NULL
|
||||
* 2) Attempt to copy string into too small buffer
|
||||
* - strDest[0] = NULL
|
||||
* - calls __safe_strings_error_handler with ERANGE
|
||||
* - returns ERANGE
|
||||
* 3) strSource = NULL
|
||||
* - returns EINVAL
|
||||
* - calls __safe_strings_error_handler with EINVAL
|
||||
* - strDest[0] = NULL
|
||||
* 4) strDest = NULL
|
||||
* - calls __safe_strings_error_handler with EINVAL
|
||||
* - returns EINVAL
|
||||
* 5) strSource = NULL, strDest = NULL
|
||||
* - calls __safe_strings_error_handler with EINVAL
|
||||
* - returns EINVAL
|
||||
* 6) sizeInBytes = 0
|
||||
* - calls __safe_strings_error_handler with ERANGE
|
||||
* - returns ERANGE
|
||||
* 7) A string with the size+NULL the same as the size of the buffer
|
||||
* - returns 0
|
||||
* - strDest should contain the string
|
||||
*/
|
||||
|
||||
_RESET_ERRNO( );
|
||||
|
||||
/* 1 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_STRING( strDest, "Hello World" );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_STRING( strDest, "Hello World" );
|
||||
|
||||
|
||||
/* 2 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( ERANGE, strcpy_s( strDest, "Hello World, this is a test" ) );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( ERANGE, strcpy_s( strDest, 15, "Hello World, this is a test" ) );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
/* 3 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( strDest, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( strDest, 15, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 4 - can't be done on template version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( NULL, 15, "Hello World" ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 5 - can't be done on template version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( NULL, 15, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 6 - can't be done on strcpy_s template version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( ERANGE, strcpy_s( strDest, 0, "Hello World") );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
|
||||
/* 7 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello World th" ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
|
||||
#undef _RESET_STRINGS
|
||||
}
|
||||
|
||||
void test_strcat_s( )
|
||||
{
|
||||
#define _RESET_STRINGS( ) dumb_memset( strSource, 0, 15 );\
|
||||
dumb_memset( strDest, 0, 15 );
|
||||
|
||||
char strSource[ 15 ];
|
||||
char strDest[ 15 ];
|
||||
|
||||
/* Test cases for strcat_s
|
||||
* 1) Normal concatenation where total string size < buffersize -1
|
||||
* - No change in errno (i.e. handler is not called)
|
||||
* - returns 0
|
||||
* 2) strSource = NULL, sizeInBytes != 0, strDest != NULL
|
||||
* - errno now EINVAL
|
||||
* - strDest[ 0 ] == NULL
|
||||
* - returns EINVAL
|
||||
* 3) strSource != NULL, sizeInBytes != 0, strDest == NULL
|
||||
* - errno now EINVAL
|
||||
* - returns EINVAL
|
||||
* 4) sizeInBytes = 0
|
||||
* - errno now ERANGE
|
||||
* - returns ERANGE
|
||||
* 5) final string that is 15 chars+null
|
||||
* - returns 0
|
||||
* - no change in errno
|
||||
*/
|
||||
|
||||
_RESET_ERRNO( );
|
||||
|
||||
/* 1 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_RETURN( 0, strcat_s( strDest, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_RETURN( 0, strcat_s( strDest, 15, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
|
||||
/* 2 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0);
|
||||
_EXPECTED_RETURN( EINVAL, strcat_s( strDest, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( EINVAL );
|
||||
_EXPECTED_RETURN( EINVAL, strcat_s( strDest, 15, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
/* 3 - can't be done with templated version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strSource, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( EINVAL );
|
||||
_EXPECTED_RETURN( EINVAL, strcat_s( NULL, 15, strSource ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 4 - can't be done with templated version*/
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( EINVAL );
|
||||
_EXPECTED_RETURN( ERANGE, strcat_s( strDest, 0, "World" ) );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
|
||||
/* 5 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "World th" ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "World th" ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
|
||||
#undef _RESET_STRINGS
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
(argc);
|
||||
(argv);
|
||||
|
||||
test_strcpy_s( );
|
||||
test_strcat_s( );
|
||||
|
||||
printf("done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* It is a condition of use that safe_strings.cpp, safe_strings.h, safe_strings_test.cpp remain together.
|
||||
*
|
||||
* Maintained by portej05 - contact via PM on www.hard-light.net/forums
|
||||
* Why have we got this, what is it for?
|
||||
* VC2005+ define some safe string functions which check buffer sizes before doing anything
|
||||
* Unfortunately, GCC and MACOS do not provide these functions, therefore, we must!
|
||||
* (if only to reduce the amount of noise the static analysis tools are spitting out)
|
||||
* They are part of ISO/IEC TR 24731 and may find their way into the CRTs at some point, at which
|
||||
* point these functions must be removed from the engine.
|
||||
* While these functions do not add a huge amount of benefit for heap-allocated strings, they
|
||||
* can protect against a class of buffer overruns in stack allocated situations.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef SAFESTRINGS_TEST_APP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "safe_strings.h"
|
||||
|
||||
int last_errno = 0;
|
||||
void error_handler( int errnoValue, const char* errnoStr, const char* file, const char* function, int line )
|
||||
{
|
||||
last_errno = errnoValue;
|
||||
(errnoStr);
|
||||
(file);
|
||||
(function);
|
||||
(line);
|
||||
}
|
||||
|
||||
#define _RESET_ERRNO( ) last_errno = 0
|
||||
|
||||
#define _EXPECTED_ERRNO( errnoVal ) if ( last_errno != errnoVal ) printf("errno value of %d not found: %d %s(%d)\n",errnoVal,last_errno,__FILE__,__LINE__)
|
||||
#define _EXPECTED_LAST_ERRNO( errnoVal ) _EXPECTED_ERRNO( errnoVal )
|
||||
#define _EXPECTED_RETURN( value, function ) if ( function != value ) printf("expected value not received: %s(%d)\n", __FILE__,__LINE__)
|
||||
|
||||
#define _EXPECTED_STRING( str, value ) if ( !strcmp( str, value ) ) printf("strings do not match: %s(%d)\n", __FILE__, __LINE__)
|
||||
#define _EXPECTED_VALUE( val, value ) if ( val != value ) printf("values do not match: %s(%d)\n", __FILE__, __LINE__ )
|
||||
|
||||
/* Dumb memset (because we can't include string.h in this program) */
|
||||
void dumb_memset( void* buf, char val, size_t bytes )
|
||||
{
|
||||
char* p = (char*)buf;
|
||||
|
||||
while ( bytes-- )
|
||||
{
|
||||
*(p++) = val;
|
||||
}
|
||||
}
|
||||
|
||||
bool strcmp( const char* str1, const char* str2 )
|
||||
{
|
||||
while ( *str1 && *str2 )
|
||||
{
|
||||
if ( *str1 != *str2 )
|
||||
return false;
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
return ( !*str1 && !*str2 );
|
||||
}
|
||||
|
||||
void test_strcpy_s( )
|
||||
{
|
||||
#define _RESET_STRINGS( ) dumb_memset( strSource, 0, 15 );\
|
||||
dumb_memset( strDest, 0, 15 );
|
||||
|
||||
char strSource[ 15 ];
|
||||
char strDest[ 15 ];
|
||||
|
||||
/* strcpy_s tests
|
||||
* Must test both strcpy_s functions (even though one calls the other)
|
||||
* 1) Copy string into larger buffer
|
||||
* - Expecting buffer to contain string + NULL
|
||||
* 2) Attempt to copy string into too small buffer
|
||||
* - strDest[0] = NULL
|
||||
* - calls __safe_strings_error_handler with ERANGE
|
||||
* - returns ERANGE
|
||||
* 3) strSource = NULL
|
||||
* - returns EINVAL
|
||||
* - calls __safe_strings_error_handler with EINVAL
|
||||
* - strDest[0] = NULL
|
||||
* 4) strDest = NULL
|
||||
* - calls __safe_strings_error_handler with EINVAL
|
||||
* - returns EINVAL
|
||||
* 5) strSource = NULL, strDest = NULL
|
||||
* - calls __safe_strings_error_handler with EINVAL
|
||||
* - returns EINVAL
|
||||
* 6) sizeInBytes = 0
|
||||
* - calls __safe_strings_error_handler with ERANGE
|
||||
* - returns ERANGE
|
||||
* 7) A string with the size+NULL the same as the size of the buffer
|
||||
* - returns 0
|
||||
* - strDest should contain the string
|
||||
*/
|
||||
|
||||
_RESET_ERRNO( );
|
||||
|
||||
/* 1 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_STRING( strDest, "Hello World" );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_STRING( strDest, "Hello World" );
|
||||
|
||||
|
||||
/* 2 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( ERANGE, strcpy_s( strDest, "Hello World, this is a test" ) );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( ERANGE, strcpy_s( strDest, 15, "Hello World, this is a test" ) );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
/* 3 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( strDest, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( strDest, 15, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 4 - can't be done on template version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( NULL, 15, "Hello World" ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 5 - can't be done on template version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( EINVAL, strcpy_s( NULL, 15, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 6 - can't be done on strcpy_s template version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( ERANGE, strcpy_s( strDest, 0, "Hello World") );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
|
||||
/* 7 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello World th" ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
|
||||
#undef _RESET_STRINGS
|
||||
}
|
||||
|
||||
void test_strcat_s( )
|
||||
{
|
||||
#define _RESET_STRINGS( ) dumb_memset( strSource, 0, 15 );\
|
||||
dumb_memset( strDest, 0, 15 );
|
||||
|
||||
char strSource[ 15 ];
|
||||
char strDest[ 15 ];
|
||||
|
||||
/* Test cases for strcat_s
|
||||
* 1) Normal concatenation where total string size < buffersize -1
|
||||
* - No change in errno (i.e. handler is not called)
|
||||
* - returns 0
|
||||
* 2) strSource = NULL, sizeInBytes != 0, strDest != NULL
|
||||
* - errno now EINVAL
|
||||
* - strDest[ 0 ] == NULL
|
||||
* - returns EINVAL
|
||||
* 3) strSource != NULL, sizeInBytes != 0, strDest == NULL
|
||||
* - errno now EINVAL
|
||||
* - returns EINVAL
|
||||
* 4) sizeInBytes = 0
|
||||
* - errno now ERANGE
|
||||
* - returns ERANGE
|
||||
* 5) final string that is 15 chars+null
|
||||
* - returns 0
|
||||
* - no change in errno
|
||||
*/
|
||||
|
||||
_RESET_ERRNO( );
|
||||
|
||||
/* 1 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_RETURN( 0, strcat_s( strDest, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
_EXPECTED_RETURN( 0, strcat_s( strDest, 15, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0 );
|
||||
|
||||
/* 2 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( 0);
|
||||
_EXPECTED_RETURN( EINVAL, strcat_s( strDest, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "World" ) );
|
||||
_EXPECTED_LAST_ERRNO( EINVAL );
|
||||
_EXPECTED_RETURN( EINVAL, strcat_s( strDest, 15, NULL ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
_EXPECTED_VALUE( strDest[ 0 ], NULL );
|
||||
|
||||
/* 3 - can't be done with templated version */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strSource, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( EINVAL );
|
||||
_EXPECTED_RETURN( EINVAL, strcat_s( NULL, 15, strSource ) );
|
||||
_EXPECTED_ERRNO( EINVAL );
|
||||
|
||||
/* 4 - can't be done with templated version*/
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( EINVAL );
|
||||
_EXPECTED_RETURN( ERANGE, strcat_s( strDest, 0, "World" ) );
|
||||
_EXPECTED_ERRNO( ERANGE );
|
||||
|
||||
/* 5 */
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, "World th" ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
|
||||
_RESET_STRINGS( );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "Hello " ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
_EXPECTED_RETURN( 0, strcpy_s( strDest, 15, "World th" ) );
|
||||
_EXPECTED_LAST_ERRNO( ERANGE );
|
||||
|
||||
#undef _RESET_STRINGS
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
(argc);
|
||||
(argv);
|
||||
|
||||
test_strcpy_s( );
|
||||
test_strcat_s( );
|
||||
|
||||
printf("done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -36,8 +36,9 @@ float Cutscene_bars_progress = 1.0f;
|
||||
|
||||
//FADEIN STUFF
|
||||
shader Viewer_shader;
|
||||
int Fade_type = FI_NONE;
|
||||
float Fade_delta_time = 1.0f;
|
||||
FadeType Fade_type = FI_NONE;
|
||||
int Fade_start_timestamp = 0;
|
||||
int Fade_end_timestamp = 0;
|
||||
|
||||
// The detail level. Anything below zero draws simple models earlier than it
|
||||
// should. Anything above zero draws higher detail models longer than it should.
|
||||
|
||||
@@ -58,11 +58,15 @@ extern int Cutscene_bar_flags;
|
||||
//-----Fadein stuff
|
||||
struct shader;
|
||||
extern shader Viewer_shader;
|
||||
#define FI_NONE 0
|
||||
#define FI_FADEIN 1
|
||||
#define FI_FADEOUT 2
|
||||
extern float Fade_delta_time;
|
||||
extern int Fade_type;
|
||||
|
||||
enum FadeType {
|
||||
FI_NONE,
|
||||
FI_FADEIN,
|
||||
FI_FADEOUT
|
||||
};
|
||||
extern FadeType Fade_type;
|
||||
extern int Fade_start_timestamp;
|
||||
extern int Fade_end_timestamp;
|
||||
|
||||
|
||||
typedef struct vei {
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define FS_VERSION_MAJOR 3 // major version
|
||||
#define FS_VERSION_MINOR 6 // increase by 1 for minor revs
|
||||
#define FS_VERSION_BUILD 13 // bugfix release
|
||||
#define FS_VERSION_REVIS 0000 // SVN revision
|
||||
#define FS_VERSION_REVIS 9276 // SVN revision
|
||||
|
||||
#define VERSION_LOC_FNAME "version.nfo"
|
||||
#define MOTD_LOC_FNAME "motd.txt"
|
||||
|
||||
+134
-134
@@ -1,135 +1,135 @@
|
||||
#ifndef _VMALLOCATOR_H_INCLUDED_
|
||||
#define _VMALLOCATOR_H_INCLUDED_
|
||||
|
||||
/* SCP_vm_allocator - maintained by portej05 (i.e. please don't patch this one yourself!) */
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 || !defined(_MSC_VER)
|
||||
|
||||
#define DESTROY( type, p ) (p)->~type( )
|
||||
|
||||
template< typename T >
|
||||
class SCP_vm_allocator
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
|
||||
/* portej05 does not like this particular function. */
|
||||
void construct( pointer p, const T& value )
|
||||
{
|
||||
::new (p) T(value);
|
||||
}
|
||||
|
||||
void destroy( pointer p )
|
||||
{
|
||||
DESTROY( T, p );
|
||||
}
|
||||
|
||||
pointer allocate( size_type n )
|
||||
{
|
||||
if ( n == 0 )
|
||||
return NULL;
|
||||
return (pointer)vm_malloc( n * sizeof( T ) );
|
||||
}
|
||||
|
||||
template<class Other>
|
||||
pointer allocate( size_type n, const Other* hint = NULL )
|
||||
{
|
||||
(hint);
|
||||
return allocate( n );
|
||||
}
|
||||
|
||||
void deallocate( pointer p, size_type )
|
||||
{
|
||||
if ( p )
|
||||
vm_free( p );
|
||||
}
|
||||
|
||||
template< class U >
|
||||
struct rebind
|
||||
{
|
||||
typedef SCP_vm_allocator< U > other;
|
||||
};
|
||||
|
||||
size_type max_size( ) const
|
||||
{ // Estimate process used by MS STL
|
||||
size_type _Count = ( size_type )( -1 ) / sizeof ( T );
|
||||
return ( 0 < _Count ? _Count : 1 );
|
||||
}
|
||||
|
||||
template< class T2 >
|
||||
SCP_vm_allocator< T >& operator=( const SCP_vm_allocator<T2>& )
|
||||
{
|
||||
return (*this);
|
||||
}
|
||||
|
||||
SCP_vm_allocator( )
|
||||
{
|
||||
}
|
||||
|
||||
SCP_vm_allocator( const SCP_vm_allocator< T >& )
|
||||
{
|
||||
}
|
||||
|
||||
template< class T2 >
|
||||
SCP_vm_allocator( const SCP_vm_allocator< T2 >& )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class SCP_vector : public std::vector< T, SCP_vm_allocator< T > > { };
|
||||
|
||||
template< typename T >
|
||||
class SCP_list : public std::list< T, SCP_vm_allocator< T > > { };
|
||||
|
||||
typedef std::basic_string<char, std::char_traits<char>, SCP_vm_allocator<char> > SCP_string;
|
||||
|
||||
typedef std::basic_stringstream<char, std::char_traits<char>, SCP_vm_allocator<char> > SCP_stringstream;
|
||||
|
||||
template< typename T, typename U >
|
||||
class SCP_map : public std::map<T, U, std::less<T>, SCP_vm_allocator<std::pair<const T, U> > > { };
|
||||
|
||||
template< typename T, typename U >
|
||||
class SCP_multimap : public std::multimap<T, U, std::less<T>, SCP_vm_allocator<std::pair<const T, U> > > { };
|
||||
|
||||
template< typename T >
|
||||
class SCP_queue : public std::queue< T, 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()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator!=(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define SCP_string std::string
|
||||
#define SCP_stringstream std::stringstream
|
||||
#define SCP_map std::map
|
||||
#define SCP_multimap std::multimap
|
||||
#define SCP_queue std::queue
|
||||
#define SCP_vector std::vector
|
||||
#define SCP_list std::list
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _VMALLOCATOR_H_INCLUDED_
|
||||
#define _VMALLOCATOR_H_INCLUDED_
|
||||
|
||||
/* SCP_vm_allocator - maintained by portej05 (i.e. please don't patch this one yourself!) */
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 || !defined(_MSC_VER)
|
||||
|
||||
#define DESTROY( type, p ) (p)->~type( )
|
||||
|
||||
template< typename T >
|
||||
class SCP_vm_allocator
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
|
||||
/* portej05 does not like this particular function. */
|
||||
void construct( pointer p, const T& value )
|
||||
{
|
||||
::new (p) T(value);
|
||||
}
|
||||
|
||||
void destroy( pointer p )
|
||||
{
|
||||
DESTROY( T, p );
|
||||
}
|
||||
|
||||
pointer allocate( size_type n )
|
||||
{
|
||||
if ( n == 0 )
|
||||
return NULL;
|
||||
return (pointer)vm_malloc( n * sizeof( T ) );
|
||||
}
|
||||
|
||||
template<class Other>
|
||||
pointer allocate( size_type n, const Other* hint = NULL )
|
||||
{
|
||||
(hint);
|
||||
return allocate( n );
|
||||
}
|
||||
|
||||
void deallocate( pointer p, size_type )
|
||||
{
|
||||
if ( p )
|
||||
vm_free( p );
|
||||
}
|
||||
|
||||
template< class U >
|
||||
struct rebind
|
||||
{
|
||||
typedef SCP_vm_allocator< U > other;
|
||||
};
|
||||
|
||||
size_type max_size( ) const
|
||||
{ // Estimate process used by MS STL
|
||||
size_type _Count = ( size_type )( -1 ) / sizeof ( T );
|
||||
return ( 0 < _Count ? _Count : 1 );
|
||||
}
|
||||
|
||||
template< class T2 >
|
||||
SCP_vm_allocator< T >& operator=( const SCP_vm_allocator<T2>& )
|
||||
{
|
||||
return (*this);
|
||||
}
|
||||
|
||||
SCP_vm_allocator( )
|
||||
{
|
||||
}
|
||||
|
||||
SCP_vm_allocator( const SCP_vm_allocator< T >& )
|
||||
{
|
||||
}
|
||||
|
||||
template< class T2 >
|
||||
SCP_vm_allocator( const SCP_vm_allocator< T2 >& )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class SCP_vector : public std::vector< T, SCP_vm_allocator< T > > { };
|
||||
|
||||
template< typename T >
|
||||
class SCP_list : public std::list< T, SCP_vm_allocator< T > > { };
|
||||
|
||||
typedef std::basic_string<char, std::char_traits<char>, SCP_vm_allocator<char> > SCP_string;
|
||||
|
||||
typedef std::basic_stringstream<char, std::char_traits<char>, SCP_vm_allocator<char> > SCP_stringstream;
|
||||
|
||||
template< typename T, typename U >
|
||||
class SCP_map : public std::map<T, U, std::less<T>, SCP_vm_allocator<std::pair<const T, U> > > { };
|
||||
|
||||
template< typename T, typename U >
|
||||
class SCP_multimap : public std::multimap<T, U, std::less<T>, SCP_vm_allocator<std::pair<const T, U> > > { };
|
||||
|
||||
template< typename T >
|
||||
class SCP_queue : public std::queue< T, 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()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator!=(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define SCP_string std::string
|
||||
#define SCP_stringstream std::stringstream
|
||||
#define SCP_map std::map
|
||||
#define SCP_multimap std::multimap
|
||||
#define SCP_queue std::queue
|
||||
#define SCP_vector std::vector
|
||||
#define SCP_list std::list
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _VMALLOCATOR_H_INCLUDED_
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "graphics/grinternal.h"
|
||||
#include "globalincs/systemvars.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "graphics/grbatch.h"
|
||||
#include "parse/scripting.h"
|
||||
#include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
|
||||
|
||||
+33
-4
@@ -109,7 +109,12 @@ struct buffer_data {
|
||||
|
||||
size_t index_offset;
|
||||
|
||||
uint *index;
|
||||
const uint *get_index() const
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
uint i_first, i_last;
|
||||
|
||||
void release()
|
||||
{
|
||||
@@ -119,10 +124,26 @@ struct buffer_data {
|
||||
}
|
||||
}
|
||||
|
||||
buffer_data() :
|
||||
flags(0), texture(-1), n_verts(0), index_offset(0), index(NULL)
|
||||
void assign(int i, uint j)
|
||||
{
|
||||
const_cast<uint *>(index)[i] = j;
|
||||
if (i_first > i_last)
|
||||
i_first = i_last = j;
|
||||
else if (i_first > j)
|
||||
i_first = j;
|
||||
else if (i_last < j)
|
||||
i_last = j;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
private:
|
||||
uint *index;
|
||||
};
|
||||
|
||||
struct vertex_buffer {
|
||||
@@ -362,7 +383,7 @@ typedef struct screen {
|
||||
int (*gf_bm_load)(ubyte type, int n, char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *c_type, int *mm_lvl, int *size);
|
||||
void (*gf_bm_init)(int n);
|
||||
void (*gf_bm_page_in_start)();
|
||||
int (*gf_bm_lock)(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags);
|
||||
int (*gf_bm_lock)(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug);
|
||||
|
||||
int (*gf_bm_make_render_target)(int n, int *width, int *height, ubyte *bpp, int *mm_lvl, int flags );
|
||||
int (*gf_bm_set_render_target)(int n, int face);
|
||||
@@ -434,6 +455,8 @@ typedef struct screen {
|
||||
|
||||
void (*gf_line_htl)(vec3d *start, vec3d* end);
|
||||
void (*gf_sphere_htl)(float rad);
|
||||
|
||||
void (*gf_update_texture)(int bitmap_handle, int bpp, ubyte* data, int width, int height);
|
||||
} screen;
|
||||
|
||||
// handy macro
|
||||
@@ -706,6 +729,8 @@ __inline void gr_render_buffer(int start, const vertex_buffer *bufferp, int texi
|
||||
#define gr_line_htl GR_CALL(*gr_screen.gf_line_htl)
|
||||
#define gr_sphere_htl GR_CALL(*gr_screen.gf_sphere_htl)
|
||||
|
||||
#define gr_update_texture GR_CALL(*gr_screen.gf_update_texture)
|
||||
|
||||
// color functions
|
||||
void gr_get_color( int *r, int *g, int b );
|
||||
void gr_init_color(color *c, int r, int g, int b);
|
||||
@@ -723,6 +748,10 @@ void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u
|
||||
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);
|
||||
|
||||
// texture update functions
|
||||
ubyte* gr_opengl_get_texture_update_pointer(int bitmap_handle);
|
||||
void gr_opengl_update_texture(int bitmap_handle, int bpp, ubyte* data, int width, int height);
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -445,12 +445,16 @@ int gr_create_font(char * typeface)
|
||||
// JAS: Try to squeeze this into the smallest square power of two texture.
|
||||
// This should probably be done at font generation time, not here.
|
||||
int w, h;
|
||||
if ( fnt->pixel_data_size < 64*64 ) {
|
||||
if ( fnt->pixel_data_size*4 < 64*64 ) {
|
||||
w = h = 64;
|
||||
} else if ( fnt->pixel_data_size < 128*128 ) {
|
||||
} else if ( fnt->pixel_data_size*4 < 128*128 ) {
|
||||
w = h = 128;
|
||||
} else {
|
||||
} else if ( fnt->pixel_data_size*4 < 256*256 ) {
|
||||
w = h = 256;
|
||||
} else if ( fnt->pixel_data_size*4 < 512*512 ) {
|
||||
w = h = 512;
|
||||
} else {
|
||||
w = h = 1024;
|
||||
}
|
||||
|
||||
fnt->bm_w = w;
|
||||
@@ -469,7 +473,7 @@ int gr_create_font(char * typeface)
|
||||
ubp = &fnt->pixel_data[fnt->char_data[i].offset];
|
||||
if ( x + fnt->char_data[i].byte_width >= fnt->bm_w ) {
|
||||
x = 0;
|
||||
y += fnt->h;
|
||||
y += fnt->h + 2;
|
||||
if ( y+fnt->h > fnt->bm_h ) {
|
||||
Error( LOCATION, "Font too big!\n" );
|
||||
}
|
||||
@@ -484,7 +488,7 @@ int gr_create_font(char * typeface)
|
||||
fnt->bm_data[(x+x1)+(y+y1)*fnt->bm_w] = (unsigned char)(c);
|
||||
}
|
||||
}
|
||||
x += fnt->char_data[i].byte_width;
|
||||
x += fnt->char_data[i].byte_width + 2;
|
||||
}
|
||||
|
||||
fnt->bitmap_id = bm_create( 8, fnt->bm_w, fnt->bm_h, fnt->bm_data, BMP_AABITMAP );
|
||||
|
||||
+78
-21
@@ -99,6 +99,7 @@ void generic_anim_init(generic_anim *ga, char *filename)
|
||||
ga->height = 0;
|
||||
ga->width = 0;
|
||||
ga->bitmap_id = -1;
|
||||
ga->colored = false;
|
||||
}
|
||||
|
||||
// Goober5000
|
||||
@@ -174,6 +175,8 @@ int generic_anim_stream(generic_anim *ga)
|
||||
//TODO: add streaming EFF
|
||||
if(ga->type == BM_TYPE_ANI) {
|
||||
bpp = ANI_BPP_CHECK;
|
||||
if(ga->colored)
|
||||
bpp = 8;
|
||||
ga->ani.animation = anim_load(ga->filename, CF_TYPE_ANY, 0);
|
||||
ga->ani.instance = init_anim_instance(ga->ani.animation, bpp);
|
||||
|
||||
@@ -187,7 +190,7 @@ int generic_anim_stream(generic_anim *ga)
|
||||
ga->height = ga->ani.animation->height;
|
||||
ga->width = ga->ani.animation->width;
|
||||
ga->buffer = ga->ani.instance->frame;
|
||||
ga->bitmap_id = bm_create(bpp, ga->width, ga->height, ga->buffer, 0);
|
||||
ga->bitmap_id = bm_create(bpp, ga->width, ga->height, ga->buffer, (bpp==8)?BMP_AABITMAP:0);
|
||||
ga->ani.instance->last_bitmap = -1;
|
||||
|
||||
ga->ani.instance->file_offset = ga->ani.animation->file_offset;
|
||||
@@ -196,8 +199,24 @@ int generic_anim_stream(generic_anim *ga)
|
||||
ga->previous_frame = -1;
|
||||
}
|
||||
else {
|
||||
//placeholder until we get eff streaming working
|
||||
return generic_anim_load(ga);
|
||||
bpp = 32;
|
||||
if(ga->colored)
|
||||
bpp = 8;
|
||||
bm_load_and_parse_eff(ga->filename, CF_TYPE_ANY, &ga->num_frames, &anim_fps, &ga->keyframe, 0);
|
||||
char *p = strrchr( ga->filename, '.' );
|
||||
if ( p )
|
||||
*p = 0;
|
||||
char frame_name[32];
|
||||
snprintf(frame_name, 32, "%s_0000", ga->filename);
|
||||
ga->bitmap_id = bm_load(frame_name);
|
||||
if(ga->bitmap_id < 0) {
|
||||
mprintf(("Cannot find first frame for eff streaming. eff Filename: %s", ga->filename));
|
||||
return -1;
|
||||
}
|
||||
snprintf(frame_name, 32, "%s_0001", ga->filename);
|
||||
ga->eff.next_frame = bm_load(frame_name);
|
||||
bm_get_info(ga->bitmap_id, &ga->width, &ga->height);
|
||||
ga->previous_frame = 0;
|
||||
}
|
||||
|
||||
// keyframe info
|
||||
@@ -224,9 +243,6 @@ int generic_anim_stream(generic_anim *ga)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// EFF not handled yet; code shouldn't get here anyway per above block
|
||||
}
|
||||
|
||||
ga->streaming = 1;
|
||||
|
||||
@@ -259,6 +275,12 @@ void generic_anim_unload(generic_anim *ga)
|
||||
anim_free(ga->ani.animation);
|
||||
free_anim_instance(ga->ani.instance);
|
||||
}
|
||||
if(ga->type == BM_TYPE_EFF) {
|
||||
if(ga->eff.next_frame >= 0)
|
||||
bm_release(ga->eff.next_frame);
|
||||
if(ga->bitmap_id >= 0)
|
||||
bm_release(ga->bitmap_id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//trying to release the first frame will release ALL frames
|
||||
@@ -272,16 +294,48 @@ void generic_anim_unload(generic_anim *ga)
|
||||
}
|
||||
|
||||
//for timer debug, #define TIMER
|
||||
void generic_render_ani_stream(generic_anim *ga)
|
||||
void generic_render_eff_stream(generic_anim *ga)
|
||||
{
|
||||
int i;
|
||||
int bpp = ANI_BPP_CHECK;
|
||||
|
||||
if(ga->current_frame == ga->previous_frame)
|
||||
return;
|
||||
ubyte bpp = 32;
|
||||
if(ga->colored)
|
||||
bpp = 8;
|
||||
#ifdef TIMER
|
||||
int start_time = timer_get_fixed_seconds();
|
||||
#endif
|
||||
|
||||
if((ga->current_frame == ga->previous_frame))
|
||||
#ifdef TIMER
|
||||
mprintf(("=========================\n"));
|
||||
mprintf(("frame: %d\n", ga->current_frame));
|
||||
#endif
|
||||
char frame_name[32];
|
||||
snprintf(frame_name, 32, "%s_%.4d", ga->filename, ga->current_frame);
|
||||
if(bm_reload(ga->eff.next_frame, frame_name) == ga->eff.next_frame)
|
||||
{
|
||||
bitmap* next_frame_bmp = bm_lock(ga->eff.next_frame, bpp, (bpp==8)?BMP_AABITMAP:BMP_TEX_NONCOMP, true);
|
||||
if(next_frame_bmp->data)
|
||||
gr_update_texture(ga->bitmap_id, bpp, (ubyte*)next_frame_bmp->data, ga->width, ga->height);
|
||||
bm_unlock(ga->eff.next_frame);
|
||||
bm_unload(ga->eff.next_frame, 0, true);
|
||||
}
|
||||
#ifdef TIMER
|
||||
mprintf(("end: %d\n", timer_get_fixed_seconds() - start_time));
|
||||
mprintf(("=========================\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void generic_render_ani_stream(generic_anim *ga)
|
||||
{
|
||||
int i;
|
||||
int bpp = ANI_BPP_CHECK;
|
||||
if(ga->colored)
|
||||
bpp = 8;
|
||||
#ifdef TIMER
|
||||
int start_time = timer_get_fixed_seconds();
|
||||
#endif
|
||||
|
||||
if(ga->current_frame == ga->previous_frame)
|
||||
return;
|
||||
|
||||
#ifdef TIMER
|
||||
@@ -300,10 +354,10 @@ void generic_render_ani_stream(generic_anim *ga)
|
||||
ga->ani.instance->data = ga->ani.animation->data + ga->ani.animation->keys[ga->current_frame].offset;
|
||||
}
|
||||
if(ga->ani.animation->flags & ANF_STREAMED) {
|
||||
ga->ani.instance->file_offset = unpack_frame_from_file(ga->ani.instance, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, 0, bpp);
|
||||
ga->ani.instance->file_offset = unpack_frame_from_file(ga->ani.instance, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, (bpp==8)?1:0, bpp);
|
||||
}
|
||||
else {
|
||||
ga->ani.instance->data = unpack_frame(ga->ani.instance, ga->ani.instance->data, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, 0, bpp);
|
||||
ga->ani.instance->data = unpack_frame(ga->ani.instance, ga->ani.instance->data, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, (bpp==8)?1:0, bpp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -331,20 +385,18 @@ void generic_render_ani_stream(generic_anim *ga)
|
||||
#endif
|
||||
for(i = ga->previous_frame + 1; i <= ga->current_frame; i++) {
|
||||
if(ga->ani.animation->flags & ANF_STREAMED) {
|
||||
ga->ani.instance->file_offset = unpack_frame_from_file(ga->ani.instance, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, 0, bpp);
|
||||
ga->ani.instance->file_offset = unpack_frame_from_file(ga->ani.instance, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, (bpp==8)?1:0, bpp);
|
||||
}
|
||||
else {
|
||||
ga->ani.instance->data = unpack_frame(ga->ani.instance, ga->ani.instance->data, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, 0, bpp);
|
||||
ga->ani.instance->data = unpack_frame(ga->ani.instance, ga->ani.instance->data, ga->buffer, ga->width * ga->height, (ga->ani.instance->xlate_pal) ? ga->ani.animation->palette_translation : NULL, (bpp==8)?1:0, bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// always go back to screen format
|
||||
BM_SELECT_SCREEN_FORMAT();
|
||||
//we need to use this because performance is worse if we flush the gfx card buffer
|
||||
if ( ga->ani.instance->last_bitmap != -1 ){
|
||||
bm_release(ga->ani.instance->last_bitmap);
|
||||
}
|
||||
ga->bitmap_id = bm_create(bpp, ga->width, ga->height, ga->buffer, 0);
|
||||
|
||||
gr_update_texture(ga->bitmap_id, bpp, ga->buffer, ga->width, ga->height);
|
||||
|
||||
//in case we want to check that the frame is actually changing
|
||||
//mprintf(("frame crc = %08X\n", cf_add_chksum_long(0, ga->buffer, ga->width * ga->height * (bpp >> 3))));
|
||||
@@ -391,7 +443,7 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
|
||||
if(ga->direction & GENERIC_ANIM_DIRECTION_NOLOOP) {
|
||||
ga->anim_time = ga->total_time - 0.001f; //stop on last frame when playing - if it's equal we jump to the first frame
|
||||
}
|
||||
else if(!ga->done_playing){
|
||||
if(!ga->done_playing){
|
||||
//we've played this at least once
|
||||
ga->done_playing = 1;
|
||||
}
|
||||
@@ -415,6 +467,8 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
|
||||
//TODO: add EFF streaming
|
||||
if(ga->type == BM_TYPE_ANI) {
|
||||
generic_render_ani_stream(ga);
|
||||
} else {
|
||||
generic_render_eff_stream(ga);
|
||||
}
|
||||
gr_set_bitmap(ga->bitmap_id);
|
||||
}
|
||||
@@ -422,6 +476,9 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
|
||||
gr_set_bitmap(ga->first_frame + ga->current_frame);
|
||||
}
|
||||
ga->previous_frame = ga->current_frame;
|
||||
gr_bitmap(x, y);
|
||||
if(ga->colored)
|
||||
gr_aabitmap(x,y);
|
||||
else
|
||||
gr_bitmap(x,y);
|
||||
}
|
||||
}
|
||||
@@ -33,9 +33,8 @@ typedef struct generic_anim {
|
||||
anim_instance *instance;
|
||||
unsigned char bg_type; //to store background type to avoid messed up colours
|
||||
} ani;
|
||||
//reserved for eff streaming
|
||||
struct {
|
||||
//
|
||||
int next_frame;
|
||||
} eff;
|
||||
};
|
||||
ubyte type;
|
||||
@@ -44,6 +43,7 @@ typedef struct generic_anim {
|
||||
int height;
|
||||
int width;
|
||||
int bitmap_id;
|
||||
bool colored;
|
||||
} generic_anim;
|
||||
|
||||
// Goober5000
|
||||
|
||||
@@ -5118,9 +5118,17 @@ typedef unsigned long long int uint64_t;
|
||||
#elif defined(_WIN32) && defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
#elif defined(_WIN32)
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
// per stdint.h
|
||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
// realize that, e.g. char has the same size as __int8
|
||||
// so we give up on __intX for them.
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed int int32_t;
|
||||
#else
|
||||
typedef signed __int32 int32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
/* Fallback if nothing above works */
|
||||
#include <inttypes.h>
|
||||
|
||||
+21
-23
@@ -357,7 +357,7 @@ void geometry_batcher::draw_quad(vertex* verts)
|
||||
}
|
||||
|
||||
|
||||
void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity)
|
||||
void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity, float offset)
|
||||
{
|
||||
vec3d p[4];
|
||||
vertex *P = &vert[n_to_render * 3];
|
||||
@@ -413,7 +413,11 @@ void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float in
|
||||
|
||||
for(int i = 0; i < 6; i++){
|
||||
P[i].r = P[i].g = P[i].b = P[i].a = _color;
|
||||
R[i] = width;
|
||||
if(offset > 0.0f) {
|
||||
R[i] = offset;
|
||||
} else {
|
||||
R[i] = width;
|
||||
}
|
||||
}
|
||||
|
||||
n_to_render += 2;
|
||||
@@ -548,13 +552,13 @@ struct batch_item {
|
||||
static SCP_vector<batch_item> geometry_map;
|
||||
static SCP_vector<batch_item> distortion_map;
|
||||
|
||||
static int find_good_batch_item(int texture)
|
||||
static size_t find_good_batch_item(int texture)
|
||||
{
|
||||
size_t max_size = geometry_map.size();
|
||||
|
||||
for (size_t i = 0; i < max_size; i++) {
|
||||
if (geometry_map[i].texture == texture)
|
||||
return (int)i;
|
||||
return i;
|
||||
}
|
||||
|
||||
// don't have an existing match so add a new entry
|
||||
@@ -564,7 +568,7 @@ static int find_good_batch_item(int texture)
|
||||
|
||||
geometry_map.push_back(new_item);
|
||||
|
||||
return (int)(geometry_map.size() - 1);
|
||||
return (geometry_map.size() - 1);
|
||||
}
|
||||
|
||||
static size_t find_good_distortion_item(int texture)
|
||||
@@ -594,8 +598,7 @@ float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float wid
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
int index = find_good_batch_item(texture);
|
||||
Assert( index >= 0 );
|
||||
size_t index = find_good_batch_item(texture);
|
||||
|
||||
geometry_map[index].laser = true;
|
||||
item = &geometry_map[index].batch;
|
||||
@@ -613,8 +616,7 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
int index = find_good_batch_item(texture);
|
||||
Assert( index >= 0 );
|
||||
size_t index = find_good_batch_item(texture);
|
||||
|
||||
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
@@ -638,8 +640,7 @@ int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float ang
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
int index = find_good_batch_item(texture);
|
||||
Assert( index >= 0 );
|
||||
size_t index = find_good_batch_item(texture);
|
||||
|
||||
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
@@ -663,8 +664,7 @@ int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float
|
||||
}
|
||||
|
||||
geometry_batcher *item = NULL;
|
||||
int index = find_good_batch_item(texture);
|
||||
Assert( index >= 0 );
|
||||
size_t index = find_good_batch_item(texture);
|
||||
|
||||
Assertion( (geometry_map[index].laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
|
||||
|
||||
@@ -696,7 +696,7 @@ void batch_render_lasers()
|
||||
}
|
||||
}
|
||||
|
||||
void batch_render_bitmaps()
|
||||
void batch_render_geometry_map_bitmaps()
|
||||
{
|
||||
for (SCP_vector<batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
|
||||
|
||||
@@ -715,12 +715,14 @@ void batch_render_bitmaps()
|
||||
void batch_render_all()
|
||||
{
|
||||
batch_render_lasers();
|
||||
batch_render_bitmaps();
|
||||
batch_render_geometry_map_bitmaps();
|
||||
batch_render_distortion_map_bitmaps();
|
||||
}
|
||||
|
||||
void batch_reset()
|
||||
{
|
||||
geometry_map.clear();
|
||||
distortion_map.clear();
|
||||
}
|
||||
|
||||
int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
|
||||
@@ -747,7 +749,7 @@ int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, floa
|
||||
return 0;
|
||||
}
|
||||
|
||||
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity)
|
||||
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity, float offset)
|
||||
{
|
||||
if (texture < 0) {
|
||||
Int3();
|
||||
@@ -766,18 +768,14 @@ int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, f
|
||||
|
||||
item->add_allocate(1);
|
||||
|
||||
item->draw_beam(start,end,width,intensity);
|
||||
item->draw_beam(start,end,width,intensity,offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void distortion_render_bitmaps()
|
||||
void batch_render_distortion_map_bitmaps()
|
||||
{
|
||||
size_t map_size = distortion_map.size();
|
||||
batch_item *bi;
|
||||
|
||||
for (size_t i = 0; i < map_size; i++) {
|
||||
bi = &distortion_map[i];
|
||||
for (SCP_vector<batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
|
||||
|
||||
if ( bi->laser )
|
||||
continue;
|
||||
|
||||
@@ -27,7 +27,7 @@ private:
|
||||
void clone(const geometry_batcher &geo);
|
||||
|
||||
public:
|
||||
geometry_batcher(): n_to_render(0), n_allocated(0), vert(NULL), radius_list(NULL), use_radius(true) {};
|
||||
geometry_batcher(): n_to_render(0), n_allocated(0), vert(NULL), use_radius(true), radius_list(NULL) {};
|
||||
~geometry_batcher();
|
||||
|
||||
geometry_batcher(const geometry_batcher &geo) { clone(geo); }
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
void draw_quad(vertex *verts);
|
||||
|
||||
// draw a beam
|
||||
void draw_beam(vec3d *start, vec3d *end, float width, float intensity = 1.0f);
|
||||
void draw_beam(vec3d *start, vec3d *end, float width, float intensity = 1.0f, float offset = 0.0f);
|
||||
|
||||
//draw a laser
|
||||
float draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b);
|
||||
@@ -74,11 +74,11 @@ int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float
|
||||
int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
|
||||
int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity = 1.0f);
|
||||
int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha = 1.0f, float depth = 0.0f);
|
||||
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity = 1.0f);
|
||||
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity = 1.0f, float offset = 0.0f);
|
||||
void batch_render_all();
|
||||
void batch_render_bitmaps();
|
||||
void batch_render_geometry_map_bitmaps();
|
||||
void batch_render_lasers();
|
||||
void batch_reset();
|
||||
void distortion_render_bitmaps();
|
||||
void batch_render_distortion_map_bitmaps();
|
||||
|
||||
#endif
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "ddsutils/ddsutils.h"
|
||||
#include "model/model.h"
|
||||
#include "debugconsole/timerbar.h"
|
||||
#include "debugconsole/dbugfile.h"
|
||||
#include "graphics/gropenglbmpman.h"
|
||||
#include "graphics/gropengllight.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
@@ -346,7 +345,7 @@ void gr_opengl_flip()
|
||||
|
||||
// opengl_save_mouse_area(mx, my, Gr_cursor_size, Gr_cursor_size);
|
||||
|
||||
if (Gr_cursor != -1) {
|
||||
if (Gr_cursor != -1 && bm_is_valid(Gr_cursor)) {
|
||||
gr_set_bitmap(Gr_cursor);
|
||||
gr_bitmap( mx, my, false);
|
||||
}
|
||||
@@ -447,7 +446,7 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
|
||||
}
|
||||
|
||||
GL_state.ScissorTest(GL_TRUE);
|
||||
if(GL_rendering_to_framebuffer) {
|
||||
if(GL_rendering_to_texture) {
|
||||
glScissor(x, y, w, h);
|
||||
} else {
|
||||
glScissor(x, gr_screen.max_h-y-h, w, h);
|
||||
@@ -610,16 +609,12 @@ void gr_opengl_cleanup(int minimize)
|
||||
#ifdef _WIN32
|
||||
HWND wnd = (HWND)os_get_window();
|
||||
|
||||
DBUGFILE_OUTPUT_0("");
|
||||
|
||||
if (GL_render_context) {
|
||||
if ( !wglMakeCurrent(NULL, NULL) ) {
|
||||
DBUGFILE_OUTPUT_0("");
|
||||
MessageBox(wnd, "SHUTDOWN ERROR", "error", MB_OK);
|
||||
}
|
||||
|
||||
if ( !wglDeleteContext(GL_render_context) ) {
|
||||
DBUGFILE_OUTPUT_0("");
|
||||
MessageBox(wnd, "Unable to delete rendering context", "error", MB_OK);
|
||||
}
|
||||
|
||||
@@ -627,7 +622,6 @@ void gr_opengl_cleanup(int minimize)
|
||||
}
|
||||
#endif
|
||||
|
||||
DBUGFILE_OUTPUT_0("opengl_minimize");
|
||||
opengl_minimize();
|
||||
|
||||
if (minimize) {
|
||||
@@ -1345,7 +1339,7 @@ void opengl_setup_viewport()
|
||||
glLoadIdentity();
|
||||
|
||||
// the top and bottom positions are reversed on purpose, but RTT needs them the other way
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
if (GL_rendering_to_texture) {
|
||||
glOrtho(0, gr_screen.max_w, 0, gr_screen.max_h, -1.0, 1.0);
|
||||
} else {
|
||||
glOrtho(0, gr_screen.max_w, gr_screen.max_h, 0, -1.0, 1.0);
|
||||
@@ -1840,6 +1834,8 @@ void opengl_setup_function_pointers()
|
||||
gr_screen.gf_line_htl = gr_opengl_line_htl;
|
||||
gr_screen.gf_sphere_htl = gr_opengl_sphere_htl;
|
||||
|
||||
|
||||
gr_screen.gf_update_texture = gr_opengl_update_texture;
|
||||
// NOTE: All function pointers here should have a Cmdline_nohtl check at the top
|
||||
// if they shouldn't be run in non-HTL mode, Don't keep separate entries.
|
||||
// *****************************************************************************
|
||||
@@ -1980,13 +1976,11 @@ bool gr_opengl_init()
|
||||
mprintf(( " Using %s texture filter.\n", (GL_mipmap_filter) ? NOX("trilinear") : NOX("bilinear") ));
|
||||
|
||||
if (Use_GLSL) {
|
||||
if (Use_GLSL > 1) {
|
||||
mprintf(( " Using GLSL for model rendering.\n" ));
|
||||
}
|
||||
|
||||
mprintf(( " OpenGL Shader Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This stops fred crashing if no textures are set
|
||||
gr_screen.current_bitmap = -1;
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@ int get_num_mipmap_levels(int w, int h)
|
||||
return (levels > 1) ? levels : 1;
|
||||
}
|
||||
|
||||
// anything API specific to freeing bm data
|
||||
/**
|
||||
* Anything API specific to freeing bm data
|
||||
*/
|
||||
void gr_opengl_bm_free_data(int n, bool release)
|
||||
{
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
@@ -68,7 +70,9 @@ void gr_opengl_bm_free_data(int n, bool release)
|
||||
opengl_kill_render_target( n );
|
||||
}
|
||||
|
||||
// API specifics for creating a user bitmap
|
||||
/**
|
||||
* API specifics for creating a user bitmap
|
||||
*/
|
||||
void gr_opengl_bm_create(int n)
|
||||
{
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
@@ -176,13 +180,17 @@ int gr_opengl_bm_load(ubyte type, int n, char *filename, CFILE *img_cfp, int *w,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// API specific init instructions
|
||||
/**
|
||||
* API specific init instructions
|
||||
*/
|
||||
void gr_opengl_bm_init(int n)
|
||||
{
|
||||
Assert( (n >= 0) && (n < MAX_BITMAPS) );
|
||||
}
|
||||
|
||||
// specific instructions for setting up the start of a page-in session
|
||||
/**
|
||||
* Specific instructions for setting up the start of a page-in session
|
||||
*/
|
||||
void gr_opengl_bm_page_in_start()
|
||||
{
|
||||
opengl_preload_init();
|
||||
@@ -306,7 +314,6 @@ static int opengl_bm_lock_compress( int handle, int bitmapnum, bitmap_entry *be,
|
||||
int alpha = 1;
|
||||
int num_mipmaps = 1;
|
||||
|
||||
|
||||
// don't use for EFFs, if they were wanting to be DDS then they should already be that way
|
||||
if ( be->type == BM_TYPE_EFF ) {
|
||||
return 1;
|
||||
@@ -408,8 +415,10 @@ static int opengl_bm_lock_compress( int handle, int bitmapnum, bitmap_entry *be,
|
||||
|
||||
extern bool opengl_texture_slot_valid(int n, int handle);
|
||||
|
||||
// Lock an image files data into memory
|
||||
int gr_opengl_bm_lock( char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags )
|
||||
/**
|
||||
* Lock an image files data into memory
|
||||
*/
|
||||
int gr_opengl_bm_lock( char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug)
|
||||
{
|
||||
ubyte c_type = BM_TYPE_NONE;
|
||||
ubyte true_bpp;
|
||||
@@ -429,13 +438,13 @@ int gr_opengl_bm_lock( char *filename, int handle, int bitmapnum, ubyte bpp, uby
|
||||
if ( (bmp->data == 0) && !opengl_texture_slot_valid(bitmapnum, handle) ) {
|
||||
Assert(be->ref_count == 1);
|
||||
|
||||
if (be->type != BM_TYPE_USER) {
|
||||
if (be->type != BM_TYPE_USER && !nodebug) {
|
||||
if (bmp->data == 0)
|
||||
nprintf (("BmpMan", "Loading %s for the first time.\n", be->filename));
|
||||
}
|
||||
|
||||
if ( !Bm_paging ) {
|
||||
if (be->type != BM_TYPE_USER)
|
||||
if (be->type != BM_TYPE_USER && !nodebug)
|
||||
nprintf(("Paging", "Loading %s (%dx%dx%d)\n", be->filename, bmp->w, bmp->h, true_bpp));
|
||||
}
|
||||
|
||||
@@ -573,7 +582,11 @@ int gr_opengl_bm_make_render_target(int n, int *width, int *height, ubyte *bpp,
|
||||
MIN(*width, *height) = MAX(*width, *height);
|
||||
}
|
||||
|
||||
Assert( is_power_of_two(*width, *height) );
|
||||
// Only enforce power of two size if not supported
|
||||
if (!(Is_Extension_Enabled(OGL_ARB_TEXTURE_NON_POWER_OF_TWO)))
|
||||
{
|
||||
Assert( is_power_of_two(*width, *height) );
|
||||
}
|
||||
|
||||
if ( opengl_make_render_target(bm_bitmaps[n].handle, n, width, height, bpp, mm_lvl, flags) ) {
|
||||
return 1;
|
||||
|
||||
@@ -43,7 +43,7 @@ void gr_opengl_bm_init(int n);
|
||||
void gr_opengl_bm_page_in_start();
|
||||
|
||||
// Lock an image files data into memory
|
||||
int gr_opengl_bm_lock(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags);
|
||||
int gr_opengl_bm_lock(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug);
|
||||
|
||||
void gr_opengl_bm_save_render_target(int slot);
|
||||
int gr_opengl_bm_make_render_target(int n, int *width, int *height, ubyte *bpp, int *mm_lvl, int flags);
|
||||
|
||||
+2398
-2328
File diff suppressed because it is too large.
Load diff
@@ -1,59 +1,63 @@
|
||||
/*
|
||||
* 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 GR_OPENGLDRAW_H
|
||||
#define GR_OPENGLDRAW_H
|
||||
|
||||
void gr_opengl_aabitmap_ex(int x, int y, int w, int h, int sx, int sy, bool resize, bool mirror);
|
||||
void gr_opengl_aabitmap(int x, int y, bool resize, bool mirror);
|
||||
void gr_opengl_string(int sx, int sy, char *s, bool resize = true);
|
||||
void gr_opengl_string(float sx, float sy, char *s, bool resize = true);
|
||||
void gr_opengl_line(int x1,int y1,int x2,int y2, bool resize);
|
||||
void gr_opengl_aaline(vertex *v1, vertex *v2);
|
||||
void gr_opengl_pixel(int x, int y, bool resize);
|
||||
void gr_opengl_gradient(int x1, int y1, int x2, int y2, bool resize);
|
||||
void gr_opengl_circle(int xc, int yc, int d, bool resize);
|
||||
void gr_opengl_curve(int xc, int yc, int r, int direction);
|
||||
void gr_opengl_scaler(vertex *va, vertex *vb, bool bw_bitmap );
|
||||
void gr_opengl_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct);
|
||||
void gr_opengl_shade(int x, int y, int w, int h, bool resize);
|
||||
void gr_opengl_flash(int r, int g, int b);
|
||||
void gr_opengl_flash_alpha(int r, int g, int b, int a);
|
||||
void gr_opengl_fade_in(int instantaneous);
|
||||
void gr_opengl_fade_out(int instantaneous);
|
||||
void gr_opengl_tmapper(int nverts, vertex **verts, uint flags);
|
||||
void gr_opengl_render(int nverts, vertex *verts, uint flags);
|
||||
void gr_opengl_render_effect(int nverts, vertex *verts, float *radius_list, uint flags);
|
||||
void gr_opengl_bitmap_ex(int x, int y, int w, int h, int sx, int sy, bool resize);
|
||||
void gr_opengl_update_distortion();
|
||||
|
||||
void opengl_render_timer_bar(int colour, float x, float y, float w, float h);
|
||||
void opengl_set_spec_mapping(int tmap_type, float *u_scale, float *v_scale, int stage = 0);
|
||||
void opengl_reset_spec_mapping();
|
||||
|
||||
void gr_opengl_line_htl(vec3d *start, vec3d *end);
|
||||
void gr_opengl_sphere_htl(float rad);
|
||||
|
||||
void gr_opengl_draw_line_list(colored_vector *lines, int num);
|
||||
|
||||
void opengl_setup_scene_textures();
|
||||
void opengl_scene_texture_shutdown();
|
||||
void gr_opengl_scene_texture_begin();
|
||||
void gr_opengl_scene_texture_end();
|
||||
|
||||
extern int Scene_texture_initialized;
|
||||
|
||||
extern GLuint Scene_color_texture;
|
||||
extern GLuint Scene_effect_texture;
|
||||
|
||||
extern int Scene_texture_width;
|
||||
extern int Scene_texture_height;
|
||||
|
||||
#endif // !GR_OPENGLDRAW_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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GR_OPENGLDRAW_H
|
||||
#define GR_OPENGLDRAW_H
|
||||
|
||||
void gr_opengl_aabitmap_ex(int x, int y, int w, int h, int sx, int sy, bool resize, bool mirror);
|
||||
void gr_opengl_aabitmap(int x, int y, bool resize, bool mirror);
|
||||
void gr_opengl_string(int sx, int sy, char *s, bool resize = true);
|
||||
void gr_opengl_string(float sx, float sy, char *s, bool resize = true);
|
||||
void gr_opengl_line(int x1,int y1,int x2,int y2, bool resize);
|
||||
void gr_opengl_aaline(vertex *v1, vertex *v2);
|
||||
void gr_opengl_pixel(int x, int y, bool resize);
|
||||
void gr_opengl_gradient(int x1, int y1, int x2, int y2, bool resize);
|
||||
void gr_opengl_circle(int xc, int yc, int d, bool resize);
|
||||
void gr_opengl_curve(int xc, int yc, int r, int direction);
|
||||
void gr_opengl_scaler(vertex *va, vertex *vb, bool bw_bitmap );
|
||||
void gr_opengl_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct);
|
||||
void gr_opengl_shade(int x, int y, int w, int h, bool resize);
|
||||
void gr_opengl_flash(int r, int g, int b);
|
||||
void gr_opengl_flash_alpha(int r, int g, int b, int a);
|
||||
void gr_opengl_fade_in(int instantaneous);
|
||||
void gr_opengl_fade_out(int instantaneous);
|
||||
void gr_opengl_tmapper(int nverts, vertex **verts, uint flags);
|
||||
void gr_opengl_render(int nverts, vertex *verts, uint flags);
|
||||
void gr_opengl_render_effect(int nverts, vertex *verts, float *radius_list, uint flags);
|
||||
void gr_opengl_bitmap_ex(int x, int y, int w, int h, int sx, int sy, bool resize);
|
||||
void gr_opengl_update_distortion();
|
||||
|
||||
void opengl_render_timer_bar(int colour, float x, float y, float w, float h);
|
||||
void opengl_set_spec_mapping(int tmap_type, float *u_scale, float *v_scale, int stage = 0);
|
||||
void opengl_reset_spec_mapping();
|
||||
|
||||
void gr_opengl_line_htl(vec3d *start, vec3d *end);
|
||||
void gr_opengl_sphere_htl(float rad);
|
||||
|
||||
void gr_opengl_draw_line_list(colored_vector *lines, int num);
|
||||
|
||||
void opengl_setup_scene_textures();
|
||||
void opengl_scene_texture_shutdown();
|
||||
void gr_opengl_scene_texture_begin();
|
||||
void gr_opengl_scene_texture_end();
|
||||
|
||||
extern int Scene_texture_initialized;
|
||||
|
||||
extern GLuint Scene_color_texture;
|
||||
extern GLuint Scene_luminance_texture;
|
||||
extern GLuint Scene_effect_texture;
|
||||
|
||||
extern int Scene_texture_width;
|
||||
extern int Scene_texture_height;
|
||||
|
||||
extern float Scene_texture_u_scale;
|
||||
extern float Scene_texture_v_scale;
|
||||
|
||||
#endif // !GR_OPENGLDRAW_H
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "graphics/gropengltexture.h"
|
||||
#include "cmdline/cmdline.h"
|
||||
#include "ddsutils/ddsutils.h"
|
||||
#include "popup/popup.h"
|
||||
|
||||
#include "osapi/outwnd.h"
|
||||
|
||||
@@ -369,9 +370,22 @@ void opengl_extensions_init()
|
||||
Use_PBOs = 1;
|
||||
}
|
||||
|
||||
// setup the best fog function found
|
||||
if ( !Fred_running ) {
|
||||
if ( Is_Extension_Enabled(OGL_EXT_FOG_COORD) ) {
|
||||
OGL_fogmode = 2;
|
||||
} else {
|
||||
OGL_fogmode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if we can't do cubemaps then turn off Cmdline_env
|
||||
if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) && Is_Extension_Enabled(OGL_ARB_TEXTURE_ENV_COMBINE)) ) {
|
||||
Cmdline_env = 0;
|
||||
}
|
||||
|
||||
if ( !Cmdline_noglsl && Is_Extension_Enabled(OGL_ARB_SHADER_OBJECTS) && Is_Extension_Enabled(OGL_ARB_FRAGMENT_SHADER)
|
||||
&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) )
|
||||
{
|
||||
&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) ) {
|
||||
int ver = 0, major = 0, minor = 0;
|
||||
const char *glsl_ver = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
|
||||
|
||||
@@ -387,29 +401,19 @@ void opengl_extensions_init()
|
||||
Use_GLSL = 3;
|
||||
}
|
||||
// SM 2.0 compatible
|
||||
else if (ver >= 110) {
|
||||
else if (ver >= 120) {
|
||||
Use_GLSL = 2;
|
||||
}
|
||||
// we require GLSL 1.10 or higher
|
||||
// we require GLSL 1.20 or higher
|
||||
else if (ver < 110) {
|
||||
Use_GLSL = 0;
|
||||
mprintf((" OpenGL Shading Language version %s is not sufficient to use GLSL mode in FSO. Defaulting to fixed-function renderer.\n", glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) ));
|
||||
#ifdef NDEBUG
|
||||
popup(0, 1, POPUP_OK, "GLSL support not available on this GPU. Disabling shader support and defaulting to fixed-function rendering.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// setup the best fog function found
|
||||
if ( !Fred_running ) {
|
||||
if ( Is_Extension_Enabled(OGL_EXT_FOG_COORD) ) {
|
||||
OGL_fogmode = 2;
|
||||
} else {
|
||||
OGL_fogmode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if we can't do cubemaps then turn off Cmdline_env
|
||||
if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) && Is_Extension_Enabled(OGL_ARB_TEXTURE_ENV_COMBINE)) ) {
|
||||
Cmdline_env = 0;
|
||||
}
|
||||
|
||||
// can't have this stuff without GLSL support
|
||||
if ( !Use_GLSL ) {
|
||||
Cmdline_normal = 0;
|
||||
|
||||
@@ -385,6 +385,8 @@ void gr_opengl_set_center_alpha(int type)
|
||||
if (!type || Cmdline_nohtl)
|
||||
return;
|
||||
|
||||
if(Num_active_gl_lights == MAX_LIGHTS)
|
||||
return;
|
||||
opengl_light glight;
|
||||
|
||||
vec3d dir;
|
||||
|
||||
@@ -194,7 +194,7 @@ static bool opengl_post_pass_bloom()
|
||||
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);
|
||||
GL_state.ScissorTest(scissor_test);
|
||||
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, opengl_get_rtt_framebuffer());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -279,12 +279,17 @@ void opengl_post_pass_fxaa() {
|
||||
recompile_fxaa_shader();
|
||||
}
|
||||
|
||||
// We only want to draw to ATTACHMENT0
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
// Do a prepass to convert the main shaders' RGBA output into RGBL
|
||||
opengl_shader_set_current( &GL_post_shader[fxaa_shader_id + 1] );
|
||||
|
||||
// basic/default uniforms
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex"), 0 );
|
||||
|
||||
vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Scene_luminance_texture, 0);
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_color_texture);
|
||||
@@ -293,13 +298,13 @@ void opengl_post_pass_fxaa() {
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glTexCoord2f(Scene_texture_u_scale, 0.0f);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glTexCoord2f(Scene_texture_u_scale, Scene_texture_v_scale);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, Scene_texture_v_scale);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glEnd();
|
||||
|
||||
@@ -308,6 +313,8 @@ void opengl_post_pass_fxaa() {
|
||||
// set and configure post shader ..
|
||||
opengl_shader_set_current( &GL_post_shader[fxaa_shader_id] );
|
||||
|
||||
vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Scene_color_texture, 0);
|
||||
|
||||
// basic/default uniforms
|
||||
vglUniform1iARB( opengl_shader_get_uniform("tex0"), 0 );
|
||||
vglUniform1fARB( opengl_shader_get_uniform("rt_w"), static_cast<float>(Post_texture_width));
|
||||
@@ -315,19 +322,19 @@ void opengl_post_pass_fxaa() {
|
||||
|
||||
GL_state.Texture.SetActiveUnit(0);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
GL_state.Texture.Enable(Scene_color_texture);
|
||||
GL_state.Texture.Enable(Scene_luminance_texture);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glTexCoord2f(Scene_texture_u_scale, 0.0f);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glTexCoord2f(Scene_texture_u_scale, Scene_texture_v_scale);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, Scene_texture_v_scale);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glEnd();
|
||||
|
||||
@@ -348,13 +355,12 @@ void gr_opengl_post_process_end()
|
||||
GL_state.Texture.SetShaderMode(GL_TRUE);
|
||||
|
||||
// Do FXAA
|
||||
if (Cmdline_fxaa && !fxaa_unavailable) {
|
||||
if (Cmdline_fxaa && !fxaa_unavailable && !GL_rendering_to_texture) {
|
||||
opengl_post_pass_fxaa();
|
||||
}
|
||||
|
||||
// done with screen render framebuffer
|
||||
//vglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
// Bind the correct framebuffer. opengl_get_rtt_framebuffer returns 0 if not doing RTT
|
||||
vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, opengl_get_rtt_framebuffer());
|
||||
|
||||
// do bloom, hopefully ;)
|
||||
bool bloomed = opengl_post_pass_bloom();
|
||||
@@ -409,13 +415,13 @@ void gr_opengl_post_process_end()
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glTexCoord2f(Scene_texture_u_scale, 0.0f);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glTexCoord2f(Scene_texture_u_scale, Scene_texture_v_scale);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, Scene_texture_v_scale);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glEnd();
|
||||
|
||||
@@ -443,9 +449,9 @@ void gr_opengl_post_process_end()
|
||||
|
||||
void get_post_process_effect_names(SCP_vector<SCP_string> &names)
|
||||
{
|
||||
int idx;
|
||||
size_t idx;
|
||||
|
||||
for (idx = 0; idx < (int)Post_effects.size(); idx++) {
|
||||
for (idx = 0; idx < Post_effects.size(); idx++) {
|
||||
names.push_back(Post_effects[idx].name);
|
||||
}
|
||||
}
|
||||
@@ -703,10 +709,6 @@ static bool opengl_post_init_table()
|
||||
|
||||
required_string("$Shader Effect:");
|
||||
stuff_int(&se.shader_effect);
|
||||
if (se.shader_effect == 0 || se.shader_effect == 1) {
|
||||
WarningEx(LOCATION, "Invalid shader effect specified for effect %s. 0 and 1 are reserved for internal use.\n", se.name);
|
||||
skip_to_start_of_string_either("$Name:", "#End");
|
||||
}
|
||||
|
||||
required_string("$Disables Rendering:");
|
||||
stuff_boolean(&se.disables_rendering);
|
||||
@@ -829,7 +831,7 @@ static char *opengl_post_load_shader(char *filename, int flags, int flags2)
|
||||
|
||||
return shader;
|
||||
} else {
|
||||
mprintf(("Loading built-in default shader for: %s\n", filename));
|
||||
mprintf((" Loading built-in default shader for: %s\n", filename));
|
||||
char* def_shader = defaults_get_file(filename);
|
||||
size_t len = strlen(def_shader);
|
||||
char *shader = (char*) vm_malloc(len + flags_len + 1);
|
||||
|
||||
@@ -51,6 +51,12 @@ struct opengl_shader_file_t {
|
||||
static opengl_shader_file_t GL_shader_file[] = {
|
||||
{ "null-v.sdr", "null-f.sdr", (0), 0, { NULL }, 0, { NULL } },
|
||||
|
||||
{ "soft-v.sdr", "soft-f.sdr", (SDR_FLAG_SOFT_QUAD),
|
||||
6, {"baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ"}, 1, { "radius_in" } },
|
||||
|
||||
{ "soft-v.sdr", "soft-f.sdr", (SDR_FLAG_SOFT_QUAD | SDR_FLAG_DISTORTION),
|
||||
5, {"baseMap", "window_width", "window_height", "distMap", "frameBuffer"}, 1, { "offset_in" } },
|
||||
|
||||
// with diffuse Textures
|
||||
{ "lne-v.sdr", "lbgsne-f.sdr", (SDR_FLAG_LIGHT | SDR_FLAG_DIFFUSE_MAP | SDR_FLAG_GLOW_MAP | SDR_FLAG_SPEC_MAP | SDR_FLAG_NORMAL_MAP | SDR_FLAG_ENV_MAP),
|
||||
8, { "sBasemap", "sGlowmap", "sSpecmap", "sNormalmap", "sEnvmap", "envMatrix", "alpha_spec", "n_lights" }, 0, { NULL } },
|
||||
@@ -247,7 +253,7 @@ static opengl_shader_file_t GL_shader_file[] = {
|
||||
13, { "sBasemap", "sGlowmap", "sSpecmap", "sNormalmap", "sEnvmap", "envMatrix", "alpha_spec", "n_lights", "anim_timer", "effect_num", "sFramebuffer", "vpwidth", "vpheight" }, 0, { NULL } },
|
||||
|
||||
{ "lfnea-v.sdr", "lfbsnea-f.sdr", (SDR_FLAG_LIGHT | SDR_FLAG_FOG | SDR_FLAG_DIFFUSE_MAP | SDR_FLAG_SPEC_MAP | SDR_FLAG_NORMAL_MAP | SDR_FLAG_ENV_MAP | SDR_FLAG_ANIMATED),
|
||||
12, { "sBasemap", "sSpecmap", "sNormalmap", "sEnvmap", "envMatrix", "alpha_spec", "n_lights", "anim_timer", "effect_num", "sFramebuffer", "vpwidth", "vpheight" }, 0, { NULL } },
|
||||
12, { "sBasemap", "sSpecmap", "sNormalmap", "sEnvmap", "envMatrix", "alpha_spec", "n_lights", "anim_timer", "effect_num", "sFramebuffer", "vpwidth", "vpheight" }, 0, { NULL } }
|
||||
|
||||
/* No Heightmapping for now - Valathil
|
||||
{ "lne-v.sdr", "lgsnhe-f.sdr", (SDR_FLAG_LIGHT | SDR_FLAG_GLOW_MAP | SDR_FLAG_SPEC_MAP | SDR_FLAG_NORMAL_MAP | SDR_FLAG_HEIGHT_MAP | SDR_FLAG_ENV_MAP),
|
||||
@@ -304,11 +310,6 @@ static opengl_shader_file_t GL_shader_file[] = {
|
||||
{ "ln-v.sdr", "lsnh-f.sdr", (SDR_FLAG_LIGHT | SDR_FLAG_SPEC_MAP | SDR_FLAG_NORMAL_MAP | SDR_FLAG_HEIGHT_MAP),
|
||||
4, { "sSpecmap", "sNormalmap", "sHeightmap", "n_lights" }, 0, { NULL } }*/
|
||||
|
||||
{ "soft-v.sdr", "soft-f.sdr", (SDR_FLAG_SOFT_QUAD),
|
||||
6, {"baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ"}, 1, { "radius_in" } },
|
||||
|
||||
{ "soft-v.sdr", "soft-f.sdr", (SDR_FLAG_SOFT_QUAD | SDR_FLAG_DISTORTION),
|
||||
8, {"baseMap", "depthMap", "window_width", "window_height", "nearZ", "farZ", "distMap", "frameBuffer"}, 1, { "radius_in" } }
|
||||
};
|
||||
|
||||
static const int Num_shader_files = sizeof(GL_shader_file) / sizeof(opengl_shader_file_t);
|
||||
@@ -353,7 +354,7 @@ void opengl_shader_set_current(opengl_shader_t *shader_obj)
|
||||
|
||||
int opengl_shader_get_index(int flags)
|
||||
{
|
||||
uint idx;
|
||||
size_t idx;
|
||||
|
||||
for (idx = 0; idx < GL_shader.size(); idx++) {
|
||||
if (GL_shader[idx].flags == flags) {
|
||||
@@ -366,7 +367,7 @@ int opengl_shader_get_index(int flags)
|
||||
|
||||
void opengl_shader_shutdown()
|
||||
{
|
||||
uint i;
|
||||
size_t i;
|
||||
|
||||
if ( !Use_GLSL ) {
|
||||
return;
|
||||
@@ -467,7 +468,7 @@ static char *opengl_load_shader(char *filename, int flags, bool unified)
|
||||
|
||||
return shader;
|
||||
} else {
|
||||
mprintf(("Loading built-in default shader for: %s\n", filename));
|
||||
mprintf((" Loading built-in default shader for: %s\n", filename));
|
||||
char* def_shader = defaults_get_file(filename);
|
||||
size_t len = strlen(def_shader);
|
||||
char *shader = (char*) vm_malloc(len + flags_len + 1);
|
||||
|
||||
+787
-787
File diff suppressed because it is too large.
Load diff
+293
-293
@@ -1,293 +1,293 @@
|
||||
/*
|
||||
* 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 _GROPENGLSTATE_H
|
||||
#define _GROPENGLSTATE_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
|
||||
struct opengl_texture_unit {
|
||||
GLboolean active; // unit is active
|
||||
GLboolean enabled; // has texture target enabled
|
||||
|
||||
GLenum texture_target;
|
||||
GLuint texture_id;
|
||||
|
||||
GLboolean texgen_S;
|
||||
GLboolean texgen_T;
|
||||
GLboolean texgen_R;
|
||||
GLboolean texgen_Q;
|
||||
|
||||
GLenum texgen_mode_S;
|
||||
GLenum texgen_mode_T;
|
||||
GLenum texgen_mode_R;
|
||||
GLenum texgen_mode_Q;
|
||||
|
||||
GLenum env_mode;
|
||||
GLenum env_combine_rgb;
|
||||
GLenum env_combine_alpha;
|
||||
|
||||
GLfloat rgb_scale;
|
||||
GLfloat alpha_scale;
|
||||
};
|
||||
|
||||
class opengl_texture_state
|
||||
{
|
||||
private:
|
||||
void default_values(GLint unit, GLenum target = GL_INVALID_ENUM);
|
||||
|
||||
GLuint active_texture_unit;
|
||||
GLboolean shader_mode;
|
||||
|
||||
opengl_texture_unit *units;
|
||||
GLuint num_texture_units;
|
||||
|
||||
|
||||
public:
|
||||
opengl_texture_state(): active_texture_unit(0), shader_mode(GL_FALSE), units(NULL), Current_texture_source(TEXTURE_SOURCE_NONE) {}
|
||||
~opengl_texture_state();
|
||||
|
||||
gr_texture_source Current_texture_source;
|
||||
|
||||
void init(GLuint n_units);
|
||||
|
||||
GLboolean TexgenS(GLint state = -1);
|
||||
GLboolean TexgenT(GLint state = -1);
|
||||
GLboolean TexgenR(GLint state = -1);
|
||||
GLboolean TexgenQ(GLint state = -1);
|
||||
void SetTarget(GLenum tex_target);
|
||||
void SetActiveUnit(GLuint id = 0);
|
||||
void Enable(GLuint tex_id = 0);
|
||||
void Disable(bool force = false);
|
||||
void DisableAll();
|
||||
void Delete(GLuint tex_id);
|
||||
GLfloat AnisoFilter(GLfloat aniso = 0.0f);
|
||||
|
||||
inline void SetRGBScale(GLfloat scale);
|
||||
inline void SetAlphaScale(GLfloat scale);
|
||||
inline void SetEnvMode(GLenum mode);
|
||||
inline void SetEnvCombineMode(GLenum cmode, GLenum cfunc);
|
||||
inline void SetWrapS(GLenum mode);
|
||||
inline void SetWrapT(GLenum mode);
|
||||
inline void SetWrapR(GLenum mode);
|
||||
inline void SetTexgenModeS(GLenum mode);
|
||||
inline void SetTexgenModeT(GLenum mode);
|
||||
inline void SetTexgenModeR(GLenum mode);
|
||||
inline void SetTexgenModeQ(GLenum mode);
|
||||
inline GLenum GetTarget();
|
||||
inline void SetShaderMode(GLboolean mode);
|
||||
};
|
||||
|
||||
inline void opengl_texture_state::SetRGBScale(GLfloat scale)
|
||||
{
|
||||
Assert( ((scale == 1.0f) || (scale == 2.0f) || (scale == 4.0f)) );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, scale);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetAlphaScale(GLfloat scale)
|
||||
{
|
||||
Assert( ((scale == 1.0f) || (scale == 2.0f) || (scale == 4.0f)) );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetEnvMode(GLenum mode)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetEnvCombineMode(GLenum cmode, GLenum cfunc)
|
||||
{
|
||||
SetEnvMode(GL_COMBINE);
|
||||
|
||||
if (cmode == GL_COMBINE_RGB) {
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, cfunc);
|
||||
} else if (cmode == GL_COMBINE_ALPHA) {
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, cfunc);
|
||||
}
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetWrapS(GLenum mode)
|
||||
{
|
||||
// glTexParameteri(units[active_texture_unit].texture_target, GL_TEXTURE_WRAP_S, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetWrapT(GLenum mode)
|
||||
{
|
||||
// glTexParameteri(units[active_texture_unit].texture_target, GL_TEXTURE_WRAP_T, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetWrapR(GLenum mode)
|
||||
{
|
||||
// glTexParameteri(units[active_texture_unit].texture_target, GL_TEXTURE_WRAP_R, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeS(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeT(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeR(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeQ(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline GLenum opengl_texture_state::GetTarget()
|
||||
{
|
||||
return units[active_texture_unit].texture_target;
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetShaderMode(GLboolean mode)
|
||||
{
|
||||
shader_mode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class opengl_state
|
||||
{
|
||||
friend class opengl_texture_state;
|
||||
|
||||
private:
|
||||
GLboolean fog_Status;
|
||||
GLboolean blend_Status;
|
||||
GLboolean alphatest_Status;
|
||||
GLboolean depthtest_Status;
|
||||
GLboolean scissortest_Status;
|
||||
GLboolean cullface_Status;
|
||||
GLboolean polygonoffsetfill_Status;
|
||||
GLboolean normalize_Status;
|
||||
GLboolean clipplane_Status[6];
|
||||
GLboolean *light_Status;
|
||||
GLboolean depthmask_Status;
|
||||
GLboolean lighting_Status;
|
||||
|
||||
GLenum frontface_Value;
|
||||
GLenum cullface_Value;
|
||||
GLenum blendfunc_Value[2];
|
||||
GLenum depthfunc_Value;
|
||||
|
||||
gr_alpha_blend Current_alpha_blend_mode;
|
||||
gr_zbuffer_type Current_zbuffer_type;
|
||||
|
||||
|
||||
public:
|
||||
opengl_state() : light_Status(NULL) {}
|
||||
~opengl_state();
|
||||
|
||||
void init();
|
||||
|
||||
opengl_texture_state Texture;
|
||||
|
||||
void SetTextureSource(gr_texture_source ts);
|
||||
void SetAlphaBlendMode(gr_alpha_blend ab);
|
||||
void SetZbufferType(gr_zbuffer_type zt);
|
||||
|
||||
// the GLboolean functions will return the current state if no argument
|
||||
// and the previous state if an argument is passed
|
||||
GLboolean Lighting(GLint state = -1);
|
||||
GLboolean Fog(GLint state = -1);
|
||||
GLboolean Blend(GLint state = -1);
|
||||
GLboolean AlphaTest(GLint state = -1);
|
||||
GLboolean DepthTest(GLint state = -1);
|
||||
GLboolean ScissorTest(GLint state = -1);
|
||||
GLboolean CullFace(GLint state = -1);
|
||||
GLboolean PolygonOffsetFill(GLint state = -1);
|
||||
GLboolean Normalize(GLint state = -1);
|
||||
GLboolean Light(GLint num, GLint state = -1);
|
||||
GLboolean ClipPlane(GLint num, GLint state = -1);
|
||||
GLboolean DepthMask(GLint state = -1);
|
||||
|
||||
inline GLenum FrontFaceValue(GLenum new_val = GL_INVALID_ENUM);
|
||||
inline GLenum CullFaceValue(GLenum new_val = GL_INVALID_ENUM);
|
||||
inline void BlendFunc(GLenum s_val, GLenum d_val);
|
||||
inline GLenum BlendFuncSource();
|
||||
inline GLenum BlendFuncDest();
|
||||
inline GLenum DepthFunc(GLenum new_val = GL_INVALID_ENUM);
|
||||
};
|
||||
|
||||
inline GLenum opengl_state::FrontFaceValue(GLenum new_val)
|
||||
{
|
||||
if (new_val != frontface_Value) {
|
||||
if (new_val != GL_INVALID_ENUM) {
|
||||
glFrontFace(new_val);
|
||||
frontface_Value = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
return frontface_Value;
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::CullFaceValue(GLenum new_val)
|
||||
{
|
||||
if (new_val != cullface_Value) {
|
||||
if (new_val != GL_INVALID_ENUM) {
|
||||
glCullFace(new_val);
|
||||
cullface_Value = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
return cullface_Value;
|
||||
}
|
||||
|
||||
inline void opengl_state::BlendFunc(GLenum s_val, GLenum d_val)
|
||||
{
|
||||
if ( !((s_val == blendfunc_Value[0]) && (d_val == blendfunc_Value[1])) ) {
|
||||
glBlendFunc(s_val, d_val);
|
||||
blendfunc_Value[0] = s_val;
|
||||
blendfunc_Value[1] = d_val;
|
||||
|
||||
Current_alpha_blend_mode = (gr_alpha_blend)(-1);
|
||||
}
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::BlendFuncSource()
|
||||
{
|
||||
return blendfunc_Value[0];
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::BlendFuncDest()
|
||||
{
|
||||
return blendfunc_Value[1];
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::DepthFunc(GLenum new_val)
|
||||
{
|
||||
if (new_val != depthfunc_Value) {
|
||||
if (new_val != GL_INVALID_ENUM) {
|
||||
glDepthFunc(new_val);
|
||||
depthfunc_Value = new_val;
|
||||
|
||||
Current_zbuffer_type = (gr_zbuffer_type)(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return depthfunc_Value;
|
||||
}
|
||||
|
||||
|
||||
extern opengl_state GL_state;
|
||||
|
||||
void opengl_setup_render_states(int &r,int &g,int &b,int &alpha, int &tmap_type, int flags, int is_scaler = 0);
|
||||
|
||||
|
||||
#endif // _GROPENGLSTATE_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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _GROPENGLSTATE_H
|
||||
#define _GROPENGLSTATE_H
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
#include "graphics/gropengl.h"
|
||||
#include "graphics/gropenglextension.h"
|
||||
#include "graphics/gropengltexture.h"
|
||||
|
||||
struct opengl_texture_unit {
|
||||
GLboolean active; // unit is active
|
||||
GLboolean enabled; // has texture target enabled
|
||||
|
||||
GLenum texture_target;
|
||||
GLuint texture_id;
|
||||
|
||||
GLboolean texgen_S;
|
||||
GLboolean texgen_T;
|
||||
GLboolean texgen_R;
|
||||
GLboolean texgen_Q;
|
||||
|
||||
GLenum texgen_mode_S;
|
||||
GLenum texgen_mode_T;
|
||||
GLenum texgen_mode_R;
|
||||
GLenum texgen_mode_Q;
|
||||
|
||||
GLenum env_mode;
|
||||
GLenum env_combine_rgb;
|
||||
GLenum env_combine_alpha;
|
||||
|
||||
GLfloat rgb_scale;
|
||||
GLfloat alpha_scale;
|
||||
};
|
||||
|
||||
class opengl_texture_state
|
||||
{
|
||||
private:
|
||||
void default_values(GLint unit, GLenum target = GL_INVALID_ENUM);
|
||||
|
||||
GLuint active_texture_unit;
|
||||
GLboolean shader_mode;
|
||||
|
||||
opengl_texture_unit *units;
|
||||
GLuint num_texture_units;
|
||||
|
||||
|
||||
public:
|
||||
opengl_texture_state(): active_texture_unit(0), shader_mode(GL_FALSE), units(NULL), Current_texture_source(TEXTURE_SOURCE_NONE) {}
|
||||
~opengl_texture_state();
|
||||
|
||||
gr_texture_source Current_texture_source;
|
||||
|
||||
void init(GLuint n_units);
|
||||
|
||||
GLboolean TexgenS(GLint state = -1);
|
||||
GLboolean TexgenT(GLint state = -1);
|
||||
GLboolean TexgenR(GLint state = -1);
|
||||
GLboolean TexgenQ(GLint state = -1);
|
||||
void SetTarget(GLenum tex_target);
|
||||
void SetActiveUnit(GLuint id = 0);
|
||||
void Enable(GLuint tex_id = 0);
|
||||
void Disable(bool force = false);
|
||||
void DisableAll();
|
||||
void Delete(GLuint tex_id);
|
||||
GLfloat AnisoFilter(GLfloat aniso = 0.0f);
|
||||
|
||||
inline void SetRGBScale(GLfloat scale);
|
||||
inline void SetAlphaScale(GLfloat scale);
|
||||
inline void SetEnvMode(GLenum mode);
|
||||
inline void SetEnvCombineMode(GLenum cmode, GLenum cfunc);
|
||||
inline void SetWrapS(GLenum mode);
|
||||
inline void SetWrapT(GLenum mode);
|
||||
inline void SetWrapR(GLenum mode);
|
||||
inline void SetTexgenModeS(GLenum mode);
|
||||
inline void SetTexgenModeT(GLenum mode);
|
||||
inline void SetTexgenModeR(GLenum mode);
|
||||
inline void SetTexgenModeQ(GLenum mode);
|
||||
inline GLenum GetTarget();
|
||||
inline void SetShaderMode(GLboolean mode);
|
||||
};
|
||||
|
||||
inline void opengl_texture_state::SetRGBScale(GLfloat scale)
|
||||
{
|
||||
Assert( ((scale == 1.0f) || (scale == 2.0f) || (scale == 4.0f)) );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, scale);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetAlphaScale(GLfloat scale)
|
||||
{
|
||||
Assert( ((scale == 1.0f) || (scale == 2.0f) || (scale == 4.0f)) );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetEnvMode(GLenum mode)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetEnvCombineMode(GLenum cmode, GLenum cfunc)
|
||||
{
|
||||
SetEnvMode(GL_COMBINE);
|
||||
|
||||
if (cmode == GL_COMBINE_RGB) {
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, cfunc);
|
||||
} else if (cmode == GL_COMBINE_ALPHA) {
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, cfunc);
|
||||
}
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetWrapS(GLenum mode)
|
||||
{
|
||||
// glTexParameteri(units[active_texture_unit].texture_target, GL_TEXTURE_WRAP_S, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetWrapT(GLenum mode)
|
||||
{
|
||||
// glTexParameteri(units[active_texture_unit].texture_target, GL_TEXTURE_WRAP_T, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetWrapR(GLenum mode)
|
||||
{
|
||||
// glTexParameteri(units[active_texture_unit].texture_target, GL_TEXTURE_WRAP_R, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeS(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeT(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeR(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetTexgenModeQ(GLenum mode)
|
||||
{
|
||||
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, mode);
|
||||
}
|
||||
|
||||
inline GLenum opengl_texture_state::GetTarget()
|
||||
{
|
||||
return units[active_texture_unit].texture_target;
|
||||
}
|
||||
|
||||
inline void opengl_texture_state::SetShaderMode(GLboolean mode)
|
||||
{
|
||||
shader_mode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class opengl_state
|
||||
{
|
||||
friend class opengl_texture_state;
|
||||
|
||||
private:
|
||||
GLboolean fog_Status;
|
||||
GLboolean blend_Status;
|
||||
GLboolean alphatest_Status;
|
||||
GLboolean depthtest_Status;
|
||||
GLboolean scissortest_Status;
|
||||
GLboolean cullface_Status;
|
||||
GLboolean polygonoffsetfill_Status;
|
||||
GLboolean normalize_Status;
|
||||
GLboolean clipplane_Status[6];
|
||||
GLboolean *light_Status;
|
||||
GLboolean depthmask_Status;
|
||||
GLboolean lighting_Status;
|
||||
|
||||
GLenum frontface_Value;
|
||||
GLenum cullface_Value;
|
||||
GLenum blendfunc_Value[2];
|
||||
GLenum depthfunc_Value;
|
||||
|
||||
gr_alpha_blend Current_alpha_blend_mode;
|
||||
gr_zbuffer_type Current_zbuffer_type;
|
||||
|
||||
|
||||
public:
|
||||
opengl_state() : light_Status(NULL) {}
|
||||
~opengl_state();
|
||||
|
||||
void init();
|
||||
|
||||
opengl_texture_state Texture;
|
||||
|
||||
void SetTextureSource(gr_texture_source ts);
|
||||
void SetAlphaBlendMode(gr_alpha_blend ab);
|
||||
void SetZbufferType(gr_zbuffer_type zt);
|
||||
|
||||
// the GLboolean functions will return the current state if no argument
|
||||
// and the previous state if an argument is passed
|
||||
GLboolean Lighting(GLint state = -1);
|
||||
GLboolean Fog(GLint state = -1);
|
||||
GLboolean Blend(GLint state = -1);
|
||||
GLboolean AlphaTest(GLint state = -1);
|
||||
GLboolean DepthTest(GLint state = -1);
|
||||
GLboolean ScissorTest(GLint state = -1);
|
||||
GLboolean CullFace(GLint state = -1);
|
||||
GLboolean PolygonOffsetFill(GLint state = -1);
|
||||
GLboolean Normalize(GLint state = -1);
|
||||
GLboolean Light(GLint num, GLint state = -1);
|
||||
GLboolean ClipPlane(GLint num, GLint state = -1);
|
||||
GLboolean DepthMask(GLint state = -1);
|
||||
|
||||
inline GLenum FrontFaceValue(GLenum new_val = GL_INVALID_ENUM);
|
||||
inline GLenum CullFaceValue(GLenum new_val = GL_INVALID_ENUM);
|
||||
inline void BlendFunc(GLenum s_val, GLenum d_val);
|
||||
inline GLenum BlendFuncSource();
|
||||
inline GLenum BlendFuncDest();
|
||||
inline GLenum DepthFunc(GLenum new_val = GL_INVALID_ENUM);
|
||||
};
|
||||
|
||||
inline GLenum opengl_state::FrontFaceValue(GLenum new_val)
|
||||
{
|
||||
if (new_val != frontface_Value) {
|
||||
if (new_val != GL_INVALID_ENUM) {
|
||||
glFrontFace(new_val);
|
||||
frontface_Value = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
return frontface_Value;
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::CullFaceValue(GLenum new_val)
|
||||
{
|
||||
if (new_val != cullface_Value) {
|
||||
if (new_val != GL_INVALID_ENUM) {
|
||||
glCullFace(new_val);
|
||||
cullface_Value = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
return cullface_Value;
|
||||
}
|
||||
|
||||
inline void opengl_state::BlendFunc(GLenum s_val, GLenum d_val)
|
||||
{
|
||||
if ( !((s_val == blendfunc_Value[0]) && (d_val == blendfunc_Value[1])) ) {
|
||||
glBlendFunc(s_val, d_val);
|
||||
blendfunc_Value[0] = s_val;
|
||||
blendfunc_Value[1] = d_val;
|
||||
|
||||
Current_alpha_blend_mode = (gr_alpha_blend)(-1);
|
||||
}
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::BlendFuncSource()
|
||||
{
|
||||
return blendfunc_Value[0];
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::BlendFuncDest()
|
||||
{
|
||||
return blendfunc_Value[1];
|
||||
}
|
||||
|
||||
inline GLenum opengl_state::DepthFunc(GLenum new_val)
|
||||
{
|
||||
if (new_val != depthfunc_Value) {
|
||||
if (new_val != GL_INVALID_ENUM) {
|
||||
glDepthFunc(new_val);
|
||||
depthfunc_Value = new_val;
|
||||
|
||||
Current_zbuffer_type = (gr_zbuffer_type)(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return depthfunc_Value;
|
||||
}
|
||||
|
||||
|
||||
extern opengl_state GL_state;
|
||||
|
||||
void opengl_setup_render_states(int &r,int &g,int &b,int &alpha, int &tmap_type, int flags, int is_scaler = 0);
|
||||
|
||||
|
||||
#endif // _GROPENGLSTATE_H
|
||||
@@ -40,12 +40,12 @@ GLint GL_supported_texture_units = 2;
|
||||
int GL_should_preload = 0;
|
||||
ubyte GL_xlat[256];
|
||||
GLfloat GL_anisotropy = 1.0f;
|
||||
GLfloat GL_max_anisotropy = 2.0f;
|
||||
GLfloat GL_max_anisotropy = -1.0f;
|
||||
int GL_mipmap_filter = 0;
|
||||
GLenum GL_texture_target = GL_TEXTURE_2D;
|
||||
GLenum GL_texture_face = GL_TEXTURE_2D;
|
||||
GLenum GL_texture_addressing = GL_REPEAT;
|
||||
bool GL_rendering_to_framebuffer = false;
|
||||
bool GL_rendering_to_texture = false;
|
||||
GLint GL_max_renderbuffer_size = 0;
|
||||
|
||||
extern int GLOWMAP;
|
||||
@@ -96,7 +96,7 @@ GLfloat opengl_get_max_anisotropy()
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if ( !GL_max_anisotropy ) {
|
||||
if ( GL_max_anisotropy < 0.0f ) {
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &GL_max_anisotropy);
|
||||
}
|
||||
|
||||
@@ -273,8 +273,10 @@ void opengl_free_texture_slot( int n )
|
||||
opengl_free_texture( &Textures[n] );
|
||||
}
|
||||
|
||||
// determine if a bitmap is in API memory, so that we can just reuse it rather
|
||||
// that having to load it from disk again
|
||||
/**
|
||||
* Determine if a bitmap is in API memory, so that we can just reuse it rather
|
||||
* that having to load it from disk again
|
||||
*/
|
||||
bool opengl_texture_slot_valid(int n, int handle)
|
||||
{
|
||||
tcache_slot_opengl *t = &Textures[n];
|
||||
@@ -297,10 +299,10 @@ bool opengl_texture_slot_valid(int n, int handle)
|
||||
int opengl_free_texture(tcache_slot_opengl *t)
|
||||
{
|
||||
// Bitmap changed!!
|
||||
if (/*t->bitmap_handle > -1*/t->texture_id) {
|
||||
if (t->texture_id) {
|
||||
// if I, or any of my children have been used this frame, bail
|
||||
// can't use bm_get_cache_slot() here since bitmap_id probably isn't valid
|
||||
if ( (t->bitmap_handle >= 0) && Tex_used_this_frame[t->bitmap_handle % MAX_BITMAPS] /*&& (t->bpp == 8)*/ ) {
|
||||
if ( (t->bitmap_handle >= 0) && Tex_used_this_frame[t->bitmap_handle % MAX_BITMAPS] ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -478,7 +480,7 @@ int opengl_create_texture_sub(int bitmap_handle, int bitmap_type, int bmap_w, in
|
||||
}
|
||||
|
||||
|
||||
if ( (bitmap_type == TCACHE_TYPE_CUBEMAP) ) {
|
||||
if ( bitmap_type == TCACHE_TYPE_CUBEMAP ) {
|
||||
t->texture_target = GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
|
||||
@@ -1047,8 +1049,7 @@ int gr_opengl_tcache_set_internal(int bitmap_handle, int bitmap_type, float *u_s
|
||||
|
||||
GL_state.Texture.SetActiveUnit(tex_unit);
|
||||
|
||||
if ( /*(bm_is_render_target(bitmap_handle) != RENDER_TARGET_DYNAMIC) &&*/
|
||||
!bm_is_render_target(bitmap_handle) &&
|
||||
if (!bm_is_render_target(bitmap_handle) &&
|
||||
((t->bitmap_handle < 0) || (bitmap_handle != t->bitmap_handle)) )
|
||||
{
|
||||
ret_val = opengl_create_texture( bitmap_handle, bitmap_type, t );
|
||||
@@ -1076,7 +1077,6 @@ int gr_opengl_tcache_set_internal(int bitmap_handle, int bitmap_type, float *u_s
|
||||
}
|
||||
// gah
|
||||
else {
|
||||
//Int3();
|
||||
mprintf(("Texturing disabled for texture %s due to internal error.\n", bm_get_filename(bitmap_handle)));
|
||||
GL_state.Texture.Disable();
|
||||
|
||||
@@ -1388,6 +1388,70 @@ int opengl_export_image( int slot, int width, int height, int alpha, int num_mip
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void gr_opengl_update_texture(int bitmap_handle, int bpp, ubyte* data, int width, int height)
|
||||
{
|
||||
GLenum texFormat, glFormat;
|
||||
int n = bm_get_cache_slot (bitmap_handle, 1);
|
||||
tcache_slot_opengl *t = &Textures[n];
|
||||
if(!t->texture_id)
|
||||
return;
|
||||
int byte_mult = (bpp >> 3);
|
||||
int true_byte_mult = (t->bpp >> 3);
|
||||
ubyte* texmem = NULL;
|
||||
// GL_BGRA_EXT is *much* faster with some hardware/drivers
|
||||
if (true_byte_mult == 4) {
|
||||
texFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
glFormat = GL_BGRA;
|
||||
} else if (true_byte_mult == 3) {
|
||||
texFormat = GL_UNSIGNED_BYTE;
|
||||
glFormat = GL_BGR;
|
||||
} else {
|
||||
texFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
glFormat = GL_BGRA;
|
||||
}
|
||||
if (byte_mult == 1) {
|
||||
texFormat = GL_UNSIGNED_BYTE;
|
||||
glFormat = GL_ALPHA;
|
||||
texmem = (ubyte *) vm_malloc (width*height*byte_mult);
|
||||
ubyte* texmemp = texmem;
|
||||
|
||||
Assert( texmem != NULL );
|
||||
|
||||
int luminance = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
if ( (i < height) && (j < width) ) {
|
||||
if ( true_byte_mult > 1 ) {
|
||||
luminance = 0;
|
||||
|
||||
if ( true_byte_mult > 3 ) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
luminance += data[(i*width+j)*true_byte_mult+k];
|
||||
}
|
||||
|
||||
*texmemp++ = (ubyte)((luminance / 3) * (data[(i*width+j)*true_byte_mult+3]/255.0f));
|
||||
} else {
|
||||
for (int k = 0; k < true_byte_mult; k++) {
|
||||
luminance += data[(i*width+j)*true_byte_mult+k];
|
||||
}
|
||||
|
||||
*texmemp++ = (ubyte)(luminance / true_byte_mult);
|
||||
}
|
||||
} else {
|
||||
*texmemp++ = GL_xlat[data[i*width+j]];
|
||||
}
|
||||
} else {
|
||||
*texmemp++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, t->texture_id);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, glFormat, texFormat, (texmem)?texmem:data);
|
||||
if (texmem != NULL)
|
||||
vm_free(texmem);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GL_EXT_framebuffer_object stuff (ie, render-to-texture)
|
||||
//
|
||||
@@ -1467,9 +1531,9 @@ int opengl_check_framebuffer()
|
||||
|
||||
static fbo_t *opengl_get_fbo(int width, int height)
|
||||
{
|
||||
uint rt_size = RenderTarget.size();
|
||||
size_t rt_size = RenderTarget.size();
|
||||
|
||||
for (uint i = 0; i < rt_size; i++) {
|
||||
for (size_t i = 0; i < rt_size; i++) {
|
||||
if ( (RenderTarget[i].width == width) && (RenderTarget[i].height == height) ) {
|
||||
return &RenderTarget[i];
|
||||
}
|
||||
@@ -1491,7 +1555,7 @@ void opengl_kill_render_target(int slot)
|
||||
}
|
||||
|
||||
tcache_slot_opengl *ts = &Textures[slot];
|
||||
uint idx = 0;
|
||||
size_t idx = 0;
|
||||
|
||||
for (idx = 0; idx < RenderTarget.size(); idx++) {
|
||||
if ( (RenderTarget[idx].width == ts->w) && (RenderTarget[idx].height == ts->h) ) {
|
||||
@@ -1527,7 +1591,7 @@ void opengl_kill_render_target(int slot)
|
||||
|
||||
void opengl_kill_all_render_targets()
|
||||
{
|
||||
for (uint i = 0; i < RenderTarget.size(); i++) {
|
||||
for (size_t i = 0; i < RenderTarget.size(); i++) {
|
||||
fbo_t *fbo = &RenderTarget[i];
|
||||
|
||||
if (fbo->framebuffer_id) {
|
||||
@@ -1553,14 +1617,6 @@ int opengl_set_render_target( int slot, int face, int is_static )
|
||||
|
||||
if (slot < 0) {
|
||||
if ( (render_target != NULL) && (render_target->working_slot >= 0) ) {
|
||||
// if (Cmdline_mipmap) {
|
||||
// ts = &Textures[render_target->working_slot];
|
||||
|
||||
// glBindTexture(ts->texture_target, ts->texture_id);
|
||||
// vglGenerateMipmapEXT(ts->texture_target);
|
||||
// glBindTexture(ts->texture_target, 0);
|
||||
// }
|
||||
|
||||
if (render_target->is_static) {
|
||||
extern void gr_opengl_bm_save_render_target(int slot);
|
||||
gr_opengl_bm_save_render_target(render_target->working_slot);
|
||||
@@ -1580,7 +1636,7 @@ int opengl_set_render_target( int slot, int face, int is_static )
|
||||
// done with this render target so lets move on
|
||||
render_target = NULL;
|
||||
|
||||
GL_rendering_to_framebuffer = false;
|
||||
GL_rendering_to_texture = false;
|
||||
|
||||
GL_CHECK_FOR_ERRORS("end of set_render_target(0)");
|
||||
|
||||
@@ -1631,7 +1687,7 @@ int opengl_set_render_target( int slot, int face, int is_static )
|
||||
// save current fbo for later use
|
||||
render_target = fbo;
|
||||
|
||||
GL_rendering_to_framebuffer = true;
|
||||
GL_rendering_to_texture = true;
|
||||
|
||||
GL_CHECK_FOR_ERRORS("end of set_render_target()");
|
||||
|
||||
@@ -1640,7 +1696,7 @@ int opengl_set_render_target( int slot, int face, int is_static )
|
||||
|
||||
int opengl_make_render_target( int handle, int slot, int *w, int *h, ubyte *bpp, int *mm_lvl, int flags )
|
||||
{
|
||||
Assert( !GL_rendering_to_framebuffer );
|
||||
Assert( !GL_rendering_to_texture );
|
||||
|
||||
if (slot < 0) {
|
||||
Int3();
|
||||
@@ -1863,6 +1919,30 @@ int opengl_make_render_target( int handle, int slot, int *w, int *h, ubyte *bpp,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn GLuint opengl_get_rtt_framebuffer()
|
||||
*
|
||||
* @brief Gets the current RTT framebuffer.
|
||||
*
|
||||
* Gets the OpenGL framebuffer ID of the currently in use RTT framebuffer.
|
||||
* If there is currently none such framebuffer in use then this function returns
|
||||
* 0 so it can be used in any place where the framebuffer should be reset to the
|
||||
* default drawing surface.
|
||||
*
|
||||
* @author m!m
|
||||
* @date 14.12.2011
|
||||
*
|
||||
* @return The current RTT FBO ID or 0 when not doing RTT.
|
||||
*/
|
||||
|
||||
GLuint opengl_get_rtt_framebuffer()
|
||||
{
|
||||
if (render_target == NULL || render_target->working_slot < 0)
|
||||
return 0;
|
||||
else
|
||||
return render_target->framebuffer_id;
|
||||
}
|
||||
|
||||
//
|
||||
// End of GL_EXT_framebuffer_object stuff
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -59,7 +59,7 @@ extern int GL_mipmap_filter;
|
||||
extern GLenum GL_texture_target;
|
||||
extern GLenum GL_texture_face;
|
||||
extern GLfloat GL_anisotropy;
|
||||
extern bool GL_rendering_to_framebuffer;
|
||||
extern bool GL_rendering_to_texture;
|
||||
extern GLint GL_max_renderbuffer_size;
|
||||
|
||||
void opengl_switch_arb(int unit, int state);
|
||||
@@ -72,7 +72,6 @@ void opengl_set_additive_tex_env();
|
||||
void opengl_set_modulate_tex_env();
|
||||
void opengl_preload_init();
|
||||
GLfloat opengl_get_max_anisotropy();
|
||||
//void opengl_set_anisotropy(GLfloat aniso_value = GL_anisotropy);
|
||||
void opengl_kill_render_target(int slot);
|
||||
int opengl_make_render_target(int handle, int slot, int *w, int *h, ubyte *bpp, int *mm_lvl, int flags);
|
||||
int opengl_set_render_target(int slot, int face = -1, int is_static = 0);
|
||||
@@ -84,5 +83,6 @@ int gr_opengl_tcache_set(int bitmap_handle, int bitmap_type, float *u_scale, flo
|
||||
int gr_opengl_preload(int bitmap_num, int is_aabitmap);
|
||||
void gr_opengl_set_texture_panning(float u, float v, bool enable);
|
||||
void gr_opengl_set_texture_addressing(int mode);
|
||||
GLuint opengl_get_rtt_framebuffer();
|
||||
|
||||
#endif //_GROPENGLTEXTURE_H
|
||||
@@ -362,7 +362,7 @@ bool gr_opengl_pack_buffer(const int buffer_id, vertex_buffer *vb)
|
||||
for (j = 0; j < vb->tex_buf.size(); j++) {
|
||||
n_verts = vb->tex_buf[j].n_verts;
|
||||
uint offset = vb->tex_buf[j].index_offset;
|
||||
uint *index = vb->tex_buf[j].index;
|
||||
const uint *index = vb->tex_buf[j].get_index();
|
||||
|
||||
// bump to our spot in the buffer
|
||||
GLubyte *ibuf = m_vbp->index_list + offset;
|
||||
@@ -499,7 +499,7 @@ static void opengl_init_arrays(opengl_vertex_buffer *vbp, const vertex_buffer *b
|
||||
if (Cmdline_drawelements) \
|
||||
glDrawElements(GL_TRIANGLES, count, element_type, ibuffer + (datap->index_offset + start)); \
|
||||
else \
|
||||
vglDrawRangeElements(GL_TRIANGLES, start, end, count, element_type, ibuffer + (datap->index_offset + start));
|
||||
vglDrawRangeElements(GL_TRIANGLES, datap->i_first, datap->i_last, count, element_type, ibuffer + (datap->index_offset + start));
|
||||
|
||||
int GL_last_shader_flags = -1;
|
||||
int GL_last_shader_index = -1;
|
||||
@@ -690,11 +690,13 @@ static void opengl_render_pipeline_program(int start, const vertex_buffer *buffe
|
||||
GL_state.Texture.SetActiveUnit(render_pass);
|
||||
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
|
||||
if( Scene_framebuffer_in_frame )
|
||||
{
|
||||
GL_state.Texture.Enable(Scene_effect_texture);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
}
|
||||
else
|
||||
GL_state.Texture.Enable(Framebuffer_fallback_texture_id);
|
||||
vglUniform1iARB( opengl_shader_get_uniform("sFramebuffer"), render_pass );
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
render_pass++;
|
||||
}
|
||||
// DRAW IT!!
|
||||
@@ -1188,7 +1190,7 @@ void gr_opengl_set_projection_matrix(float fov, float aspect, float z_near, floa
|
||||
|
||||
GL_CHECK_FOR_ERRORS("start of set_projection_matrix()()");
|
||||
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
if (GL_rendering_to_texture) {
|
||||
glViewport(gr_screen.offset_x, gr_screen.offset_y, gr_screen.clip_width, gr_screen.clip_height);
|
||||
} else {
|
||||
glViewport(gr_screen.offset_x, (gr_screen.max_h - gr_screen.offset_y - gr_screen.clip_height), gr_screen.clip_width, gr_screen.clip_height);
|
||||
@@ -1203,7 +1205,7 @@ void gr_opengl_set_projection_matrix(float fov, float aspect, float z_near, floa
|
||||
clip_height = tan( (double)fov * 0.5 ) * z_near;
|
||||
clip_width = clip_height * (GLdouble)aspect;
|
||||
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
if (GL_rendering_to_texture) {
|
||||
glFrustum( -clip_width, clip_width, clip_height, -clip_height, z_near, z_far );
|
||||
} else {
|
||||
glFrustum( -clip_width, clip_width, -clip_height, clip_height, z_near, z_far );
|
||||
@@ -1230,7 +1232,7 @@ void gr_opengl_end_projection_matrix()
|
||||
glLoadIdentity();
|
||||
|
||||
// the top and bottom positions are reversed on purpose, but RTT needs them the other way
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
if (GL_rendering_to_texture) {
|
||||
glOrtho(0, gr_screen.max_w, 0, gr_screen.max_h, -1.0, 1.0);
|
||||
} else {
|
||||
glOrtho(0, gr_screen.max_w, gr_screen.max_h, 0, -1.0, 1.0);
|
||||
@@ -1408,7 +1410,7 @@ void gr_opengl_set_2d_matrix(/*int x, int y, int w, int h*/)
|
||||
glLoadIdentity();
|
||||
|
||||
// the top and bottom positions are reversed on purpose, but RTT needs them the other way
|
||||
if (GL_rendering_to_framebuffer) {
|
||||
if (GL_rendering_to_texture) {
|
||||
glOrtho( 0, gr_screen.max_w, 0, gr_screen.max_h, -1, 1 );
|
||||
} else {
|
||||
glOrtho( 0, gr_screen.max_w, gr_screen.max_h, 0, -1, 1 );
|
||||
|
||||
@@ -434,6 +434,10 @@ void gr_stub_draw_line_list(colored_vector *lines, int num)
|
||||
{
|
||||
}
|
||||
|
||||
void gr_stub_update_texture(int bitmap_handle, int bpp, ubyte* data, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
// bitmap functions
|
||||
int gr_stub_bm_load(ubyte type, int n, char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *c_type, int *mm_lvl, int *size)
|
||||
{
|
||||
@@ -524,7 +528,7 @@ int gr_stub_bm_load(ubyte type, int n, char *filename, CFILE *img_cfp, int *w, i
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gr_stub_bm_lock(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags)
|
||||
int gr_stub_bm_lock(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug)
|
||||
{
|
||||
ubyte c_type = BM_TYPE_NONE;
|
||||
ubyte true_bpp;
|
||||
@@ -535,7 +539,7 @@ int gr_stub_bm_lock(char *filename, int handle, int bitmapnum, ubyte bpp, ubyte
|
||||
true_bpp = 8;
|
||||
|
||||
// don't do a bpp check here since it could be different in OGL - taylor
|
||||
if ( (bmp->data == 0) ) {
|
||||
if ( bmp->data == 0 ) {
|
||||
Assert(be->ref_count == 1);
|
||||
|
||||
if ( be->type != BM_TYPE_USER ) {
|
||||
@@ -811,5 +815,6 @@ bool gr_stub_init()
|
||||
gr_screen.gf_line_htl = gr_stub_draw_htl_line;
|
||||
gr_screen.gf_sphere_htl = gr_stub_draw_htl_sphere;
|
||||
|
||||
gr_screen.gf_update_texture = gr_stub_update_texture;
|
||||
return true;
|
||||
}
|
||||
+76
-58
@@ -290,8 +290,9 @@ static int Damage_flash_bright;
|
||||
static int Damage_flash_timer;
|
||||
|
||||
HudGauge::HudGauge():
|
||||
base_w(0), base_h(0), gauge_config(-1), config_override(true), reticle_follow(false), active(false), pop_up(false), disabled_views(0), texture_target(-1),
|
||||
target_w(-1), target_h(-1), canvas_w(-1), canvas_h(-1), custom_gauge(false), font_num(FONT1), off_by_default(false), sexp_override(false)
|
||||
base_w(0), base_h(0), gauge_config(-1), font_num(FONT1), reticle_follow(false), lock_color(false), sexp_lock_color(false),
|
||||
active(false), off_by_default(false), sexp_override(false), pop_up(false), disabled_views(0), custom_gauge(false),
|
||||
texture_target(-1), canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
{
|
||||
position[0] = 0;
|
||||
position[1] = 0;
|
||||
@@ -306,16 +307,17 @@ target_w(-1), target_h(-1), canvas_w(-1), canvas_h(-1), custom_gauge(false), fon
|
||||
texture_target_fname[0] = '\0';
|
||||
|
||||
custom_name[0] = '\0';
|
||||
custom_text[0] = '\0';
|
||||
custom_text = "";
|
||||
custom_frame.first_frame = -1;
|
||||
custom_frame.num_frames = 0;
|
||||
custom_frame_offset = 0;
|
||||
}
|
||||
|
||||
HudGauge::HudGauge(int _gauge_object, int _gauge_config, bool _allow_override, bool _slew, bool _message, int _disabled_views, int r, int g, int b):
|
||||
base_w(0), base_h(0), gauge_object(_gauge_object), gauge_config(_gauge_config), config_override(_allow_override), reticle_follow(_slew),
|
||||
message_gauge(_message), active(false), pop_up(false), disabled_views(_disabled_views), texture_target(-1), target_w(-1), target_h(-1),
|
||||
textoffset_x(0), textoffset_y(0), canvas_w(-1), canvas_h(-1), custom_gauge(false), font_num(FONT1), off_by_default(false), sexp_override(false)
|
||||
HudGauge::HudGauge(int _gauge_object, int _gauge_config, bool _slew, bool _message, int _disabled_views, int r, int g, int b):
|
||||
base_w(0), base_h(0), gauge_config(_gauge_config), gauge_object(_gauge_object), font_num(FONT1),
|
||||
reticle_follow(_slew), lock_color(false), sexp_lock_color(false), active(false), off_by_default(false), sexp_override(false), pop_up(false), message_gauge(_message),
|
||||
disabled_views(_disabled_views), custom_gauge(false), textoffset_x(0), textoffset_y(0), texture_target(-1),
|
||||
canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
{
|
||||
Assert(gauge_config <= NUM_HUD_GAUGES && gauge_config >= 0);
|
||||
|
||||
@@ -339,8 +341,8 @@ textoffset_x(0), textoffset_y(0), canvas_w(-1), canvas_h(-1), custom_gauge(false
|
||||
texture_target_fname[0] = '\0';
|
||||
|
||||
custom_name[0] = '\0';
|
||||
custom_text[0] = '\0';
|
||||
default_text[0] = '\0';
|
||||
custom_text = "";
|
||||
default_text = "";
|
||||
custom_frame.first_frame = -1;
|
||||
custom_frame.num_frames = 0;
|
||||
custom_frame_offset = 0;
|
||||
@@ -348,9 +350,10 @@ textoffset_x(0), textoffset_y(0), canvas_w(-1), canvas_h(-1), custom_gauge(false
|
||||
|
||||
// constructor for custom gauges
|
||||
HudGauge::HudGauge(int _gauge_config, bool _slew, int r, int g, int b, char* _custom_name, char* _custom_text, char* frame_fname, int txtoffset_x, int txtoffset_y):
|
||||
gauge_object(HUD_OBJECT_CUSTOM), base_w(0), base_h(0), gauge_config(_gauge_config), config_override(true), reticle_follow(_slew), message_gauge(false),
|
||||
active(false), pop_up(false), disabled_views(VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY), texture_target(-1), target_w(-1), target_h(-1),
|
||||
textoffset_x(txtoffset_x), textoffset_y(txtoffset_y), canvas_w(-1), canvas_h(-1), custom_gauge(true), font_num(FONT1), off_by_default(false), sexp_override(false)
|
||||
base_w(0), base_h(0), gauge_config(_gauge_config), gauge_object(HUD_OBJECT_CUSTOM), font_num(FONT1),
|
||||
reticle_follow(_slew), lock_color(false), sexp_lock_color(false), active(false), off_by_default(false), sexp_override(false), pop_up(false), message_gauge(false),
|
||||
disabled_views(VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY), custom_gauge(true), textoffset_x(txtoffset_x),
|
||||
textoffset_y(txtoffset_y), texture_target(-1), canvas_w(-1), canvas_h(-1), target_w(-1), target_h(-1)
|
||||
{
|
||||
position[0] = 0;
|
||||
position[1] = 0;
|
||||
@@ -376,11 +379,11 @@ textoffset_x(txtoffset_x), textoffset_y(txtoffset_y), canvas_w(-1), canvas_h(-1)
|
||||
}
|
||||
|
||||
if(_custom_text) {
|
||||
strcpy_s(custom_text, _custom_text);
|
||||
strcpy_s(default_text, _custom_text);
|
||||
custom_text = _custom_text;
|
||||
default_text = _custom_text;
|
||||
} else {
|
||||
custom_text[0] = '\0';
|
||||
default_text[0] = '\0';
|
||||
custom_text = "";
|
||||
default_text = "";
|
||||
}
|
||||
|
||||
custom_frame.first_frame = -1;
|
||||
@@ -428,9 +431,9 @@ char* HudGauge::getCustomGaugeName()
|
||||
return custom_name;
|
||||
}
|
||||
|
||||
char* HudGauge::getCustomGaugeText()
|
||||
const char* HudGauge::getCustomGaugeText()
|
||||
{
|
||||
return custom_text;
|
||||
return custom_text.c_str();
|
||||
}
|
||||
|
||||
void HudGauge::updateCustomGaugeCoords(int _x, int _y)
|
||||
@@ -452,18 +455,22 @@ void HudGauge::updateCustomGaugeFrame(int frame_offset)
|
||||
custom_frame_offset = frame_offset;
|
||||
}
|
||||
|
||||
void HudGauge::updateCustomGaugeText(char* txt)
|
||||
void HudGauge::updateCustomGaugeText(const char* txt)
|
||||
{
|
||||
if(!custom_gauge) {
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy_s(custom_text, txt);
|
||||
custom_text = txt;
|
||||
}
|
||||
|
||||
bool HudGauge::configOverride()
|
||||
void HudGauge::updateCustomGaugeText(SCP_string& txt)
|
||||
{
|
||||
return config_override;
|
||||
if(!custom_gauge) {
|
||||
return;
|
||||
}
|
||||
|
||||
custom_text = txt;
|
||||
}
|
||||
|
||||
void HudGauge::setFont()
|
||||
@@ -546,8 +553,21 @@ int HudGauge::getObjectType()
|
||||
return gauge_object;
|
||||
}
|
||||
|
||||
void HudGauge::lockConfigColor(bool lock)
|
||||
{
|
||||
lock_color = lock;
|
||||
}
|
||||
|
||||
void HudGauge::sexpLockConfigColor(bool lock)
|
||||
{
|
||||
sexp_lock_color = lock;
|
||||
}
|
||||
|
||||
void HudGauge::updateColor(int r, int g, int b, int a)
|
||||
{
|
||||
if(sexp_lock_color || lock_color)
|
||||
return;
|
||||
|
||||
gr_init_alphacolor(&gauge_color, r, g, b, a);
|
||||
}
|
||||
|
||||
@@ -658,11 +678,14 @@ void HudGauge::render(float frametime)
|
||||
|
||||
setGaugeColor();
|
||||
|
||||
if(custom_text) {
|
||||
if(custom_text[0] != '\0') {
|
||||
hud_num_make_mono(custom_text);
|
||||
renderString(position[0] + textoffset_x, position[1] + textoffset_y, custom_text);
|
||||
}
|
||||
if( !custom_text.empty() ) {
|
||||
char *text = new char[custom_text.size()+1];
|
||||
strcpy(text, custom_text.c_str());
|
||||
|
||||
hud_num_make_mono(text);
|
||||
renderString(position[0] + textoffset_x, position[1] + textoffset_y, text);
|
||||
|
||||
delete[] text;
|
||||
}
|
||||
|
||||
if(custom_frame.first_frame > -1) {
|
||||
@@ -1013,7 +1036,9 @@ void HudGauge::pageIn()
|
||||
void HudGauge::initialize()
|
||||
{
|
||||
//Reset text to default
|
||||
strcpy_s(custom_text, default_text);
|
||||
custom_text = default_text;
|
||||
|
||||
sexp_lock_color = false;
|
||||
}
|
||||
|
||||
bool HudGauge::canRender()
|
||||
@@ -1389,7 +1414,7 @@ void hud_update_frame(float frametime)
|
||||
// to deal with the message. hud_sqaudmsg_do_frame will return 0 if the key
|
||||
// wasn't used in messaging mode, otherwise 1. In the event the key was used,
|
||||
// return immediately out of this function.
|
||||
if ( Players->flags & PLAYER_FLAGS_MSG_MODE ) {
|
||||
if ( Players[Player_num].flags & PLAYER_FLAGS_MSG_MODE ) {
|
||||
hud_squadmsg_do_frame();
|
||||
}
|
||||
|
||||
@@ -1589,7 +1614,7 @@ void hud_render_preprocess(float frametime)
|
||||
}
|
||||
|
||||
HudGaugeMissionTime::HudGaugeMissionTime():
|
||||
HudGauge(HUD_OBJECT_MISSION_TIME, HUD_MISSION_TIME, true, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_MISSION_TIME, HUD_MISSION_TIME, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1811,14 +1836,13 @@ void update_throttle_sound()
|
||||
|
||||
if ( percent_throttle < ZERO_PERCENT ) {
|
||||
if ( Player_engine_snd_loop > -1 ) {
|
||||
snd_chg_loop_status(Player_engine_snd_loop, 0);
|
||||
snd_stop(Player_engine_snd_loop); // Backslash - otherwise, long engine loops keep playing
|
||||
Player_engine_snd_loop = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( Player_engine_snd_loop == -1 ){
|
||||
Player_engine_snd_loop = snd_play_looping( &Snds[SND_ENGINE], 0.0f , -1, -1, percent_throttle * ENGINE_MAX_VOL );
|
||||
Player_engine_snd_loop = snd_play_looping( &Snds[Ship_info[Ships[Player_obj->instance].ship_info_index].engine_snd_cockpit], 0.0f , -1, -1, percent_throttle * ENGINE_MAX_VOL );
|
||||
} else {
|
||||
// The sound may have been trashed at the low-level if sound channel overflow.
|
||||
// TODO: implement system where certain sounds cannot be interrupted (priority?)
|
||||
@@ -1857,7 +1881,7 @@ void hud_damage_popup_init()
|
||||
}
|
||||
|
||||
HudGaugeDamage::HudGaugeDamage():
|
||||
HudGauge(HUD_OBJECT_DAMAGE, HUD_DAMAGE_GAUGE, true, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_DAMAGE, HUD_DAMAGE_GAUGE, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1923,6 +1947,8 @@ void HudGaugeDamage::initialize()
|
||||
Damage_flash_timer = timestamp(1);
|
||||
next_flash = timestamp(1);
|
||||
flash_status = false;
|
||||
|
||||
HudGauge::initialize();
|
||||
}
|
||||
|
||||
void HudGaugeDamage::pageIn()
|
||||
@@ -2262,7 +2288,7 @@ void hud_start_text_flash(char *txt, int t, int interval)
|
||||
}
|
||||
|
||||
HudGaugeTextWarnings::HudGaugeTextWarnings():
|
||||
HudGauge(HUD_OBJECT_TEXT_WARNINGS, HUD_TEXT_FLASH, true, true, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_TEXT_WARNINGS, HUD_TEXT_FLASH, true, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -2271,6 +2297,8 @@ void HudGaugeTextWarnings::initialize()
|
||||
{
|
||||
next_flash = timestamp(0);
|
||||
flash_flags = false;
|
||||
|
||||
HudGauge::initialize();
|
||||
}
|
||||
|
||||
int HudGaugeTextWarnings::maybeTextFlash()
|
||||
@@ -2316,7 +2344,7 @@ void HudGaugeTextWarnings::render(float frametime)
|
||||
}
|
||||
|
||||
HudGaugeKills::HudGaugeKills():
|
||||
HudGauge(HUD_OBJECT_KILLS, HUD_KILLS_GAUGE, true, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_KILLS, HUD_KILLS_GAUGE, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2376,7 +2404,7 @@ void HudGaugeKills::render(float frametime)
|
||||
}
|
||||
|
||||
HudGaugeLag::HudGaugeLag():
|
||||
HudGauge(HUD_OBJECT_LAG, HUD_LAG_GAUGE, true, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_LAG, HUD_LAG_GAUGE, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -2464,18 +2492,11 @@ void HudGaugeLag::render(float frametime)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load in ::Kills_gauge if required
|
||||
* @brief Obsolete initializer for the kills gauge. Now superseded by the new HUD code.
|
||||
*/
|
||||
void hud_init_kills_gauge()
|
||||
{
|
||||
if ( !Kills_gauge_loaded ) {
|
||||
Kills_gauge.first_frame = bm_load_animation(Kills_fname[gr_screen.res], &Kills_gauge.num_frames);
|
||||
if ( Kills_gauge.first_frame == -1 ) {
|
||||
Warning(LOCATION, "Could not load in the kills ani: Kills_fname[gr_screen.res]\n");
|
||||
return;
|
||||
}
|
||||
Kills_gauge_loaded = 1;
|
||||
}
|
||||
Kills_gauge_loaded = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2687,7 +2708,7 @@ void hud_support_view_update()
|
||||
}
|
||||
|
||||
HudGaugeSupport::HudGaugeSupport():
|
||||
HudGauge(HUD_OBJECT_SUPPORT, HUD_SUPPORT_GAUGE, true, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_SUPPORT, HUD_SUPPORT_GAUGE, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3201,7 +3222,7 @@ void hud_add_objective_messsage(int type, int status)
|
||||
}
|
||||
|
||||
HudGaugeObjectiveNotify::HudGaugeObjectiveNotify():
|
||||
HudGauge(HUD_OBJECT_OBJ_NOTIFY, HUD_OBJECTIVES_NOTIFY_GAUGE, true, false, false, VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP, 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_OBJ_NOTIFY, HUD_OBJECTIVES_NOTIFY_GAUGE, false, false, VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP, 255, 255, 255)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -3249,6 +3270,8 @@ void HudGaugeObjectiveNotify::initialize()
|
||||
flash_timer[0] = timestamp(1);
|
||||
flash_timer[1] = timestamp(1);
|
||||
flash_flag = false;
|
||||
|
||||
HudGauge::initialize();
|
||||
}
|
||||
|
||||
void HudGaugeObjectiveNotify::pageIn()
|
||||
@@ -3334,7 +3357,7 @@ void HudGaugeObjectiveNotify::renderRedAlert()
|
||||
{
|
||||
int w, h;
|
||||
|
||||
if ( !red_alert_check_status() ) {
|
||||
if ( !red_alert_in_progress() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3353,7 +3376,7 @@ void HudGaugeObjectiveNotify::renderRedAlert()
|
||||
// Blit the background
|
||||
gr_set_color_fast(&Color_red); // Color box red, because it's an emergency
|
||||
|
||||
GR_AABITMAP(Objective_display_gauge.first_frame, position[0], position[1]);
|
||||
renderBitmap(Objective_display_gauge.first_frame, position[0], position[1]);
|
||||
|
||||
startFlashNotify();
|
||||
if(maybeFlashNotify()) {
|
||||
@@ -3653,11 +3676,6 @@ extern void hudtarget_page_in();
|
||||
*/
|
||||
void hud_page_in()
|
||||
{
|
||||
bm_page_in_aabitmap( Kills_gauge.first_frame, Kills_gauge.num_frames );
|
||||
|
||||
// Paging functions for the rest of the hud code
|
||||
hudtarget_page_in();
|
||||
|
||||
// Go through all hud gauges to page them in
|
||||
int i;
|
||||
size_t j, num_gauges = 0;
|
||||
@@ -3708,7 +3726,7 @@ HudGauge* hud_get_gauge(char* name)
|
||||
}
|
||||
|
||||
HudGaugeMultiMsg::HudGaugeMultiMsg():
|
||||
HudGauge(HUD_OBJECT_MULTI_MSG, HUD_MESSAGE_LINES, true, false, true, 0, 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_MULTI_MSG, HUD_MESSAGE_LINES, false, true, 0, 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3735,7 +3753,7 @@ void HudGaugeMultiMsg::render(float frametime)
|
||||
}
|
||||
|
||||
HudGaugeVoiceStatus::HudGaugeVoiceStatus():
|
||||
HudGauge(HUD_OBJECT_VOICE_STATUS, HUD_MESSAGE_LINES, true, false, true, VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY, 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_VOICE_STATUS, HUD_MESSAGE_LINES, false, true, VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY, 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3774,7 +3792,7 @@ void HudGaugeVoiceStatus::render(float frametime)
|
||||
}
|
||||
|
||||
HudGaugePing::HudGaugePing():
|
||||
HudGauge(HUD_OBJECT_PING, HUD_LAG_GAUGE, true, false, false, 0, 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_PING, HUD_LAG_GAUGE, false, false, 0, 255, 255, 255)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -3811,7 +3829,7 @@ void HudGaugePing::render(float frametime)
|
||||
}
|
||||
|
||||
HudGaugeSupernova::HudGaugeSupernova():
|
||||
HudGauge(HUD_OBJECT_SUPERNOVA, HUD_DIRECTIVES_VIEW, true, false, false, 0, 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_SUPERNOVA, HUD_DIRECTIVES_VIEW, false, false, 0, 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+13
-8
@@ -13,6 +13,7 @@
|
||||
#include "hud/hudgauges.h"
|
||||
#include "graphics/2d.h"
|
||||
#include "hud/hudparse.h"
|
||||
#include "globalincs/vmallocator.h"
|
||||
|
||||
struct object;
|
||||
struct cockpit_display;
|
||||
@@ -214,7 +215,8 @@ protected:
|
||||
|
||||
int font_num;
|
||||
|
||||
bool config_override;
|
||||
bool lock_color;
|
||||
bool sexp_lock_color;
|
||||
bool reticle_follow;
|
||||
bool active;
|
||||
bool off_by_default;
|
||||
@@ -234,8 +236,9 @@ protected:
|
||||
int custom_frame_offset;
|
||||
int textoffset_x, textoffset_y;
|
||||
char custom_name[NAME_LENGTH];
|
||||
char custom_text[NAME_LENGTH];
|
||||
char default_text[NAME_LENGTH];
|
||||
SCP_string custom_text;
|
||||
|
||||
SCP_string default_text;
|
||||
|
||||
// Render to texture stuff
|
||||
char texture_target_fname[MAX_FILENAME_LEN];
|
||||
@@ -246,7 +249,7 @@ protected:
|
||||
public:
|
||||
// constructors
|
||||
HudGauge();
|
||||
HudGauge(int _gauge_object, int _gauge_config, bool _allow_override, bool _slew, bool _message, int _disabled_views, int r, int g, int b);
|
||||
HudGauge(int _gauge_object, int _gauge_config, bool _slew, bool _message, int _disabled_views, int r, int g, int b);
|
||||
// constructor for custom gauges
|
||||
HudGauge(int _gauge_config, bool _slew, int r, int g, int b, char* _custom_name, char* _custom_text, char* frame_fname, int txtoffset_x, int txtoffset_y);
|
||||
|
||||
@@ -262,8 +265,9 @@ public:
|
||||
bool isOffbyDefault();
|
||||
bool isActive();
|
||||
|
||||
bool configOverride();
|
||||
void updateColor(int r, int g, int b, int a);
|
||||
void updateColor(int r, int g, int b, int a = 255);
|
||||
void lockConfigColor(bool lock);
|
||||
void sexpLockConfigColor(bool lock);
|
||||
void updateActive(bool show);
|
||||
void updatePopUp(bool pop_up_flag);
|
||||
void updateSexpOverride(bool sexp);
|
||||
@@ -280,8 +284,9 @@ public:
|
||||
char* getCustomGaugeName();
|
||||
void updateCustomGaugeCoords(int _x, int _y);
|
||||
void updateCustomGaugeFrame(int frame_offset);
|
||||
void updateCustomGaugeText(char* txt);
|
||||
char* getCustomGaugeText();
|
||||
void updateCustomGaugeText(const char* txt);
|
||||
void updateCustomGaugeText(SCP_string& txt);
|
||||
const char* getCustomGaugeText();
|
||||
|
||||
void startPopUp(int time=4000);
|
||||
int popUpActive();
|
||||
|
||||
@@ -584,7 +584,7 @@ void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, in
|
||||
}
|
||||
|
||||
HudGaugeBrackets::HudGaugeBrackets():
|
||||
HudGauge(HUD_OBJECT_BRACKETS, HUD_OFFSCREEN_INDICATOR, true, false, true, VM_DEAD_VIEW, 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_BRACKETS, HUD_OFFSCREEN_INDICATOR, false, true, VM_DEAD_VIEW, 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ void HudGaugeBrackets::render(float frametime)
|
||||
if(!in_frame)
|
||||
g3_start_frame(0);
|
||||
|
||||
for(int i = 0; i < (int)target_display_list.size(); i++) {
|
||||
for(size_t i = 0; i < target_display_list.size(); i++) {
|
||||
// make sure this point is projected. Otherwise, skip.
|
||||
if( !(target_display_list[i].target_point.flags & PF_OVERFLOW) ) {
|
||||
if ( target_display_list[i].objp ) {
|
||||
|
||||
+27
-13
@@ -140,7 +140,7 @@ char *Escort_gauge_filenames[GR_NUM_RESOLUTIONS][MAX_ESCORT_SHIPS] =
|
||||
static int Last_target_index; // index into Escort_gauges for last targeted via 'Next Escort Target' key
|
||||
|
||||
HudGaugeEscort::HudGaugeEscort():
|
||||
HudGauge(HUD_OBJECT_ESCORT, HUD_ESCORT_VIEW, true, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
HudGauge(HUD_OBJECT_ESCORT, HUD_ESCORT_VIEW, false, false, (VM_EXTERNAL | VM_DEAD_VIEW | VM_WARP_CHASE | VM_PADLOCK_ANY | VM_OTHER_SHIP), 255, 255, 255)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -465,12 +465,15 @@ void hud_escort_init()
|
||||
// ----------------------------------------------------------------------
|
||||
// hud_escort_clear_all()
|
||||
//
|
||||
void hud_escort_clear_all()
|
||||
void hud_escort_clear_all(bool clear_flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
Num_escort_ships = 0;
|
||||
for ( i = 0; i < Max_escort_ships; i++ ) {
|
||||
if(clear_flags && (Escort_ships[i].objnum >= 0) && (Objects[Escort_ships[i].objnum].type == OBJ_SHIP) && (Objects[Escort_ships[i].objnum].instance >= 0)){
|
||||
Ships[Objects[Escort_ships[i].objnum].instance].flags &= ~SF_ESCORT;
|
||||
}
|
||||
Escort_ships[i].obj_signature = -99;
|
||||
Escort_ships[i].np_id = -1;
|
||||
shield_info_reset(&Escort_ships[i].hit_info);
|
||||
@@ -602,8 +605,8 @@ void hud_create_complete_escort_list(escort_info *escorts, int *num_escorts)
|
||||
}
|
||||
}
|
||||
|
||||
// don't process ships that are dying, or objects that should be dead
|
||||
if ( (Ships[objp->instance].flags & (SF_DYING|SF_DEPARTING)) || (objp->flags & OF_SHOULD_BE_DEAD) ){
|
||||
// don't process objects that should be dead
|
||||
if ( objp->flags & OF_SHOULD_BE_DEAD ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -759,10 +762,10 @@ void hud_remove_ship_from_escort_index(int dead_index, int objnum)
|
||||
|
||||
}
|
||||
|
||||
// called once per frame to remove dead or departed ships from the escort list
|
||||
// called once per frame to refresh the escort list if important flags changed
|
||||
void hud_escort_cull_list()
|
||||
{
|
||||
int i, objnum;
|
||||
int i;
|
||||
|
||||
int np_index;
|
||||
|
||||
@@ -773,19 +776,30 @@ void hud_escort_cull_list()
|
||||
|
||||
// maybe remove him if he left
|
||||
if ( np_index < 0 ) {
|
||||
hud_remove_ship_from_escort_index(i, -1);
|
||||
i--;
|
||||
hud_setup_escort_list(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// everything else
|
||||
else {
|
||||
for ( i = 0; i < Num_escort_ships; i++ ) {
|
||||
objnum = Escort_ships[i].objnum;
|
||||
int objnum = Escort_ships[i].objnum;
|
||||
Assert( objnum >=0 && objnum < MAX_OBJECTS );
|
||||
if ( Objects[objnum].flags & OF_SHOULD_BE_DEAD || Ships[Objects[objnum].instance].flags & SF_HIDDEN_FROM_SENSORS ) {
|
||||
hud_remove_ship_from_escort_index(i, objnum);
|
||||
i--;
|
||||
|
||||
if ( Objects[objnum].flags & OF_SHOULD_BE_DEAD ) {
|
||||
hud_setup_escort_list(0);
|
||||
break;
|
||||
} else if ( Objects[objnum].type == OBJ_SHIP ) {
|
||||
int shipnum = Objects[objnum].instance;
|
||||
Assert( shipnum >= 0 && shipnum < MAX_SHIPS );
|
||||
|
||||
if ( (Ships[shipnum].flags & SF_HIDDEN_FROM_SENSORS)
|
||||
|| ((Ships[shipnum].flags2 & SF2_STEALTH) && ((Ships[shipnum].team != Player_ship->team) || (Ships[shipnum].flags2 & SF2_FRIENDLY_STEALTH_INVIS)))
|
||||
) {
|
||||
hud_setup_escort_list(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -834,7 +848,7 @@ void hud_add_ship_to_escort(int objnum, int supress_feedback)
|
||||
complete_escorts[num_complete_escorts].obj_signature = Objects[objnum].signature;
|
||||
complete_escorts[num_complete_escorts].priority = Ships[Objects[objnum].instance].escort_priority;
|
||||
|
||||
// remove him from escort list
|
||||
// add him to escort list
|
||||
Ships[Objects[objnum].instance].flags |= SF_ESCORT;
|
||||
|
||||
num_complete_escorts++;
|
||||
|
||||
@@ -26,7 +26,7 @@ void hud_escort_init();
|
||||
void hud_setup_escort_list(int level = 1);
|
||||
void hud_escort_view_toggle();
|
||||
void hud_add_remove_ship_escort(int objnum, int supress_feedback = 0);
|
||||
void hud_escort_clear_all();
|
||||
void hud_escort_clear_all(bool clear_flags = false);
|
||||
void hud_escort_ship_hit(object *objp, int quadrant);
|
||||
void hud_escort_target_next();
|
||||
void hud_escort_cull_list();
|
||||
|
||||
Loaded 100 of 302 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user