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

游戏

开发平台:

Visual C++

  1. #include "ray.h"
  2. #include "globals.h"
  3. #include "blockmap.h"
  4. #include "error.h"
  5. pdata N_PTR=NULL;
  6. typedef struct BLOCK_MAP {           
  7.   long x_base, y_base, x_range, y_range;
  8.   short x_count, y_count;
  9.   pline_list * blocks;
  10.   pobject_node ** objects;
  11.   } block_map;
  12. typedef struct LINE_LINK * pline_link;
  13. typedef struct LINE_LINK {
  14.   plinedef data;
  15.   pline_link next;
  16.   } line_link;
  17.   
  18. BOOL block_map_loaded=FALSE;
  19. block_map the_block_map;
  20. plinedef Ll_Get_Data(pline_link node) {
  21.   return node->data;
  22.   }
  23. pline_link Ll_Make_Link(plinedef line_pointed_to) {
  24.   pline_link new_link;
  25.   new_link=(pline_link)NewPtr(sizeof(line_link));
  26.   new_link->data=line_pointed_to;
  27.   new_link->next=NULL;
  28.   return new_link;
  29.   }
  30. void Ll_Push_Link(pline_link & base_link, pline_link push_link) {
  31.   if (push_link==NULL)
  32.     return;
  33.   push_link->next=base_link;
  34.   base_link=push_link;
  35.   }
  36. void Ll_Make_And_Push_Link(pline_link & base_link, plinedef line_pointed_to) {
  37.   pline_link the_link;
  38.   the_link=Ll_Make_Link(line_pointed_to);
  39.   Ll_Push_Link(base_link, the_link);
  40.   }
  41. pline_link Ll_Get_Next_Link(pline_link cur_link) {
  42.   if (cur_link==NULL)
  43.     return NULL;
  44.   return cur_link->next;
  45.   }
  46. BOOL Ll_Empty_Link(pline_link the_link) {
  47.   return ((the_link == NULL) ? TRUE : FALSE); 
  48. }
  49. void Ll_Make_Empty(pline_link & the_link) {
  50.   the_link=NULL;
  51. }
  52. void Ll_Clear_Links(pline_link & base_link)
  53. {
  54. pline_link cur_link, next_link;
  55. cur_link=base_link;
  56. while (!Ll_Empty_Link(cur_link)) {
  57.   next_link=Ll_Get_Next_Link(cur_link);
  58.   DelPtr(cur_link);
  59.   cur_link=next_link;
  60.   }
  61. Ll_Make_Empty(base_link);
  62. }
  63. void Ll_Push_In_Array(pline_link ** & the_array, short x_pos, short y_pos,
  64.    plinedef data) {
  65. if ((x_pos>=0) && (x_pos<the_block_map.x_count) &&
  66.     (y_pos>=0) && (y_pos<the_block_map.y_count)) {
  67.       Ll_Make_And_Push_Link((the_array[x_pos])[y_pos],
  68.         data);
  69.       }
  70. }
  71. line_list * Get_Block_Line_List(USHORT block_x, USHORT block_y) {
  72. if (!block_map_loaded)
  73.   return NULL;
  74.   
  75. // range check
  76. if ((block_x>=0) && (block_x<the_block_map.x_count) &&
  77.     (block_y>=0) && (block_y<the_block_map.y_count) ) {
  78.   line_list * base_list=the_block_map.blocks[block_x];
  79.   return base_list+block_y;
  80.   } else {
  81.   return NULL;
  82.   }
  83. }
  84. pobject_node * Get_Block_Obj_List(USHORT block_x, USHORT block_y) {
  85. if (!block_map_loaded)
  86.   return NULL;
  87.   
  88. // range check
  89. if ((block_x>=0) && (block_x<the_block_map.x_count) &&
  90.     (block_y>=0) && (block_y<the_block_map.y_count) ) {
  91.   pobject_node * base_list=the_block_map.objects[block_x];
  92.   return base_list+block_y;
  93.   } else {
  94.   return (pobject_node *)&N_PTR;
  95.   }
  96. }
  97. line_list * Get_Line_List(long x, long y) {
  98. if (!block_map_loaded)
  99.   return NULL;
  100. long block_x, block_y;
  101. block_x=x-the_block_map.x_base;
  102. block_y=y-the_block_map.y_base;
  103. block_x>>=BLOCK_MAP_X_SHIFT;
  104. block_y>>=BLOCK_MAP_Y_SHIFT;
  105. // range check
  106. if ((block_x>=0) && (block_x<the_block_map.x_count) &&
  107.     (block_y>=0) && (block_y<the_block_map.y_count) ) {
  108.   line_list * base_list=the_block_map.blocks[block_x];
  109.   return base_list+block_y;
  110.   } else {
  111.   return NULL;
  112.   }
  113. }
  114. void Generate_Block_Map() {
  115.    block_map_loaded = TRUE;
  116.    long min_x, min_y, max_x, max_y, range_x, range_y;
  117.    pvector2 cur_vec;
  118.    short counter;
  119.    // Get min and max points of world be looping through vectors
  120.    min_x=max_x=Vector_List[0].x;
  121.    min_y=max_y=Vector_List[0].y;
  122.    for (counter=1; counter < Number_Of_Vectors; counter++) {
  123.       cur_vec=Vector_List+counter;
  124.       if (cur_vec->x < min_x)
  125.          min_x=cur_vec->x;
  126.       if (cur_vec->y < min_y)
  127.          min_y=cur_vec->y;
  128.       if (cur_vec->x > max_x)
  129.          max_x=cur_vec->x;
  130.       if (cur_vec->y > max_y)
  131.          max_y=cur_vec->y;
  132.    }
  133.    // Get block range
  134.    range_x=max_x-min_x;
  135.    range_y=max_y-min_y;
  136.    // Save info on block table
  137.    the_block_map.x_base=min_x;
  138.    the_block_map.y_base=min_y;
  139.    the_block_map.x_range=range_x;
  140.    the_block_map.y_range=range_y;
  141.    the_block_map.x_count=(range_x+(BLOCK_MAP_X_SIZE-1)) >> BLOCK_MAP_X_SHIFT;
  142.    the_block_map.y_count=(range_y+(BLOCK_MAP_Y_SIZE-1)) >> BLOCK_MAP_Y_SHIFT;
  143.    pline_link ** block_temps;
  144.    pline_link * cur_block_line;
  145.    short cur_x, cur_y;
  146.    block_temps=(pline_link **)NewPtr(the_block_map.x_count * sizeof(pline_link *));
  147.    for (cur_x=0; cur_x<the_block_map.x_count; cur_x++) {
  148.       block_temps[cur_x]=(pline_link *)NewPtr(the_block_map.y_count *
  149.         sizeof(pline_link));
  150.       cur_block_line=block_temps[cur_x];
  151.       for (cur_y=0; cur_y<the_block_map.y_count; cur_y++) {
  152.         Ll_Make_Empty(cur_block_line[cur_y]);
  153.       }
  154.    }
  155.    plinedef cur_line;
  156.    long x1, y1, x2, y2, x_diff, y_diff, error_term, 
  157.         x_unit, y_unit, cur_abs_x, cur_abs_y;
  158.    short new_x, new_y;
  159.    for (USHORT l_index=0; l_index<Number_Of_Linedefs; l_index++) {
  160.       cur_line=Ld_List+l_index;
  161.       // Get block map positions of start and end
  162.       x1=(Vector_List[cur_line->v[0]].x-the_block_map.x_base);
  163.       y1=(Vector_List[cur_line->v[0]].y-the_block_map.y_base);
  164.       x2=(Vector_List[cur_line->v[1]].x-the_block_map.x_base);
  165.       y2=(Vector_List[cur_line->v[1]].y-the_block_map.y_base);
  166.       
  167.       // setup line for bresnham's algorithym      
  168.       
  169.       cur_abs_x=x1;
  170.       cur_abs_y=y1;
  171.       cur_x=cur_abs_x>>BLOCK_MAP_X_SHIFT;
  172.       cur_y=cur_abs_y>>BLOCK_MAP_Y_SHIFT;
  173.       Ll_Push_In_Array(block_temps, cur_x, cur_y, cur_line);
  174.       error_term=0;
  175.       
  176.       x_diff=x2-x1;
  177.       if (x_diff<0) {
  178.         x_diff=-x_diff;
  179.         x_unit=-1;
  180.       } else x_unit=1;
  181.       y_diff=y2-y1;
  182.       if (y_diff<0) {
  183.         y_diff=-y_diff;
  184.         y_unit=-1;
  185.       } else y_unit=1;
  186.       if (x_diff>y_diff) {
  187.         for (short position=0; position<=x_diff; position++) {
  188.           new_x=cur_abs_x>>BLOCK_MAP_X_SHIFT;
  189.           new_y=cur_abs_y>>BLOCK_MAP_Y_SHIFT;
  190.           if ((new_x!=cur_x)||(new_y!=cur_y)) {
  191.              cur_x=new_x;
  192.              cur_y=new_y;
  193.              Ll_Push_In_Array(block_temps, cur_x, cur_y, cur_line);
  194.              }
  195.           cur_abs_x+=x_unit;
  196.           error_term+=y_diff;
  197.           if (error_term>=x_diff) {
  198.             error_term-=x_diff;
  199.             cur_abs_y+=y_unit;
  200.             }  
  201.           }
  202.       } else {
  203.         for (short position=0; position<=y_diff; position++) {
  204.           new_x=cur_abs_x>>BLOCK_MAP_X_SHIFT;
  205.           new_y=cur_abs_y>>BLOCK_MAP_Y_SHIFT;
  206.           if ((new_x!=cur_x)||(new_y!=cur_y)) {
  207.              cur_x=new_x;
  208.              cur_y=new_y;
  209.              Ll_Push_In_Array(block_temps, cur_x, cur_y, cur_line);
  210.              }
  211.           cur_abs_y+=y_unit;
  212.           error_term+=x_diff;
  213.           if (error_term>=y_diff) {
  214.             error_term-=y_diff;
  215.             cur_abs_x+=x_unit;
  216.             } /* end if */
  217.           } /* end for */
  218.       } /* end if (x_diff>y_diff) */
  219.    } /* end loop through lines */
  220.       
  221. pline_list cur_list_column;
  222. pline_list cur_line_list;
  223. pline_link cur_link;
  224. short line_count;
  225. the_block_map.blocks=(pline_list *)NewPtr(the_block_map.x_count*sizeof(pline_list));
  226. for (cur_x=0; cur_x<the_block_map.x_count; cur_x++) {
  227.   the_block_map.blocks[cur_x]=(pline_list)NewPtr(the_block_map.y_count*sizeof(line_list));
  228.   cur_list_column=the_block_map.blocks[cur_x];
  229.   cur_block_line=block_temps[cur_x];
  230.   for (cur_y=0; cur_y<the_block_map.y_count; cur_y++) {
  231.     cur_link=cur_block_line[cur_y];
  232.     line_count=0;
  233.     while (!Ll_Empty_Link(cur_link)) {
  234.       cur_link=Ll_Get_Next_Link(cur_link);
  235.       line_count++;
  236.       }
  237.     cur_line_list=cur_list_column+cur_y;
  238.     cur_line_list->line_count=line_count;
  239.     if (line_count > 0) {
  240.       cur_line_list->lines=(plinedef *)NewPtr(line_count * sizeof(plinedef));
  241.       cur_link=cur_block_line[cur_y];
  242.       short cur_line=0;
  243.       while (!Ll_Empty_Link(cur_link)) {
  244.         cur_line_list->lines[cur_line]=Ll_Get_Data(cur_link);
  245.         cur_link=Ll_Get_Next_Link(cur_link);
  246.         cur_line++;
  247.         }
  248.     } else {
  249.       cur_line_list->lines=NULL;
  250.     }
  251.     cur_link=cur_block_line[cur_y];
  252.     Ll_Clear_Links(cur_link);
  253.   }
  254.   DelPtr(cur_block_line);
  255. }
  256. DelPtr(block_temps);
  257. pobject_node * cur_object_list;
  258. the_block_map.objects=(pobject_node **)NewPtr(the_block_map.x_count * sizeof(pobject_node *));
  259. for (cur_x=0; cur_x<the_block_map.x_count; cur_x++) {
  260.    the_block_map.objects[cur_x]=(pobject_node *)NewPtr(the_block_map.y_count * sizeof(pobject_node));
  261.    cur_object_list=the_block_map.objects[cur_x];
  262.    for (cur_y=0; cur_y<the_block_map.y_count; cur_y++) {
  263.       cur_object_list[cur_y]=NULL;
  264.    }
  265. }
  266. }
  267. void Clear_Block_Map() {
  268. if (!block_map_loaded)
  269.   return;
  270. short cur_x, cur_y;
  271. pline_list cur_list_column;
  272. for (cur_x=0; cur_x<the_block_map.x_count; cur_x++) {
  273.   cur_list_column=the_block_map.blocks[cur_x]; 
  274.   for (cur_y=0; cur_y<the_block_map.y_count; cur_y++) {
  275.     if (cur_list_column[cur_y].lines!=NULL)
  276.       DelPtr(cur_list_column[cur_y].lines);
  277.     }
  278.   if (the_block_map.objects[cur_x]!=NULL)
  279.     DelPtr(the_block_map.objects[cur_x]);
  280.   DelPtr(cur_list_column);
  281.   }
  282. DelPtr(the_block_map.objects);
  283. DelPtr(the_block_map.blocks);
  284. }
  285. short Block_X(long real_x) {
  286.    if (block_map_loaded)
  287.       return ((real_x-(the_block_map.x_base<<SHIFT))>>(SHIFT+BLOCK_MAP_X_SHIFT));
  288.    Error("Invalid call to Block_X");
  289.    return 0;
  290. }
  291. short Block_Y(long real_y) {
  292.    if (block_map_loaded)
  293.       return ((real_y-(the_block_map.y_base<<SHIFT))>>(SHIFT+BLOCK_MAP_Y_SHIFT));
  294.    Error("Invalid call to Block_Y");
  295.    return 0;
  296. }
  297. long Block_Left_Line(long base_x) {
  298.    if (block_map_loaded) 
  299.       return (((((base_x-(the_block_map.x_base<<SHIFT))>>SHIFT)&BLOCK_MAP_X_AND)
  300.          +the_block_map.x_base)<<SHIFT);
  301.    Error("Invalid call to Block_Left_Line");
  302.    return 0;
  303. }
  304. long Block_Right_Line(long base_x) {
  305.    if (block_map_loaded) 
  306.       return (((((base_x-(the_block_map.x_base<<SHIFT))>>SHIFT)&BLOCK_MAP_X_AND)+the_block_map.x_base+
  307.          BLOCK_MAP_X_SIZE)<<SHIFT);
  308.    Error("Invalid call to Block_Right_Line");
  309.    return 0;
  310. }
  311. long Block_Bottom_Line(long base_y) {
  312.    if (block_map_loaded) 
  313.       return (((((base_y-(the_block_map.y_base<<SHIFT))>>SHIFT)&BLOCK_MAP_Y_AND)+
  314.         the_block_map.y_base)<<SHIFT);
  315.    Error("Invalid call to Block_Bottom_Line");
  316.    return 0;
  317. }
  318. long Block_Top_Line(long base_y) {
  319.    if (block_map_loaded) 
  320.       return (((((base_y-(the_block_map.y_base<<SHIFT))>>SHIFT)&BLOCK_MAP_Y_AND)+the_block_map.y_base+
  321.          BLOCK_MAP_Y_SIZE)<<SHIFT);
  322.    Error("Invalid call to Block_Top_Line");
  323.    return 0;
  324. }
  325. BOOL In_Block_X(long real_x, short block_x) {
  326.    if (block_map_loaded)
  327.       return ( (Block_X(real_x)==block_x) ? TRUE : FALSE);
  328.    Error("Invalid call to In_Block_X");
  329.    return FALSE;
  330. }
  331. BOOL In_Block_Y(long real_y, short block_y) {
  332.    if (block_map_loaded)
  333.       return ( (Block_Y(real_y)==block_y) ? TRUE : FALSE);
  334.    Error("Invalid call to In_Block_Y");
  335.    return FALSE;
  336. }