source: golgotha/src/golg/tile.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 6.4 KB
Line 
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#include "file/file.hh"
10#include "load3d.hh"
11#include "tile.hh"
12#include "error/alert.hh"
13#include "obj3d.hh"
14#include "map.hh"
15#include "resources.hh"
16#include "string/str_checksum.hh"
17#include "r1_api.hh"
18#include "checksum/checksum.hh"
19#include "saver.hh"
20#include "file/file.hh"
21#include "lisp/lisp.hh"
22#include "g1_render.hh"
23#include "tmanage.hh"
24#include "string/str_checksum.hh"
25#include "map_cell.hh"
26
27g1_tile_man_class g1_tile_man;
28
29
30static i4_array<w16> select_remap(0,128);
31
32
33void g1_tile_class::set_friction(float uB)
34{
35  friction_fraction = uB;
36  damping_fraction = 1.0/uB;
37  damping_e = exp(-uB *0.1);
38}
39
40
41int g1_tile_man_class::get_remap(int tile_num)
42{
43  return select_remap[tile_num];
44}
45
46g1_tile_man_class::g1_tile_man_class()
47{
48  t_tiles=0;
49  max_tiles=0;
50  array=0;
51  sorted_by_checksum=0;
52}
53
54
55
56int g1_tile_man_class::remap_size()
57{
58  return select_remap.size();
59}
60
61void g1_tile_man_class::reset(int _max_tiles)
62{
63  if (array)
64    i4_free(array);
65   
66  max_tiles=_max_tiles+1;
67  t_tiles=0;
68  if (max_tiles)
69    array=(g1_tile_class *)i4_malloc(sizeof(g1_tile_class) * max_tiles,"");
70  else
71    array=0;
72
73  array[0].init();
74  array[0].texture=0;
75  array[0].filename_checksum=0;
76  sorted_by_checksum=0;
77}
78
79void g1_tile_class::apply_to_cell(g1_map_cell_class &cell)
80{
81  if (flags & BLOCKING)
82    cell.flags&=~g1_map_cell_class::IS_GROUND;
83  else
84    cell.flags|=g1_map_cell_class::IS_GROUND;
85}
86
87void g1_tile_class::init()
88{
89  flags=SELECTABLE;
90  set_friction(g1_resources.damping_friction);
91}
92
93
94static i4_bool test_closest(const i4_3d_point_class &p1,
95                         const i4_3d_point_class &p2,
96                         i4_float &dist)             
97{
98  i4_float d=((p1.x - p2.x) * (p1.x - p2.x)) +
99    ((p1.y - p2.y) * (p1.y - p2.y));
100 
101
102  if (fabs(d-dist)<0.005)
103  {
104    if (p1.z>p2.z)
105    {
106      dist=d;
107      return i4_T;
108    }
109  } else if (d<dist)
110  {
111    dist=d;
112    return i4_T;
113  }
114  return i4_F;
115}
116
117
118int g1_tile_man_class::get_tile_from_name(char *name)
119{
120  sw32 len = strlen(name);
121  return get_tile_from_checksum(i4_check_sum32(name,len));
122}
123
124int g1_tile_man_class::get_tile_from_name(i4_const_str &name)
125{
126  return get_tile_from_checksum(i4_str_checksum(name));
127}
128
129
130int g1_tile_compare(const void *a, const void *b)
131{
132  if (((g1_tile_class *)a)->filename_checksum<((g1_tile_class *)b)->filename_checksum)
133    return -1;
134  else if (((g1_tile_class *)a)->filename_checksum>((g1_tile_class *)b)->filename_checksum)
135    return 1;
136  else return 0;
137}
138
139void g1_tile_man_class::finished_load()
140{
141 if (!sorted_by_checksum)
142  {
143    int i,order_on=0;
144
145    for (i=0; i<t_tiles; i++)
146    {
147      if (array[i].flags & g1_tile_class::SELECTABLE)
148        array[i].selection_order=order_on++;     
149      else
150        array[i].selection_order=0;
151    }
152
153    qsort(array, t_tiles, sizeof(g1_tile_class), g1_tile_compare);
154    sorted_by_checksum=1;
155
156    select_remap.clear();
157    for (i=0; i<order_on; i++)
158      select_remap.add();
159
160    for (i=0; i<t_tiles;i++)
161      if (array[i].flags & g1_tile_class::SELECTABLE)
162        select_remap[array[i].selection_order]=i;
163
164    pink=array[get_tile_from_name("pink")].texture;
165    default_tile_type=get_tile_from_name("tron_grid");
166  }
167}
168
169int g1_tile_man_class::get_tile_from_checksum(w32 checksum)
170{
171  if (!t_tiles)
172    return 0;
173
174 
175  sw32 lo=0,hi=t_tiles-1,mid;
176
177  mid=(lo+hi+1)/2;
178  while (1)
179  {
180    if (checksum==array[mid].filename_checksum)
181      return mid;
182    else if (checksum<array[mid].filename_checksum)
183      hi=mid-1;
184    else
185      lo=mid+1;
186   
187    w32 last_mid=mid;
188    mid=(hi+lo)/2;
189
190    if (last_mid==mid)
191      return 0;
192  }
193
194  return 0;
195}
196
197
198void g1_tile_man_class::add(li_object *o, li_environment *env)
199{
200  if (t_tiles==max_tiles)
201    i4_error("too many tiles");
202
203  li_object *prop=0;
204
205  li_string *tname=0; 
206  if (o->type()==LI_STRING)
207    tname=li_string::get(o,env);
208  else
209  {
210    prop=li_cdr(o,env);
211    tname=li_string::get(li_car(o,env),env);
212  }
213
214
215  r1_texture_manager_class *tman=g1_render.r_api->get_tmanager();
216
217
218  i4_const_str i4_tname=i4_const_str(tname->value());
219  array[t_tiles].texture=tman->register_texture(i4_tname, i4_tname);
220  array[t_tiles].filename_checksum=i4_str_checksum(i4_tname);
221
222
223  array[t_tiles++].get_properties(prop, env);
224  sorted_by_checksum=0;
225}
226
227
228static li_symbol *g1_block=0, *g1_wave=0, *g1_selectable=0, *g1_friction=0, *g1_save_name=0,
229  *g1_damage=0;
230
231// format of ("texture_name" (property_name prop_value)..)
232void g1_tile_class::get_properties(li_object *properties, li_environment *env)
233{
234  init();
235
236  while (properties)
237  {
238    li_symbol *sym=li_symbol::get(li_car(li_car(properties,env),env),env);
239    li_object *value=li_car(li_cdr(li_car(properties,env),env),env);
240
241    if (sym==li_get_symbol("block", g1_block))
242    {
243      if (li_get_bool(value,env)) flags|=BLOCKING; else flags&=~BLOCKING;
244    }
245    else if (sym==li_get_symbol("wave", g1_wave))
246    {
247      if (li_get_bool(value,env)) flags|=WAVE; else flags&=~WAVE;
248    }
249    else if (sym==li_get_symbol("selectable", g1_selectable))
250    {
251      if (li_get_bool(value, env)) flags|=SELECTABLE; else flags&=~SELECTABLE;
252    }
253    else if (sym==li_get_symbol("friction", g1_friction))
254      set_friction(li_float::get(value,env)->value());     
255    else if (sym==li_get_symbol("damage", g1_damage))
256      damage = li_int::get(value,env)->value();
257    else if (sym==li_get_symbol("save_name", g1_save_name))
258      filename_checksum=i4_str_checksum(i4_const_str(li_string::get(value,env)->value()));
259    else
260      i4_error("bad texture flag '%s' should be block, wave, selectable, friction, save_name",
261               sym->name()->value());
262
263    properties=li_cdr(properties,env);
264  }
265}
266
267void g1_tile_man_class::uninit()
268{
269  select_remap.uninit();
270  if (array)
271    i4_free(array);
272  array=0;
273}
274
Note: See TracBrowser for help on using the repository browser.