Skip to content

Commit 5e10fcc

Browse files
committed
Merge remote-tracking branch 'upstream/master' into turret-alt-math-fix
2 parents eb538ff + 12672d0 commit 5e10fcc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+10588
-456
lines changed

code/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ TARGET_LINK_LIBRARIES(code PUBLIC openal)
2626
TARGET_LINK_LIBRARIES(code PUBLIC ${LUA_LIBS})
2727
TARGET_LINK_LIBRARIES(code PUBLIC ${PNG_LIBS})
2828
TARGET_LINK_LIBRARIES(code PUBLIC ${JPEG_LIBS})
29+
TARGET_LINK_LIBRARIES(code PUBLIC lz4)
2930

3031
TARGET_LINK_LIBRARIES(code PUBLIC sdl2)
3132

code/ai/aiturret.cpp

Lines changed: 33 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -110,121 +110,51 @@ void turret_instance_find_world_orient(matrix* out_mat, int model_instance_num,
110110
*
111111
* @return 1 if objp is in fov of the specified turret. Otherwise return 0.
112112
*/
113-
int object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
113+
bool object_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
114114
{
115115
vec3d v2e;
116116
float size_mod;
117-
bool in_fov;
117+
bool in_fov = false;
118118

119-
vm_vec_normalized_dir(&v2e, &objp->pos, tpos);
120-
size_mod = objp->radius / (dist + objp->radius);
121-
122-
in_fov = turret_fov_test(ss, tvec, &v2e, size_mod);
123-
124-
if ( in_fov ) {
125-
return 1;
126-
}
119+
if (ss->flags[Ship::Subsystem_Flags::FOV_edge_check]) {
120+
int model_num;
121+
switch (objp->type) {
122+
case OBJ_SHIP:
123+
model_num = Ship_info[Ships[objp->instance].ship_info_index].model_num;
124+
break;
125+
case OBJ_ASTEROID:
126+
model_num = Asteroid_info[Asteroids[objp->instance].asteroid_type].model_num[Asteroids[objp->instance].asteroid_subtype];
127+
break;
128+
default:
129+
vm_vec_normalized_dir(&v2e, &objp->pos, tpos);
130+
size_mod = objp->radius / (dist + objp->radius);
127131

128-
return 0;
129-
}
132+
in_fov = turret_fov_test(ss, tvec, &v2e, size_mod);
130133

131-
bool is_object_radius_in_turret_fov(object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, vec3d *v2e, vec3d *predicted_pos, float distance)
132-
{
133-
float target_dist = distance;
134-
if (distance == 0.0f)
135-
target_dist = vm_vec_dist(predicted_pos,tpos);
136-
137-
if (object_in_turret_fov(objp, ss, tvec, tpos, target_dist + objp->radius)) {
138-
// so the targeted spot in not in fov but the enemy + radius is
139-
// lets align the darn gun and try shooting there
140-
vec3d temp_vec;
141-
float multiplier = 0;
142-
model_subsystem *tp = ss->system_info;
134+
return in_fov;
135+
}
143136

144-
// project v2e_from_turret to turret normal
145-
// substract resultant vector from the temp_vec (v2e_from_turret)
146-
// adjust z component as necessary
147-
// calculate multiplier for the resultant vector
148-
// use multiplier and the z component and compose a new vector
149-
float dot = vm_vec_dot(v2e, tvec);
137+
auto pm = model_get(model_num);
138+
for (int i = 0; i < 8; i++) {
139+
vec3d bbox_point;
140+
vm_vec_unrotate(&bbox_point, &pm->bounding_box[i], &objp->orient);
141+
bbox_point += objp->pos;
150142

151-
vm_vec_scale_add(&temp_vec, v2e, tvec, -dot);
143+
vm_vec_normalized_dir(&v2e, &bbox_point, tpos);
144+
in_fov = turret_fov_test(ss, tvec, &v2e, -0.2f);
152145

153-
if (IS_VEC_NULL_SQ_SAFE(&temp_vec)) {
154-
// return false, target is perfectly aligned over or below the turret
155-
// safe bet is to allow turret to reacquire better target
156-
return false;
146+
if (in_fov)
147+
return true;
157148
}
158149

159-
// normalize the vec, it needs to be done regardless
160-
vm_vec_normalize(&temp_vec);
161-
bool fix_elevation = false;
162-
bool fix_base_rot = false;
163-
164-
if (dot < tp->turret_fov) {
165-
dot = tp->turret_fov;
166-
fix_elevation = true;
167-
}
168-
if (dot > tp->turret_max_fov) {
169-
dot = tp->turret_max_fov;
170-
fix_elevation = true;
171-
}
172-
173-
if (tp->flags[Model::Subsystem_Flags::Turret_restricted_fov]) {
174-
// Since we no longer maintain world_to_turret_matrix, regenerate it here.
175-
matrix turret_matrix;
176-
turret_instance_find_world_orient(&turret_matrix, Ships[Objects[ss->parent_objnum].instance].model_instance_num, tp->subobj_num, &vmd_identity_matrix);
177-
178-
vec3d turret_v2e;
179-
vm_vec_rotate(&turret_v2e, &temp_vec, &turret_matrix);
180-
181-
// now in turrets frame of reference
182-
// check if math is actually possible
183-
if (!((turret_v2e.xyz.x == 0) && (turret_v2e.xyz.z == 0))) {
184-
float temp_y = turret_v2e.xyz.y;
185-
turret_v2e.xyz.y = 0.0f;
186-
// make sure null vecs wont happen
187-
if (!IS_VEC_NULL_SQ_SAFE(&turret_v2e)) {
188-
vm_vec_normalize(&turret_v2e);
189-
// only do this if it actually is required
190-
if (turret_v2e.xyz.z < tp->turret_base_fov) {
191-
float check_pos = 1;
192-
193-
fix_base_rot = true;
194-
turret_v2e.xyz.z = tp->turret_base_fov;
195-
if (turret_v2e.xyz.x < 0)
196-
check_pos = -1;
197-
turret_v2e.xyz.x = check_pos * sqrtf(1 - (turret_v2e.xyz.z* turret_v2e.xyz.z));
198-
199-
// restore y component
200-
float scalar = sqrtf(1 - (temp_y*temp_y));
201-
vm_vec_scale(&turret_v2e, scalar);
202-
turret_v2e.xyz.z = temp_y;
203-
// back to world frame
204-
vm_vec_unrotate(&temp_vec, &turret_v2e, &turret_matrix);
205-
}
206-
}
207-
}
208-
}
150+
} else {
151+
vm_vec_normalized_dir(&v2e, &objp->pos, tpos);
152+
size_mod = objp->radius / (dist + objp->radius);
209153

210-
if (fix_elevation || fix_base_rot) {
211-
if (fix_elevation) {
212-
multiplier = sqrtf(1 - (dot*dot));
213-
// keep the temp_vec scaled with the tweaked vector
214-
vm_vec_scale(&temp_vec, multiplier);
215-
}
216-
vm_vec_scale_add(v2e, &temp_vec, tvec, dot);
217-
// and we are done with v2e...
218-
vm_vec_scale_add(predicted_pos, tpos, v2e, target_dist);
219-
// and we are done with predicted position
220-
return true;
221-
} else {
222-
mprintf(("Warning: Function 'is_object_radius_in_turret_fov' was called\nwithout need to fix turret alignments\n"));
223-
return false;
224-
}
154+
in_fov = turret_fov_test(ss, tvec, &v2e, size_mod);
225155
}
226-
// outside of the expanded radii, unable to align, return false
227-
return false;
156+
157+
return in_fov;
228158
}
229159

230160
/**
@@ -1205,17 +1135,11 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
12051135
if ( tagged_only_flag && ship_is_tagged(&Objects[aip->target_objnum]) ) {
12061136
// select new target if aip->target_objnum is out of field of view
12071137
vec3d v2e;
1208-
float dist;
12091138
bool in_fov;
1210-
dist = vm_vec_normalized_dir(&v2e, &Objects[aip->target_objnum].pos, tpos);
1139+
vm_vec_normalized_dir(&v2e, &Objects[aip->target_objnum].pos, tpos);
12111140

12121141
in_fov = turret_fov_test(turret_subsys, tvec, &v2e);
12131142

1214-
if (turret_subsys->flags[Ship::Subsystem_Flags::FOV_edge_check]) {
1215-
if (in_fov == false)
1216-
if (object_in_turret_fov(&Objects[aip->target_objnum], turret_subsys, tvec, tpos, dist + Objects[aip->target_objnum].radius))
1217-
in_fov = true;
1218-
}
12191143
// MODIFY FOR ATTACKING BIG SHIP
12201144
// dot += (0.5f * Objects[aip->target_objnum].radius / dist);
12211145
if (in_fov) {
@@ -1457,11 +1381,6 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
14571381

14581382
in_fov = turret_fov_test(ss, gvec, &v2e);
14591383

1460-
if (ss->flags[Ship::Subsystem_Flags::FOV_edge_check]) {
1461-
if (in_fov == false)
1462-
in_fov = is_object_radius_in_turret_fov(&Objects[ss->turret_enemy_objnum], ss, gvec, &gun_pos, &v2e, predicted_enemy_pos, 0.0f);
1463-
}
1464-
14651384
if (in_fov) {
14661385
ret_val = model_rotate_gun(objp, pm, pmi, tp, predicted_enemy_pos);
14671386
} else if ((tp->flags[Model::Subsystem_Flags::Turret_reset_idle]) &&(timestamp_elapsed(ss->rotation_timestamp))) {

code/cfile/cfile.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ static int cfget_cfile_block()
866866
cfile->data = nullptr;
867867
cfile->fp = nullptr;
868868
cfile->type = CFILE_BLOCK_USED;
869+
cf_clear_compression_info(cfile);
869870
return i;
870871
}
871872
}
@@ -921,7 +922,7 @@ int cfclose( CFILE * cfile )
921922
} else {
922923
// VP do nothing
923924
}
924-
925+
cf_clear_compression_info(cfile);
925926
cfile->type = CFILE_BLOCK_UNUSED;
926927
return result;
927928
}
@@ -973,7 +974,7 @@ static CFILE *cf_open_fill_cfblock(const char* source, int line, const char* ori
973974
if(pos == -1L)
974975
pos = 0;
975976
cf_init_lowlevel_read_code(cfp,0,filelength(fileno(fp)), 0 );
976-
977+
cf_check_compression(cfp);
977978
return cfp;
978979
}
979980
}
@@ -1008,7 +1009,7 @@ static CFILE *cf_open_packed_cfblock(const char* source, int line, const char* o
10081009
cfp->line_num = line;
10091010

10101011
cf_init_lowlevel_read_code(cfp,offset, size, 0 );
1011-
1012+
cf_check_compression(cfp);
10121013
return cfp;
10131014
}
10141015

@@ -1052,6 +1053,7 @@ static CFILE *cf_open_mapped_fill_cfblock(const char* source, int line, const ch
10521053
cfp->line_num = line;
10531054

10541055
cf_init_lowlevel_read_code(cfp, 0, 0, 0 );
1056+
10551057
#if defined _WIN32
10561058
cfp->hMapFile = CreateFileMapping(cfp->hInFile, NULL, PAGE_READONLY, 0, 0, NULL);
10571059
if (cfp->hMapFile == NULL) {

code/cfile/cfilearchive.cpp

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "cfile/cfile.h"
2626
#include "cfile/cfilearchive.h"
27+
#include "cfile/cfilecompression.h"
2728
#include "luaconf.h"
2829

2930
#include <sstream>
@@ -33,7 +34,6 @@
3334
#define CHECK_POSITION
3435

3536
// Called once to setup the low-level reading code.
36-
3737
void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size, size_t pos )
3838
{
3939
Assert(cfile != nullptr);
@@ -54,18 +54,45 @@ void cf_init_lowlevel_read_code( CFILE * cfile, size_t lib_offset, size_t size,
5454
}
5555
}
5656

57+
//This function checks the file header to see if the file is compressed, if so it fills the correct compression info.
58+
void cf_check_compression(CFILE* cfile)
59+
{
60+
if (cfile->size <= 16)
61+
return;
62+
int header=cfread_int(cfile);
63+
cfseek(cfile, 0, SEEK_SET);
64+
if (comp_check_header(header) == COMP_HEADER_MATCH)
65+
comp_create_ci(cfile, header);
66+
}
67+
68+
//This function is called to cleanup compression info when the cfile handle is reused.
69+
void cf_clear_compression_info(CFILE* cfile)
70+
{
71+
if (cfile->compression_info.header != 0)
72+
{
73+
free(cfile->compression_info.offsets);
74+
free(cfile->compression_info.decoder_buffer);
75+
cfile->compression_info.offsets = nullptr;
76+
cfile->compression_info.decoder_buffer = nullptr;
77+
cfile->compression_info.header = 0;
78+
cfile->compression_info.block_size = 0;
79+
cfile->compression_info.last_decoded_block_pos = 0;
80+
cfile->compression_info.last_decoded_block_bytes = 0;
81+
cfile->compression_info.num_offsets = 0;
82+
}
83+
}
5784

5885

5986
// cfeof() Tests for end-of-file on a stream
6087
//
6188
// returns a nonzero value after the first read operation that attempts to read
6289
// past the end of the file. It returns 0 if the current position is not end of file.
6390
// There is no error return.
64-
6591
int cfeof(CFILE *cfile)
6692
{
6793
Assert(cfile != NULL);
68-
94+
if (cfile->compression_info.header != 0)
95+
return comp_feof(cfile);
6996
int result = 0;
7097

7198
#if defined(CHECK_POSITION) && !defined(NDEBUG)
@@ -92,6 +119,8 @@ int cfeof(CFILE *cfile)
92119
int cftell( CFILE * cfile )
93120
{
94121
Assert(cfile != NULL);
122+
if (cfile->compression_info.header != 0)
123+
return (int)comp_ftell(cfile);
95124

96125
#if defined(CHECK_POSITION) && !defined(NDEBUG)
97126
if (cfile->fp) {
@@ -117,6 +146,9 @@ int cfseek( CFILE *cfile, int offset, int where )
117146

118147
Assert(cfile != NULL);
119148

149+
if (cfile->compression_info.header != 0)
150+
return comp_fseek(cfile, offset, where);
151+
120152
// TODO: seek to offset in memory mapped file
121153
Assert( !cfile->mem_mapped );
122154

@@ -202,23 +234,31 @@ int cfread(void *buf, int elsize, int nelem, CFILE *cfile)
202234
// This is a file from memory
203235
bytes_read = size;
204236
memcpy(buf, reinterpret_cast<const char*>(cfile->data) + cfile->raw_position, size);
237+
} else if (cfile->compression_info.header != 0) {
238+
bytes_read = comp_fread(cfile, reinterpret_cast<char*>(buf),size);
239+
if (bytes_read != size)
240+
{
241+
mprintf(("\nFile: %s decompression error. Result was: %d expected: %d\n", cfile->original_filename.c_str(), (int)bytes_read, (int)size));
242+
Assertion(bytes_read == size, "File decompression error!");
243+
}
205244
} else {
206-
bytes_read = fread( buf, 1, size, cfile->fp );
245+
bytes_read = fread(buf, 1, size, cfile->fp);
207246
}
247+
208248
if ( bytes_read > 0 ) {
209249
cfile->raw_position += bytes_read;
210250
Assertion(cfile->raw_position <= cfile->size, "Invalid raw_position value detected!");
211251
}
212252

213253
#if defined(CHECK_POSITION) && !defined(NDEBUG)
214-
if (cfile->fp) {
254+
//Raw position is not the fp position with compressed files
255+
if (cfile->fp && cfile->compression_info.header == 0) {
215256
auto tmp_offset = ftell(cfile->fp) - cfile->lib_offset;
216-
Assert(tmp_offset==cfile->raw_position);
257+
Assert(tmp_offset == cfile->raw_position);
217258
}
218259
#endif
219260

220261
return (int)(bytes_read / elsize);
221-
222262
}
223263

224264
int cfread_lua_number(double *buf, CFILE *cfile)
@@ -266,4 +306,3 @@ int cfread_lua_number(double *buf, CFILE *cfile)
266306
return items_read;
267307

268308
}
269-

0 commit comments

Comments
 (0)