VOXREND.CPP
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:12k
源码类别:

游戏

开发平台:

Visual C++

  1. #include <mem.h>
  2. #include "ray.h"
  3. #include "globals.h"
  4. #include "voxel.h"
  5. #include "rayrend.h"
  6. #include "asm.h"
  7. #include "screen.h"
  8. #include "mymem.h"
  9. #include "shading.h"
  10. #include "sprvox.h"
  11. #include "scrconf.h"
  12. #include "voxsky.h"
  13. #include "rcvars.h"
  14. #include "sortseg.h"
  15. #include "fixed.h"
  16. #include "prevarr.h"
  17. #include "skipping.h"
  18. #define XT_TO_VOX_SHIFT 4
  19. #define NORM_TO_VOX 2
  20. #define SMOOTH_DELIMATOR_X 0x00004000
  21. #define SMOOTH_DELIMATOR_Y 0x00400000
  22. #define BLUE_COLOR 0x3f
  23. #define DIST_MIN_FIXED (DIST_SCALER*DIST_MIN<<SHIFT)
  24. #define DIST_MAX_FIXED (DIST_SCALER*DIST_MAX<<SHIFT)
  25. #define DIST_INC (DIST_SCALER<<SHIFT)
  26. #define MAX_SS_VECTORS 100
  27. #define DOUBLE_DIS 30
  28. #define QUAD_DIS 60
  29. typedef struct VOX_RUN * pvox_run;
  30. typedef struct VOX_RUN{
  31.    short left, right;
  32.    } vox_run;
  33. shade_mode do_shading;
  34. skipping_mode do_skipping;
  35. void Set_Shading(shade_mode new_mode)
  36. {
  37. do_shading=new_mode;
  38. }
  39. void Set_Skipping(skipping_mode new_mode)
  40. {
  41. do_skipping=new_mode;
  42. }
  43. void Transform_Points(pvector2 start_list, pvector2 dest_list, short vector_count);
  44. short Clip_Points_Max(pvector2 start_list, pvector2 dest_list, short vector_count);
  45. short Clip_Points_Min(pvector2 start_list, pvector2 dest_list, short vector_count);
  46. void Make_Vox_Runs(
  47.    pvector2 point_list,
  48.    short point_count,
  49.    pvox_run dest_runs,
  50.    short & start_line,
  51.    short & end_line);
  52. void Render_Vox_Runs(
  53.    pssector vox_ssector,
  54.    pvox_run screen_runs,
  55.    short start_line,
  56.    short end_line);
  57. void Render_Voxel_Sub_Sector(pssector vox_ssector)
  58. {
  59.    vector2 trans_list[MAX_SS_VECTORS];
  60.    vector2 clipped_points[MAX_SS_VECTORS];
  61.    vector2 clipped_intermediates[MAX_SS_VECTORS];
  62.    vox_run screen_runs[DIST_MAX];
  63.    short start_line, end_line;
  64.    psorted_vector_type start_list;
  65.    short clipped_point_count;
  66.    start_list=(psorted_vector_type)vox_ssector->extra_data;
  67.    // transform points relative to viewer
  68.    Transform_Points(start_list->vectors, trans_list, start_list->vector_count);
  69.    // perform clipping, first against maximum distance, and then against minimum distance
  70.    clipped_point_count=Clip_Points_Max(trans_list, clipped_intermediates, 
  71.       start_list->vector_count);
  72.    // has polygon been clipped out of existence?
  73.    if (clipped_point_count==0)
  74.       return;
  75.    clipped_point_count=Clip_Points_Min(clipped_intermediates, clipped_points,
  76.       clipped_point_count);
  77.    // has polygon been clipped out of existence?
  78.    if (clipped_point_count==0)
  79.       return;
  80.    Make_Vox_Runs(
  81.       clipped_points,
  82.       clipped_point_count,
  83.       screen_runs,
  84.       start_line,
  85.       end_line);
  86.    Render_Vox_Runs( 
  87.       vox_ssector,
  88.       screen_runs,
  89.       start_line,
  90.       end_line);
  91. }
  92. void Transform_Points(pvector2 start_list, pvector2 dest_list, short vector_count) {
  93.    short vec_index;
  94.    // get a translated list
  95.    for (vec_index=0; vec_index<vector_count; vec_index++) {
  96.       rotate_x=((start_list[vec_index].x<<SHIFT)-render_x);
  97.       rotate_y=((start_list[vec_index].y<<SHIFT)-render_y);
  98.       rotate_angle=render_view_angle;
  99.       dest_list[vec_index].x=FixedRotateY();
  100.       dest_list[vec_index].y=FixedRotateX();
  101.       }
  102. }
  103. short Clip_Points_Max(pvector2 start_list, pvector2 dest_list, short vector_count) {
  104.    pvector2 cur_vec, next_vec;
  105.    short vec_index;
  106.    short clip_counter;
  107.    clip_counter=0;
  108.    cur_vec=start_list+(vector_count-1);
  109.    for (vec_index=0; vec_index<vector_count; vec_index++) {
  110.       next_vec=start_list+vec_index;
  111.       // categorize edges by types
  112.       if ((cur_vec->y <= DIST_MAX_FIXED) && (next_vec->y <= DIST_MAX_FIXED)) {
  113.          // edge not at all behind view volume
  114.          dest_list[clip_counter].x=next_vec->x;
  115.          dest_list[clip_counter++].y=next_vec->y;
  116.       } /* endif */
  117.       if ((cur_vec->y > DIST_MAX_FIXED) && (next_vec->y > DIST_MAX_FIXED)) {
  118.          // all behind volume, so go on
  119.          }
  120.       if ((cur_vec->y <= DIST_MAX_FIXED) && (next_vec->y > DIST_MAX_FIXED)) {
  121.          // edge is leaving view volume
  122.          MYFIXED slope=fixeddiv(next_vec->x-cur_vec->x, next_vec->y-cur_vec->y);
  123.          dest_list[clip_counter].y=DIST_MAX_FIXED;
  124.          dest_list[clip_counter++].x=cur_vec->x +
  125.             fixedmult(slope, DIST_MAX_FIXED-cur_vec->y);
  126.          }
  127.       if ((cur_vec->y > DIST_MAX_FIXED) && (next_vec->y <=DIST_MAX_FIXED)) {
  128.          // edge is entering view volume
  129.          MYFIXED slope=fixeddiv(next_vec->x-cur_vec->x, next_vec->y-cur_vec->y);
  130.          dest_list[clip_counter].y=DIST_MAX_FIXED;
  131.          dest_list[clip_counter++].x=cur_vec->x + 
  132.             fixedmult(slope, DIST_MAX_FIXED-cur_vec->y);
  133.          dest_list[clip_counter].x=next_vec->x;
  134.          dest_list[clip_counter++].y=next_vec->y;
  135.          }
  136.       cur_vec=next_vec;
  137.       }
  138. return clip_counter;
  139. }
  140. short Clip_Points_Min(pvector2 start_list, pvector2 dest_list, short vector_count) {
  141.    pvector2 cur_vec, next_vec;
  142.    short vec_index;
  143.    short clip_counter;
  144.    clip_counter=0;
  145.    cur_vec=start_list+(vector_count-1);
  146.    for (vec_index=0; vec_index<vector_count; vec_index++) {
  147.       next_vec=start_list+vec_index;
  148.       // categorize edges by types
  149.       if ((cur_vec->y >= DIST_MIN_FIXED) && (next_vec->y >= DIST_MIN_FIXED)) {
  150.          // edge not at all inf front of view volume
  151.          dest_list[clip_counter].x=next_vec->x;
  152.          dest_list[clip_counter++].y=next_vec->y;
  153.       } /* endif */
  154.       if ((cur_vec->y < DIST_MIN_FIXED) && (next_vec->y < DIST_MIN_FIXED)) {
  155.          // all in front of volume, so go on
  156.          }
  157.       if ((cur_vec->y >= DIST_MIN_FIXED) && (next_vec->y < DIST_MIN_FIXED)) {
  158.          // edge is leaving view volume
  159.          MYFIXED slope=fixeddiv(next_vec->x-cur_vec->x, next_vec->y-cur_vec->y);
  160.          dest_list[clip_counter].y=DIST_MIN_FIXED;
  161.          dest_list[clip_counter++].x=cur_vec->x +
  162.             fixedmult(slope, DIST_MIN_FIXED-cur_vec->y);
  163.          }
  164.       if ((cur_vec->y < DIST_MIN_FIXED) && (next_vec->y >=DIST_MIN_FIXED)) {
  165.          // edge is entering view volume
  166.          MYFIXED slope=fixeddiv(next_vec->x-cur_vec->x, next_vec->y-cur_vec->y);
  167.          dest_list[clip_counter].y=DIST_MIN_FIXED;
  168.          dest_list[clip_counter++].x=cur_vec->x + 
  169.             fixedmult(slope, DIST_MIN_FIXED-cur_vec->y);
  170.          dest_list[clip_counter].x=next_vec->x;
  171.          dest_list[clip_counter++].y=next_vec->y;
  172.          }
  173.       cur_vec=next_vec;
  174.       }
  175. return clip_counter;
  176. }
  177. void Make_Vox_Runs(
  178.    pvector2 point_list,
  179.    short point_count,
  180.    pvox_run dest_runs,
  181.    short & start_line,
  182.    short & end_line) {
  183.    short vec_index;
  184.    short cur_dist;
  185.    MYFIXED max_dist, min_dist;
  186.    MYFIXED left_x, right_x;
  187.    MYFIXED left_slope, right_slope;
  188.    MYFIXED fixed_dist;
  189.    short max_dist_index, left_vec, right_vec, last_vec;
  190.  
  191.    max_dist=0; 
  192.    min_dist=MAXMYFIXED;
  193.    max_dist_index=0;
  194.    for (vec_index=0; vec_index<point_count; vec_index++) {
  195.       if (point_list[vec_index].y<min_dist) {
  196.          min_dist=point_list[vec_index].y;
  197.       }
  198.       if (point_list[vec_index].y>max_dist) {
  199.          max_dist=point_list[vec_index].y;
  200.          max_dist_index=vec_index;
  201.       }
  202.    }
  203.    start_line=(min_dist+(DIST_INC-1))/DIST_INC;
  204.    end_line=(max_dist+(DIST_INC-1))/DIST_INC;
  205.    left_vec=max_dist_index;
  206.    right_vec=max_dist_index;
  207.    for (cur_dist=end_line-1; cur_dist>=start_line; cur_dist--) {
  208.       fixed_dist=cur_dist*DIST_INC;
  209.       // get on the correct left edge
  210.       if (point_list[left_vec].y>fixed_dist) {
  211.          while (point_list[left_vec].y>fixed_dist) {
  212.             last_vec=left_vec;
  213.             left_vec=(left_vec-1+point_count)%point_count;
  214.             }
  215.          left_slope=fixeddiv(point_list[left_vec].x-point_list[last_vec].x,
  216.                            point_list[left_vec].y-point_list[last_vec].y);
  217.          left_x=point_list[last_vec].x-fixedmult(left_slope, point_list[last_vec].y-fixed_dist);
  218.       }
  219.       // get on the correct right edge
  220.       if (point_list[right_vec].y>fixed_dist) {
  221.          while (point_list[right_vec].y>fixed_dist) {
  222.             last_vec=right_vec;
  223.             right_vec=(right_vec+1)%point_count;
  224.             }
  225.          right_slope=fixeddiv(point_list[right_vec].x-point_list[last_vec].x,
  226.                            point_list[right_vec].y-point_list[last_vec].y);
  227.          right_x=point_list[last_vec].x-fixedmult(right_slope, point_list[last_vec].y-fixed_dist);
  228.       }
  229.       // project values and put them in runs
  230.       dest_runs[cur_dist].left=Project(left_x, fixed_dist);
  231.       if (dest_runs[cur_dist].left<0) {
  232.          dest_runs[cur_dist].left=0;
  233.       }
  234.       dest_runs[cur_dist].right=Project(right_x, fixed_dist);
  235.       if (dest_runs[cur_dist].right>WINDOW_WIDTH) {
  236.          dest_runs[cur_dist].right=WINDOW_WIDTH;
  237.       }
  238.       // update x values
  239.       left_x-=fixedmult(left_slope, DIST_INC);
  240.       right_x-=fixedmult(right_slope, DIST_INC);
  241.    }
  242. }
  243. void Render_Vox_Runs(
  244.    pssector vox_ssector,
  245.    pvox_run screen_runs,
  246.    short start_line,
  247.    short end_line) {
  248.    MYFIXED inc_scaler_x, inc_scaler_y;
  249.    MYFIXED fixed_x, fixed_y;
  250.    short left, right;
  251.    psector vox_sector;
  252.    short temp_light;
  253.    vox_sector=GetSecFromSSec(vox_ssector);
  254.    alt_array=(PUCHAR)vox_sector->extra_data;
  255.    Setup_Vox_Sprite_Rend(vox_ssector->objects, start_line, end_line);
  256.    // make sure previous run causes no drawing
  257.    // setup constants for getting positions in map
  258.    fixed_x=(render_x/VOXEL_SPEED_SCALE)<<(VOX_FP_SHIFT-SHIFT);
  259.    fixed_y=(render_y/VOXEL_SPEED_SCALE)<<(VOX_FP_SHIFT-SHIFT);
  260.  
  261.    inc_scaler_x=(-floor_trans_x)>>XT_TO_VOX_SHIFT;
  262.    inc_scaler_y=(-floor_trans_y)>>XT_TO_VOX_SHIFT;
  263.    // file in any sprites before first line
  264.    for (long cur_dis=0; cur_dis<start_line; cur_dis++)
  265.       Do_Vox_Sprite_Line(0);
  266.    short dist_inc;
  267.    if (do_skipping) {
  268.    if (start_line>DOUBLE_DIS) {
  269.       if (start_line>QUAD_DIS) {
  270.          dist_inc=4;
  271.       } else {
  272.          dist_inc=2;
  273.       }
  274.    } else {
  275.       dist_inc=1;
  276.    }
  277.    } else dist_inc=1;
  278.    // loop through a constant number of distances, draw a voxel row at each distance
  279.    for (cur_dis=start_line; cur_dis<end_line; cur_dis+=dist_inc) {
  280.       
  281.       // Do them's sprites
  282.       for (short cur_line=cur_dis-dist_inc+1; cur_line<=cur_dis; cur_line++)
  283.         Do_Vox_Sprite_Line(cur_line*DIST_SCALER);
  284.       // setup light table
  285.       temp_light=(SecLight(vox_sector)-
  286.          ((cur_dis*DIST_SCALER) >> (SecLTSpeed(vox_sector))) );
  287.       if (temp_light<0) temp_light=0;
  288.       if (temp_light>MAX_LIGHT) temp_light=MAX_LIGHT;
  289.       v_light_table=pal_table[temp_light];
  290.       // Setup correct scaling table
  291.       cur_scaler=alt_scaler[cur_dis];
  292.       // Setup top value for drawing
  293.       starting_y=(SHORT)(GetZScVal(ALT_MAX*HEIGHT_SCALER, (cur_dis*DIST_SCALER)<<SHIFT)
  294.          >> SHIFT);
  295.       // get horizontal positions from run list
  296.       left=screen_runs[cur_dis].left;
  297.       right=screen_runs[cur_dis].right;
  298.       // Get map positions at start of ray
  299.       x_loc=(((rcos_table[render_view_angle]+floor_offsets_x[right-1]) * cur_dis)<<NORM_TO_VOX)+
  300.          (fixed_x);
  301.       y_loc=(((rsin_table[render_view_angle]+floor_offsets_y[right-1]) * cur_dis)<<NORM_TO_VOX)+
  302.          (fixed_y);
  303.       // Get increment in map
  304.       x_inc=(cur_dis * inc_scaler_x);
  305.       y_inc=(cur_dis * inc_scaler_y);
  306.       // set horizontal render constants
  307.       v_horiz_length=right-left;
  308.       if (v_horiz_length<=0)
  309.          continue;
  310.       vox_buff=buff+left;
  311.       prev_vox_colors=prev_colors+left;
  312.       prev_vox_heights=win_bottoms+left;
  313.       // adjust y to scale correctly through altitude bitmap
  314.       y_loc<<=8;
  315.       y_inc<<=8;
  316.       if (do_shading) {
  317.         //if ((ABS(x_inc)<SMOOTH_DELIMATOR_X)&&(ABS(y_inc)<SMOOTH_DELIMATOR_Y))
  318.            Draw_Vox_Row_Smooth();
  319.         //else Draw_Vox_Row();
  320.       } else {
  321.         Draw_Vox_Row_Fast();
  322.       } /* endif */
  323.       if (do_skipping) {
  324.       if (cur_dis==DOUBLE_DIS) {
  325.         dist_inc=2;
  326.       }
  327.       if (cur_dis==QUAD_DIS) {
  328.         dist_inc=4;
  329.       }
  330.       }
  331.    } /* endfor */
  332. }