home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / RAYCAST.ZIP / SPRREND.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-08  |  9.6 KB  |  367 lines

  1. #include "ray.h"
  2. #include "globals.h"
  3. #include "rayspr.h"
  4. #include "rayrend.h"
  5. #include "forever.h"
  6. #include "prevarr.h"
  7. #include "rayvb.h"
  8. #include "voxinter.h"
  9. #include "sprdimen.h"
  10.  
  11. void Draw_Sprite(pobject cur_sprite);
  12. inline  BOOL Bubble_Down(USHORT element_num);
  13. void Depth_Sort_Objects(pobject_node list, USHORT  num_elements); 
  14.  
  15. pobject_node sorting_list;
  16.  
  17. void Translate_Object_Vectors(pobject_node trans_list)
  18. {
  19.    pobject_node cur_obj_node=trans_list;
  20.    pobject cur_obj;
  21.    while ( !(OL_Empty_Node(cur_obj_node)) ) {
  22.       cur_obj=cur_obj_node->data;
  23.       rotate_angle=render_view_angle;
  24.       rotate_x=cur_obj->x - render_x;
  25.       rotate_y=cur_obj->y - render_y;
  26.       cur_obj->tx=FixedRotateY();
  27.       cur_obj->ty=FixedRotateX();
  28.       cur_obj_node=OL_Next_Node(cur_obj_node);
  29.    } /* endwhile */
  30. }
  31.  
  32. void Draw_SS_Sprites(pssector cur_ss)
  33. {
  34. USHORT obj_count;
  35. pobject_node cur_node;
  36.  
  37. Translate_Object_Vectors(cur_ss->objects);
  38.  
  39. obj_count=cur_ss->num_objects;
  40. Depth_Sort_Objects(cur_ss->objects, obj_count);
  41.  
  42. cur_node=cur_ss->objects;
  43.  
  44. while ( !(OL_Empty_Node(cur_node)) ) {
  45.    (*cur_node->data->type->Render_Func)(cur_node->data);
  46.    cur_node=OL_Next_Node(cur_node);
  47.    }
  48.    
  49. }
  50.  
  51. void Draw_Sprite(pobject cur_sprite)
  52. {
  53.  
  54. if ((cur_sprite->ty>>SHIFT)<=0)
  55.   return;
  56.  
  57. pobject_type spr_type;
  58. wall_run_info * cur_wall_run;
  59. short mid_proj;
  60. short abs_proj_left, abs_proj_right, cur_proj_left, cur_proj_right;
  61. MYFIXED height_top, height_bottom; 
  62. short sprite_start, sprite_end, spr_sc_height, spr_sc_width;
  63. Ptr sprite_texture, sprite_light;
  64. long temp_frame, temp_light;
  65. MYFIXED sprite_inc_y, sprite_inc_x, spr_start_col;
  66. pvb_node cur_bounds, next_bounds;
  67. short screen_x, cur_start, cur_end;
  68. MYFIXED sprite_clip;
  69. MYFIXED spr_col_base;
  70.  
  71. spr_type=cur_sprite->type;
  72. mid_proj=(fixedmd(-cur_sprite->tx, SCALE_FACTOR, cur_sprite->ty))+
  73.         WINDOW_MIDDLEW;
  74.  
  75. if (cur_sprite->cur_sec->flags & VOXEL_SECTOR) {
  76.    height_bottom=cur_sprite->z+Get_Voxel_Alt((PUCHAR)cur_sprite->cur_sec->extra_data,
  77.          cur_sprite->x, cur_sprite->y);
  78. } else {
  79.    height_bottom=cur_sprite->cur_sec->floor_height+cur_sprite->z;
  80. }/* endif */
  81.  
  82. height_top=height_bottom+(spr_type->height);
  83.  
  84. height_bottom=GetZScVal(height_bottom, cur_sprite->ty);
  85.  
  86. height_top=GetZScVal(height_top, cur_sprite->ty);
  87.  
  88. sprite_start=height_top>>SHIFT;
  89.  
  90. sprite_end=height_bottom>>SHIFT;
  91.  
  92. spr_sc_height=sprite_end-sprite_start;
  93.  
  94. if (spr_type->wshift > spr_type->hshift) {
  95.    spr_sc_width=spr_sc_height << (spr_type->wh_ratio);
  96. } else {
  97.    spr_sc_width=spr_sc_height >> (spr_type->wh_ratio);
  98. }
  99.  
  100. if ((spr_sc_width<=0)||(spr_sc_height<=0))
  101.    return;
  102.  
  103. abs_proj_left=mid_proj-(spr_sc_width >> 1);
  104. abs_proj_right=mid_proj+(spr_sc_width >> 1);
  105.  
  106. if (abs_proj_right<0)
  107.   return;
  108.  
  109. if (abs_proj_left>=WINDOW_WIDTH)
  110.    return;
  111.  
  112. // Get the light of sprite
  113.  
  114. temp_light=(SecLight(cur_sprite->cur_sec) -
  115.    (cur_sprite->ty>>(SHIFT+SecLTSpeed(cur_sprite->cur_sec))) );
  116. if (temp_light<0) {
  117.    temp_light=0;
  118. } /* endif */
  119. if (temp_light>MAX_LIGHT) {
  120.    temp_light=MAX_LIGHT;
  121. } /* endif */
  122.  
  123. sprite_light=pal_table[temp_light];
  124.  
  125.  
  126. // Get sprite texture
  127.  
  128. temp_frame=Get_Angle_Difference(cur_sprite->angle, render_view_angle);
  129. temp_frame=Get_Angle_Sum(temp_frame, ANGLE_180);
  130. temp_frame=Get_Angle_Sum(spr_type->half_angle, temp_frame);
  131. temp_frame=(temp_frame*spr_type->angle_num)/ANGLE_360;
  132. temp_frame&= (spr_type->angle_num -1);
  133.  
  134. sprite_texture=Get_Sprite_Texture(spr_type->frames[temp_frame], 
  135.         cur_sprite->cur_frame);
  136.  
  137. sprite_inc_x=((Get_Sprite_Texture_Width(spr_type->frames[temp_frame]) << SHIFT) / spr_sc_width);
  138.  
  139. sprite_inc_y=((Get_Sprite_Texture_Height(spr_type->frames[temp_frame]) << SLIVER_SHIFT) / spr_sc_height);
  140.  
  141. if (spr_type->rev_frames[temp_frame]) {
  142.    spr_start_col=((Get_Sprite_Texture_Width(spr_type->frames[temp_frame])) << SHIFT)-1;
  143.    sprite_inc_x=-sprite_inc_x;
  144. } else {
  145.    spr_start_col=0;
  146. }
  147.  
  148. short texture_and_height=Get_Sprite_Texture_Height(spr_type->frames[temp_frame])-1;
  149. Byte texture_width_shift=Get_Sprite_Texture_Shift(spr_type->frames[temp_frame]);
  150.  
  151. //loop for necessary bounds
  152. next_bounds=VB_GetFirstNode();
  153.  
  154. // loop w/ exit
  155.  
  156. FOREVER {
  157.  
  158.    if (next_bounds==NULL) {
  159.       break;
  160.    } /* endif */
  161.  
  162.    cur_bounds=next_bounds;
  163.    next_bounds=VB_GetNextNode(next_bounds);
  164.  
  165.    // is whole sprite right of bounds. If so, go to next bound
  166.  
  167.    if (abs_proj_left>=cur_bounds->right) {
  168.       continue;
  169.    } /* endif */
  170.  
  171.    // is whole sprite left of bounds. If so, we're done
  172.  
  173.    if (abs_proj_right<=cur_bounds->left) {
  174.       break;
  175.    } /* endif */
  176.  
  177.    //get horiz bounds of current run
  178.  
  179.    cur_proj_left=abs_proj_left;
  180.    if (cur_proj_left<cur_bounds->left) {
  181.        //get starting texture x pos for bounds
  182.       spr_col_base=spr_start_col+(cur_bounds->left-cur_proj_left)*sprite_inc_x;
  183.       cur_proj_left=cur_bounds->left;
  184.    } else {
  185.       //get starting texture x pos for bounds
  186.       spr_col_base=spr_start_col;
  187.    } /* endif */
  188.  
  189.    cur_proj_right=abs_proj_right;
  190.    if (cur_proj_right>cur_bounds->right) {
  191.       cur_proj_right=cur_bounds->right;
  192.    } /* endif */
  193.  
  194.    //loop for bounds length
  195.    for (screen_x=cur_proj_left; screen_x<cur_proj_right; screen_x++) {
  196.       //clip end y
  197.       if (sprite_end > win_bottoms[screen_x]) {
  198.          cur_end=win_bottoms[screen_x];
  199.          if (cur_end<=sprite_start) {
  200.             continue;
  201.          } /* endif */
  202.       } else {
  203.          cur_end=sprite_end;
  204.       } /* endif */
  205.  
  206.       //clip start y
  207.       if (sprite_start < win_tops[screen_x]) {
  208.          cur_start=win_tops[screen_x];
  209.          if (cur_end<=cur_start) {
  210.             continue;
  211.          } /* endif */
  212.          sprite_clip=sprite_inc_y * (cur_start-sprite_start);
  213.       } else {
  214.          cur_start=sprite_start;
  215.          sprite_clip=0;
  216.       } /* endif */
  217.  
  218.       if (wall_run_count>=MAX_WALL_RUNS) {
  219.          break;
  220.       }
  221.  
  222.       cur_wall_run=wall_runs+wall_run_count;
  223.       wall_run_count++;
  224.  
  225.       //set start y pos, scale and clip val in texture
  226.       cur_wall_run->width_shift=texture_width_shift;
  227.       cur_wall_run->bound_val=texture_and_height;
  228.       cur_wall_run->top=cur_start;
  229.       cur_wall_run->scale=cur_end-cur_start;
  230.       cur_wall_run->clip=sprite_clip;
  231.  
  232.       //set texture y increment,texture, screen x pos, and light
  233.       cur_wall_run->increment=sprite_inc_y;
  234.       cur_wall_run->texture=sprite_texture;
  235.       cur_wall_run->ray=screen_x;
  236.       cur_wall_run->light=sprite_light;
  237.  
  238.       //set x pos in texture
  239.       cur_wall_run->column=(spr_col_base>>SHIFT);
  240.       spr_col_base+=sprite_inc_x;
  241.  
  242.    } /* end loop for current bounds*/
  243.  
  244. } /* end loop for whole sprite */
  245.          
  246. }
  247.  
  248. void Draw_Flat_Sprite(pobject cur_sprite) {
  249.    short start_x, start_y, length_x, length_y;
  250.    pspr_dimensions cur_dimensions;
  251.    MYFIXED inc_x, inc_y;
  252.    MYFIXED sum_x;
  253.    Byte * sprite_texture;
  254.    short texture_height_and, texture_width_shift;
  255.    Byte * sprite_light;
  256.    wall_run_info * cur_wall_run;
  257.  
  258.    cur_dimensions=(pspr_dimensions)cur_sprite->type->render_data;
  259.  
  260.    start_x=fixedmult(cur_dimensions->start_x, WINDOW_WIDTH);
  261.    start_y=fixedmult(cur_dimensions->start_y, WINDOW_HEIGHT);
  262.    length_x=fixedmult(cur_dimensions->length_x, WINDOW_WIDTH);
  263.    length_y=fixedmult(cur_dimensions->length_y, WINDOW_HEIGHT);
  264.  
  265.    if ((length_x<=0)||(length_y<=0))
  266.       return;
  267.  
  268.    inc_x=(Get_Sprite_Texture_Width(cur_sprite->type->frames[0]) << SHIFT) / length_x;
  269.    inc_y=(Get_Sprite_Texture_Height(cur_sprite->type->frames[0]) << SLIVER_SHIFT) / length_y;
  270.  
  271.    sprite_light=pal_table[SecLight(cur_sprite->cur_sec)];
  272.    texture_height_and=Get_Sprite_Texture_Height(cur_sprite->type->frames[0])-1;
  273.    texture_width_shift=Get_Sprite_Texture_Shift(cur_sprite->type->frames[0]);
  274.    sprite_texture=Get_Sprite_Texture(cur_sprite->type->frames[0], 
  275.       cur_sprite->cur_frame);
  276.  
  277.    sum_x=0;
  278.    for (short cur_x=0; cur_x<length_x; cur_x++) {
  279.       cur_wall_run=wall_runs+wall_run_count;
  280.       wall_run_count++;
  281.  
  282.       cur_wall_run->width_shift=texture_width_shift;
  283.       cur_wall_run->bound_val=texture_height_and;
  284.       cur_wall_run->texture=sprite_texture;
  285.       cur_wall_run->clip=0;
  286.       cur_wall_run->increment=inc_y;
  287.       cur_wall_run->top=start_y;
  288.       cur_wall_run->scale=length_y;
  289.       cur_wall_run->light=sprite_light;
  290.       cur_wall_run->ray=cur_x+start_x;
  291.       cur_wall_run->column=sum_x>>SHIFT;
  292.  
  293.       sum_x+=inc_x;
  294.  
  295.    } /* endfor */
  296.  
  297. }
  298.  
  299. void Depth_Sort_Objects(pobject_node list, USHORT num_objects)
  300. {
  301.  
  302. sorting_list=list;
  303.  
  304. USHORT cur_find;
  305.  
  306. //loop in descending order finding correct nodes for each spot
  307.   
  308. for (cur_find=num_objects; cur_find>1; cur_find--) {
  309.  
  310.    //if no swaps are made finding the correct node
  311.    if (!Bubble_Down(cur_find)) {
  312.                               
  313.       //list is sorted so stop
  314.       break;
  315.       }
  316. }
  317. }
  318.  
  319. inline BOOL Bubble_Down(USHORT element_num)
  320. {
  321.  
  322. pobject_node cur_node, next_node;
  323. USHORT cur_element;
  324. BOOL swap_made;
  325.  
  326. //get first positive y object
  327.  
  328. cur_node=sorting_list;
  329. cur_element=1;
  330.  
  331. while ( (Sprite_Y(cur_node)<0) && (cur_element<element_num) ) {
  332.    cur_node=OL_Next_Node(cur_node);
  333.    cur_element++;
  334.    }
  335.  
  336. //go through remaining objects
  337.  
  338. swap_made=FALSE;   
  339.  
  340. while (cur_element<element_num) {
  341.  
  342.    //is current y greater than next node's y?
  343.  
  344.    next_node=OL_Next_Node(cur_node);
  345.  
  346.    if ( Sprite_Y(cur_node) > Sprite_Y(next_node) ) {
  347.    
  348.       //swap them
  349.       OL_Swap_SS_Nodes(cur_node, next_node);
  350.  
  351.       //note that a swap has been made
  352.       swap_made=TRUE;
  353.  
  354.  
  355.    }
  356.  
  357.    cur_node=OL_Next_Node(cur_node);
  358.    cur_element++;
  359.  
  360. }
  361.  
  362. //tell caller whether any swaps were made
  363. return swap_made;
  364. }
  365.  
  366.  
  367.