📄 raycast.cpp
字号:
if (ceil_height_diff>0 && sec_ceil_texture!=cur_sky_texture)
norm_ceiling=TRUE;
else norm_ceiling=FALSE;
} else do_upper=FALSE;
if ((wall_type==LOW_WALL) || (wall_type==MID_WALL) && (!(Cur_Sec->flags & VOXEL_SECTOR))) {
do_lower=TRUE;
if (floor_height_diff>0 && sec_floor_texture!=cur_sky_texture)
norm_floor=TRUE;
else norm_floor=FALSE;
} else do_lower=FALSE;
// Set initial fixed point sums
mid_sum_top=mid_walls.top_start; mid_sum_bottom=mid_walls.bottom_start;
top_increment=mid_walls.top_increment; bottom_increment=mid_walls.bottom_increment;
prev_win_top=prev_wall_top=win_tops[proj_left];
prev_win_bottom=prev_wall_bottom=win_bottoms[proj_left];
// init covering mode used to correct bounds with upper & lower textures
covering_mode=FALSE;
cur_bounds=mid_walls.cur_bounds;
for (cur_ray=proj_left; cur_ray<proj_right; cur_ray++) {
// Get the short values for actual screen coordinates
mid_top=mid_sum_top>>SHIFT;
mid_bottom=mid_sum_bottom>>SHIFT;
// Increment fixed point sums
mid_sum_top+=top_increment;
mid_sum_bottom+=bottom_increment;
// Adjust against window bounds
cur_win_top=win_tops[cur_ray];
cur_win_bottom=win_bottoms[cur_ray];
// save non clipped bounds
no_clip_top=mid_top;
no_clip_bottom=mid_bottom;
Assert(no_clip_top>no_clip_bottom, "Bad Seg! at ssetup_count= " << ssetup_count);
// Adjust against window top
if (mid_top < cur_win_top) {
mid_top=cur_win_top;
} /* endif */
if (mid_bottom < cur_win_top) {
mid_bottom=cur_win_top;
} /* endif */
// Adjust against window bottom
if (mid_bottom > cur_win_bottom) {
mid_bottom=cur_win_bottom;
} /* endif */
if (mid_top > cur_win_bottom) {
mid_top=cur_win_bottom;
} /* endif */
// Do the floor and ceiling
#ifdef DO_FLOORS
floor_ray=cur_ray;
if (do_upper) {
floor_texture=sec_ceil_texture;
if (norm_ceiling) {
cur_height_diff=ceil_height_diff;
if (prev_win_top < cur_win_top) {
floor_start=prev_win_top; floor_end=MIN(cur_win_top, prev_wall_top);
Finish_Tex();
} else {
floor_start=cur_win_top; floor_end=MIN(prev_win_top, mid_top);
Start_Tex();
}
if (mid_top < prev_wall_top) {
floor_start=MAX(mid_top, prev_win_top); floor_end=prev_wall_top;
Finish_Tex();
} else {
floor_start=MAX(prev_wall_top, cur_win_top); floor_end=mid_top;
Start_Tex();
} /* endif */
} else {
floor_start=cur_win_top; floor_end=mid_top;
Draw_Sky_Column();
}
prev_win_top=cur_win_top;
prev_wall_top=mid_top;
} /* end of if "do_upper"*/
if (do_lower) {
floor_texture=sec_floor_texture;
if ( norm_floor ) {
cur_height_diff=floor_height_diff;
if (cur_win_bottom < prev_win_bottom) {
floor_start=MAX(cur_win_bottom, prev_wall_bottom); floor_end=prev_win_bottom;
Finish_Tex();
} else {
floor_start=MAX(mid_bottom, prev_win_bottom); floor_end=cur_win_bottom;
Start_Tex();
}
if (prev_wall_bottom < mid_bottom) {
floor_start=prev_wall_bottom; floor_end=MIN(prev_win_bottom, mid_bottom);
Finish_Tex();
} else {
floor_start=mid_bottom; floor_end=MIN(prev_wall_bottom, cur_win_bottom);
Start_Tex();
} /* endif */
} else {
floor_start=mid_bottom; floor_end=cur_win_bottom;
Draw_Sky_Column();
}
prev_win_bottom=cur_win_bottom;
prev_wall_bottom=mid_bottom;
} /* end of if "do_lower" */
#endif
#ifdef CLIPVERT
// Update bounding windows
//Note: Since upper and lower textures define the difference between two
//sectors, you bound the top of a window with an upper texture's bottom,
//and the bottom of a window with a lower texture's top
if (wall_type == MID_WALL) {
win_tops[cur_ray]=mid_top;
win_bottoms[cur_ray]=mid_bottom;
}
if (wall_type == LOW_WALL) {
win_bottoms[cur_ray]=mid_top;
#ifdef CHECK_HIGH_LOW_CLIP_OUT
if (covering_mode) {
if (no_clip_top > cur_win_top) {
VB_CoverSection(cur_bounds, cov_mode_start, cur_ray);
covering_mode=FALSE;
}
} else {
if (no_clip_top <= cur_win_top) {
cov_mode_start=cur_ray;
covering_mode=TRUE;
}
}
#endif
}
if (wall_type == HIGH_WALL) {
win_tops[cur_ray]=mid_bottom;
#ifdef CHECK_HIGH_LOW_CLIP_OUT
if (covering_mode) {
if (no_clip_bottom < cur_win_bottom) {
VB_CoverSection(cur_bounds, cov_mode_start, cur_ray);
covering_mode=FALSE;
}
} else {
if (no_clip_bottom >= cur_win_bottom) {
cov_mode_start=cur_ray;
covering_mode=TRUE;
}
}
#endif
}
#endif
// Do we even have a wall?
if (mid_top >= mid_bottom)
continue;
// Setup light & column
cur_increment=fixeddiv(seg_height, mid_sum_bottom-mid_sum_top);
cur_clip=fixedmult(cur_increment, (mid_top<<SHIFT)-mid_sum_top);
long_distance=intersects[cur_ray].distance>>SHIFT;
temp_light=base_light-(long_distance >> lt_speed);
if (temp_light <0) temp_light=0;
if (temp_light > MAX_LIGHT) temp_light=MAX_LIGHT;
cur_light=pal_table[temp_light];
cur_column=intersects[cur_ray].xpos;
if (cur_column<0)
cur_column=texture_and_width-((-cur_column)&texture_and_width);
else cur_column&=texture_and_width;
// And setup wall run
if (wall_run_count>=MAX_WALL_RUNS) {
break;
} /* endif */
cur_wall_run=wall_runs+wall_run_count;
wall_run_count++;
cur_wall_run->width_shift=texture_width_shift;
cur_wall_run->bound_val=texture_and_height;
cur_wall_run->texture=wall_texture;
cur_wall_run->top=mid_top;
cur_wall_run->scale=mid_bottom-mid_top;
cur_wall_run->ray=cur_ray;
cur_wall_run->increment=cur_increment;
cur_wall_run->clip=cur_clip;
cur_wall_run->light=cur_light;
cur_wall_run->column=(Byte)cur_column;
} /* endfor */
#ifdef CHECK_HIGH_LOW_CLIP_OUT
if (covering_mode)
VB_CoverSection(cur_bounds, cov_mode_start, proj_right);
#endif
if (do_upper && norm_ceiling) {
cur_height_diff=ceil_height_diff;
floor_texture=sec_ceil_texture;
floor_ray=proj_right;
floor_start=prev_win_top; floor_end=prev_wall_top;
Finish_Tex();
} /* endif */
if (do_lower && norm_floor) {
cur_height_diff=floor_height_diff;
floor_texture=sec_floor_texture;
floor_ray=proj_right;
floor_start=prev_wall_bottom; floor_end=prev_win_bottom;
Finish_Tex();
} /* endif */
}
/*
Get_Intersects
This is the third time I am writing this routine. I do not know why I keep losing it
In any case, this routine gets the intersection values along the seg for each ray
Notes: It modifies global array intersects and require setup intersection to have been
called previously
*/
void Get_Intersects(pvector2 base_v, angle_type angle_diff)
{
intersect_struct * cur_intersect;
long test_angle;
// Decide whether deriving columns from x or y coordinate is more accurate
test_angle=angle_diff;
if (test_angle > ANGLE_180) test_angle-=ANGLE_180;
BOOL is_y_angle=( ((test_angle <= ANGLE_45) || (test_angle >=ANGLE_135)) ? TRUE : FALSE);
// based on that decision, run two different loops to get distance and column values
if (is_y_angle) {
MYFIXED base_y, subs_y;
base_y=base_v->y;
for (short cur_ray=proj_left; cur_ray < proj_right; cur_ray++) {
cur_intersect=intersects+cur_ray;
cur_intersect->distance=Get_Intersection_Y(cur_ray);
Assert((cur_intersect->distance <= 0), "Negative column distance");
subs_y=cur_intersect->distance-base_y;
cur_intersect->xpos=convtoLONG(fixeddiv(subs_y << W_TEX_SHIFT,
rcos_table[angle_diff]));
cur_intersect->increment=fixedmult(cur_intersect->distance, y_inv_trans);
} /* endfor */
} else {
MYFIXED base_x, subs_x;
base_x=base_v->x;
for (short cur_ray=proj_left; cur_ray < proj_right; cur_ray++) {
cur_intersect=intersects+cur_ray;
cur_intersect->distance=Get_Intersection_Y(cur_ray);
Assert((cur_intersect->distance <=0), "Negative column distance");
subs_x=Get_Intersection_X()-base_x;
cur_intersect->xpos=convtoLONG(fixeddiv(subs_x << W_TEX_SHIFT,
rsin_table[angle_diff]));
cur_intersect->increment=fixedmult(cur_intersect->distance, y_inv_trans);
} /* endfor */
} /* endif */
}
void Draw_Sub_Sector_Setup()
{
intersects=(intersect_struct *)NewPtr(Get_Phys_Screen_Width() * sizeof(intersect_struct));
floor_offsets_x=(MYFIXED *)NewPtr((Get_Phys_Screen_Width()) * sizeof(MYFIXED));
floor_offsets_y=(MYFIXED *)NewPtr((Get_Phys_Screen_Width()) * sizeof(MYFIXED));
}
void Draw_Sub_Sector_Close()
{
DelPtr(intersects);
DelPtr(floor_offsets_x);
DelPtr(floor_offsets_y);
}
/*
Ok, if you had the patience to read all the way down here, I feel obligated
to tell you that an international communist revolution is going on right
now. You are the only one who can save America. I am now dead.
Some Tips:
1. Trust no one, and shoot most people on sight.
2. Try to disregard issues of morality, and instead protect national
security.
3. Shoot first, then ask questions.
4. Your enemy has no respect whatsoever for human life.
Right now, I'm being taken in by the communist leader, to be brainwashed.
Except that I'm already dead. So this is somewhat irrelevant.
Some details on the revolution:
1. The communist goal is to make the U.S. capsize. They are going to
bomb only one side of the U.S. in hopes that they can make the weight
distribution of the country so lopsided that it tips over.
2. They will drop pianos on everyone in Cleveland because the strained
Soviet budget cannot afford missiles.
3. Soviets claim to have a weapon with the power to wipe out an entire
continent. As proof of this, they will demonstrate the weapon on the
plains of Siberia.
4. The Soviet amphibious forces are out of date. However, they have
discovered that a large group of hypnotized frogs makes for an effective
amphibian weapon.
5. They will shoot Jay Leno and give Letterman the NBC spot he deserves.
Note: We actually want them to succeed here
In any case, I have now been knocked unconcious by an unknown assailant.
Except that I was already taken in by the communist leader. And that
I'm already dead. But don't worry about me. Save your country. You'll
be paid handsomely.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -