Improve interaction of Del+F with normal map usage

Refactor edge computation into helper.

Let Automap_visited always be exactly what the player mapped normally.
This allows reversing Del+F.
This commit is contained in:
Kp 2013-12-15 18:32:10 +00:00
parent 61ac9c31f3
commit ad90c245b6
3 changed files with 36 additions and 51 deletions

View file

@ -40,6 +40,8 @@ typedef struct segmasks {
sbyte centermask; //which sides center point is on back of (6 bits)
} segmasks;
struct segment_depth_array_t : public array<ubyte, MAX_SEGMENTS> {};
extern int Highest_vertex_index; // Highest index in Vertices and Vertex_active, an efficiency hack
extern int Highest_segment_index; // Highest index in Segments, an efficiency hack
extern int Doing_lighting_hack_flag;
@ -138,7 +140,7 @@ extern void pick_random_point_in_seg(vms_vector *new_pos, int segnum);
extern void validate_segment_side(segment *sp, int sidenum);
int check_segment_connections(void);
void flush_fcd_cache(void);
int set_segment_depths(int start_seg, array<ubyte, MAX_SEGMENTS> &segbuf);
unsigned set_segment_depths(int start_seg, array<ubyte, MAX_SEGMENTS> *limit, segment_depth_array_t &depths);
void apply_all_changed_light(void);
void set_ambient_sound_flags(void);

View file

@ -136,7 +136,7 @@ typedef struct automap
int blue_48;
int red_48;
control_info controls;
array<ubyte, MAX_SEGMENTS> Automap_full_depth; // same as Automap_visited but filled completely - visited or not - to adjust depth with map powerup or cheat
segment_depth_array_t depth_array;
} automap;
#define MAX_EDGES_FROM_VERTS(v) ((v)*4)
@ -153,6 +153,7 @@ typedef struct automap
#define K_GREEN_31 BM_XRGB(0, 31, 0)
int Automap_active = 0;
static int Automap_debug_show_all_segments;
static void init_automap_colors(automap *am)
{
@ -188,7 +189,7 @@ array<ubyte, MAX_SEGMENTS> Automap_visited; // Segment visited list
// Function Prototypes
static void adjust_segment_limit(automap *am, int SegmentLimit);
static void draw_all_edges(automap *am);
static void automap_build_edge_list(automap *am);
static void automap_build_edge_list(automap *am, int add_all_edges);
#define MAX_DROP_MULTI 2
#define MAX_DROP_SINGLE 9
@ -376,6 +377,9 @@ static void ClearMarkers()
void automap_clear_visited()
{
Automap_visited.fill(0);
#ifndef NDEBUG
Automap_debug_show_all_segments = 0;
#endif
ClearMarkers();
}
@ -552,7 +556,8 @@ static void draw_automap(automap *am)
g3_draw_sphere(&sphere_point,objp->size);
break;
case OBJ_POWERUP:
if ( Automap_visited[objp->segnum] ) {
if (Automap_visited[objp->segnum] || Automap_debug_show_all_segments)
{
ubyte id = get_powerup_id(objp);
if (id==POW_KEY_RED)
gr_setcolor(BM_XRGB(63, 5, 5));
@ -606,6 +611,17 @@ static void draw_automap(automap *am)
#define MAP_BACKGROUND_FILENAME ((HIRESMODE && PHYSFSX_exists("mapb.pcx",1))?"MAPB.PCX":"MAP.PCX")
#endif
static void recompute_automap_segment_visibility(automap *am)
{
int compute_depth_all_segments = (cheats.fullautomap || (Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL));
if (Automap_debug_show_all_segments)
compute_depth_all_segments = 1;
automap_build_edge_list(am, compute_depth_all_segments);
am->max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, compute_depth_all_segments ? NULL : &Automap_visited, am->depth_array);
am->segment_limit = am->max_segments_away;
adjust_segment_limit(am, am->segment_limit);
}
static int automap_key_command(window *wind, d_event *event, automap *am)
{
int c = event_key_get(event);
@ -636,26 +652,14 @@ static int automap_key_command(window *wind, d_event *event, automap *am)
{
cheats.fullautomap = !cheats.fullautomap;
// if cheat of map powerup, work with full depth
if (cheats.fullautomap || Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL)
{
am->Automap_full_depth.fill(1);
am->max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, am->Automap_full_depth);
}
else
am->max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, Automap_visited);
am->segment_limit = am->max_segments_away;
adjust_segment_limit(am, am->segment_limit);
automap_build_edge_list(am);
recompute_automap_segment_visibility(am);
}
return 1;
#endif
#ifndef NDEBUG
case KEY_DEBUGGED+KEY_F: {
Automap_visited.fill(1);
automap_build_edge_list(am);
am->max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, Automap_visited);
am->segment_limit = am->max_segments_away;
adjust_segment_limit(am, am->segment_limit);
Automap_debug_show_all_segments = !Automap_debug_show_all_segments;
recompute_automap_segment_visibility(am);
}
return 1;
#endif
@ -954,8 +958,6 @@ void do_automap( int key_code )
gr_set_current_canvas(NULL);
automap_build_edge_list(am);
if ( am->viewDist==0 )
am->viewDist = ZOOM_DEFAULT;
@ -972,16 +974,7 @@ void do_automap( int key_code )
am->t2 = am->t1;
//Fill in Automap_visited from Objects[Players[Player_num].objnum].segnum
// if cheat of map powerup, work with full depth
if (cheats.fullautomap || Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL)
{
am->Automap_full_depth.fill(1);
am->max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, am->Automap_full_depth);
}
else
am->max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, Automap_visited);
am->segment_limit = am->max_segments_away;
adjust_segment_limit(am, am->segment_limit);
recompute_automap_segment_visibility(am);
// ZICO - code from above to show frame in OGL correctly. Redundant, but better readable.
// KREATOR - Now applies to all platforms so double buffering is supported
@ -1011,10 +1004,7 @@ void adjust_segment_limit(automap *am, int SegmentLimit)
e = &am->edges[i];
e->flags |= EF_TOO_FAR;
for (e1=0; e1<e->num_faces; e1++ ) {
ubyte depthlimit = Automap_visited[e->segnum[e1]];
// if cheat of map powerup, work with full depth
if (cheats.fullautomap || Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL)
depthlimit = am->Automap_full_depth[e->segnum[e1]];
ubyte depthlimit = am->depth_array[e->segnum[e1]];
if ( depthlimit <= SegmentLimit ) {
e->flags &= (~EF_TOO_FAR);
break;
@ -1359,6 +1349,7 @@ static void add_segment_edges(automap *am, segment *seg)
#if defined(DXX_BUILD_DESCENT_II)
// If they have a map powerup, draw unvisited areas in dark blue.
// NOTE: D1 originally had this part of code but w/o cheat-check. It's only supposed to draw blue with powerup that does not exist in D1. So make this D2-only
if (!Automap_debug_show_all_segments)
if ((cheats.fullautomap || Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL) && (!Automap_visited[segnum]))
color = am->wall_revealed_color;
Here:
@ -1401,7 +1392,7 @@ static void add_unknown_segment_edges(automap *am, segment *seg)
}
}
void automap_build_edge_list(automap *am)
void automap_build_edge_list(automap *am, int add_all_edges)
{
int i,e1,e2,s;
Edge_info * e;
@ -1414,7 +1405,7 @@ void automap_build_edge_list(automap *am)
am->num_edges = 0;
am->highest_edge_index = -1;
if (cheats.fullautomap || (Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL) ) {
if (add_all_edges) {
// Cheating, add all edges as visited
for (s=0; s<=Highest_segment_index; s++)
#ifdef EDITOR

View file

@ -1644,45 +1644,37 @@ void pick_random_point_in_seg(vms_vector *new_pos, int segnum)
// ----------------------------------------------------------------------------------------------------------
// Set the segment depth of all segments from start_seg in *segbuf.
// Returns maximum depth value.
int set_segment_depths(int start_seg, array<ubyte, MAX_SEGMENTS> &segbuf)
unsigned set_segment_depths(int start_seg, array<ubyte, MAX_SEGMENTS> *limit, segment_depth_array_t &depth)
{
int i, curseg;
ubyte visited[MAX_SEGMENTS];
int queue[MAX_SEGMENTS];
int head, tail;
int depth;
int parent_depth=0;
depth = 1;
head = 0;
tail = 0;
for (i=0; i<=Highest_segment_index; i++)
visited[i] = 0;
if (segbuf[start_seg] == 0)
return 1;
queue[tail++] = start_seg;
visited[start_seg] = 1;
segbuf[start_seg] = depth++;
if (depth == 0)
depth = 255;
depth[start_seg] = 1;
unsigned parent_depth=0;
while (head < tail) {
curseg = queue[head++];
parent_depth = segbuf[curseg];
parent_depth = depth[curseg];
for (i=0; i<MAX_SIDES_PER_SEGMENT; i++) {
int childnum;
childnum = Segments[curseg].children[i];
if (childnum != -1)
if (segbuf[childnum])
if (!limit || (*limit)[childnum])
if (!visited[childnum]) {
visited[childnum] = 1;
segbuf[childnum] = parent_depth+1;
depth[childnum] = min(static_cast<unsigned>(std::numeric_limits<segment_depth_array_t::value_type>::max()), parent_depth + 1);
queue[tail++] = childnum;
}
}