1  /********************************************************************** <BR>


2  This file is part of Crack dot Com's free source code release of


3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for


4  information about compiling & licensing issues visit this URL</a>


5  <PRE> If that doesn't help, contact Jonathan Clark at


6  golgotha_source@usa.net (Subject should have "GOLG" in it)


7  ***********************************************************************/


8 


9  #ifndef G1_MAP_VERTEX_HH


10  #define G1_MAP_VERTEX_HH


11 


12 


13  #include "arch.hh"


14  #include "f_tables.hh"


15  #include "math/vector.hh"


16  #include "math/transform.hh"


17  #include "r1_clip.hh"


18  #include "r1_api.hh"


19  #include "map_man.hh"


20 


21  class i4_file_class;


22  class i4_saver_class;


23 


24  extern i4_float g1_vert_height_table[256];


25 


26  class g1_map_vertex_class


27  {


28  public:


29  i4_3d_vector v; // view space transformed coordinates


30  i4_float px, py; // projected screen x & y


31  i4_float w; // 1/z


32 


33 


34  // 888 lighting values for r,g,b, dynamic light cannot be recalculated


35  // dynamic light is assummed to come from straight down, this value is changed by light objects


36  // but is normally 0


37  w32 dynamic_light;


38 


39 


40  // sum of dynamic, static, and global light values packed into 888, top bit indicates


41  // need to recalculate. Set needtorecalc if dynamic light or normal changes


42  w32 light_sum;


43 


44  w16 normal; // 555, x,y,z, top bit indicates needs recalc


45 


46 


47  w16 flags;


48 


49  // amount of light (0..255) visible from the directional light (in the direction of the


50  // of the global directional light)  cannot be calculated in game because it requires


51  // raytracing and radiocity (not implemented yet)


52  w8 static_intensity;


53 


54  // 0256 shadow subtraction for clouds


55  w8 shadow_subtract;


56 


57  w8 height; // height above ground increments of .05


58  w8 clip_code;


59 


60  i4_float t_height; // height with tintersection adjustment


61 


62  enum {


63  SELECTED = (1<<0), // only used by editor


64  FOGGED = (1<<1), // fog of war


65 


66  TRANSFORMED = (1<<2),


67  PROJECTED = (1<<3),


68  CLIP_CODE_CALCULATED= (1<<4),


69  W_CALCULATED = (1<<5),


70 


71  NEED_UNDO_SAVE = (1<<6), // only used by editor


72  WAS_DRAWN_LAST_FRAME= (1<<7), // only used by editor


73  APPLY_WAVE_FUNCTION = (1<<8), // if vert is part of water


74 


75  T_INTERSECTION = (1<<9), // used to determine that this is a T intersection


76  };


77 


78  enum {SAVED_FLAGS = SELECTED  FOGGED};


79 


80 


81  w16 get_flag(w16 f) { return (flags & f); }


82  void set_flag(w16 f, int on_off)


83  {


84  if (on_off) flags=f;


85  else flags&=~f;


86  }


87 


88  w8 is_transformed() { return get_flag(TRANSFORMED); }


89  void set_is_transformed(w8 yes_no) { set_flag(TRANSFORMED, yes_no); }


90 


91  w8 is_projected() { return get_flag(PROJECTED); }


92  void set_is_projected(w8 yes_no) { set_flag(PROJECTED, yes_no); }


93 


94  w8 is_selected() { return get_flag(SELECTED); }


95  void set_is_selected(w8 yes_no) { set_flag(SELECTED, yes_no); }


96 


97  w8 need_undo() { return get_flag(NEED_UNDO_SAVE); }


98  void set_need_undo(w8 yes_no) { set_flag(NEED_UNDO_SAVE, yes_no); }


99 


100  w8 is_clipped() { return get_flag(CLIP_CODE_CALCULATED); }


101  void set_is_clipped(w8 yes_no) { set_flag(CLIP_CODE_CALCULATED, yes_no); }


102 


103  w8 is_w_calculated() { return get_flag(W_CALCULATED); }


104  void set_is_w_calculated(w8 yes_no) { set_flag(W_CALCULATED, yes_no); }


105 


106  void clear_calculations()


107  {


108  flags &= ~(PROJECTED  TRANSFORMED  CLIP_CODE_CALCULATED  W_CALCULATED  T_INTERSECTION);


109  }


110 


111 


112  float get_non_dynamic_ligth_intensity(int cvx, int cvy);


113  void recalc_normal(int cvx, int cvy);


114  void recalc_light_sum(int cvx, int cvy);


115 


116  void get_normal(i4_3d_vector &v, int cvx, int cvy)


117  {


118  if (normal & 0x8000)


119  recalc_normal(cvx, cvy);


120 


121  v.x=g1_table_0_31_to_n1_1[(normal>>10)&31];


122  v.y=g1_table_0_31_to_n1_1[(normal>>5)&31];


123  v.z=g1_table_0_31_to_n1_1[(normal)&31];


124  }


125 


126 


127  void get_rgb(i4_float &r, i4_float &g, i4_float &b, int cvx, int cvy)


128  {


129  if (light_sum & 0x80000000)


130  recalc_light_sum(cvx, cvy);


131  w32 ls=light_sum;


132  r=g1_table_0_255_to_0_1[((ls>>16)&0xff)];


133  g=g1_table_0_255_to_0_1[((ls>>8)&0xff)];


134  b=g1_table_0_255_to_0_1[((ls)&0xff)];


135  }


136 


137  float get_r(int cvx, int cvy)


138  {


139  if (light_sum & 0x80000000)


140  recalc_light_sum(cvx, cvy);


141 


142  return g1_table_0_255_to_0_1[((light_sum>>16)&0xff)];


143  }


144 


145  i4_float get_height() { return g1_vert_height_table[height]; }


146 


147  void wave_transform(i4_transform_class &t, float map_x, float map_y);


148 


149  void transform(i4_transform_class &t, int map_x, int map_y,float &xscale, float &yscale)


150  {


151  if (!is_transformed())


152  {


153  if (flags & APPLY_WAVE_FUNCTION)


154  wave_transform(t, map_x, map_y);


155  else


156  t.transform(i4_3d_point_class(map_x, map_y, t_height), v);


157 


158  v.x *= xscale;


159  v.y *= yscale;


160 


161  set_is_transformed(i4_T);


162  }


163  }


164 


165  void calculate_w()


166  {


167  w=r1_ooz(v.z);


168  set_is_w_calculated(i4_T);


169  }


170 


171  void project(i4_float win_center_x, i4_float win_center_y)


172  {


173  if (!is_projected())


174  {


175  if (!is_w_calculated())


176  calculate_w();


177 


178  px=v.x * w * win_center_x + win_center_x;


179  py=v.y * w * win_center_y + win_center_y;


180  set_is_projected(i4_T);


181  }


182  }


183 


184  w8 calc_clip_code()


185  {


186  if (!is_clipped())


187  {


188  clip_code = r1_calc_outcode(v);


189 


190  set_is_clipped(1);


191  }


192  return clip_code;


193  }


194 


195  void set_r1_vert(r1_vert *r)


196  {


197  r>v.x = v.x;


198  r>v.y = v.y;


199  r>v.z = v.z;


200  r>px = px;


201  r>py = py;


202  r>w = w;


203  r>outcode = clip_code;


204  }


205 


206  void load_v1(i4_file_class *fp);


207  void load_v2(i4_file_class *fp);


208  void load_v4(i4_file_class *fp);


209 


210  void init();


211 


212  };


213 


214 


215  inline g1_map_vertex_class *g1_vertex_min(g1_map_vertex_class *v1,g1_map_vertex_class *v2)


216  {


217  if (v1>height<v2>height)


218  return v1;


219  else return v2;


220  }


221 


222  i4_bool g1_load_map_verts(g1_map_vertex_class *list, int lsize,


223  i4_loader_class *fp, int goto_sections);


224 


225  void g1_save_map_verts(g1_map_vertex_class *list, int lsize,


226  i4_saver_class *fp, int mark_section);


227 


228  inline g1_map_vertex_class *g1_get_vertex(int x, int y)


229  {


230  return g1_verts + y*(g1_map_width+1) + x;


231  }


232 


233  #endif


234 


235 


236 


237 

