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 |
|
---|
27 | g1_tile_man_class g1_tile_man;
|
---|
28 |
|
---|
29 |
|
---|
30 | static i4_array<w16> select_remap(0,128);
|
---|
31 |
|
---|
32 |
|
---|
33 | void 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 |
|
---|
41 | int g1_tile_man_class::get_remap(int tile_num)
|
---|
42 | {
|
---|
43 | return select_remap[tile_num];
|
---|
44 | }
|
---|
45 |
|
---|
46 | g1_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 |
|
---|
56 | int g1_tile_man_class::remap_size()
|
---|
57 | {
|
---|
58 | return select_remap.size();
|
---|
59 | }
|
---|
60 |
|
---|
61 | void 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 |
|
---|
79 | void 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 |
|
---|
87 | void g1_tile_class::init()
|
---|
88 | {
|
---|
89 | flags=SELECTABLE;
|
---|
90 | set_friction(g1_resources.damping_friction);
|
---|
91 | }
|
---|
92 |
|
---|
93 |
|
---|
94 | static 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 |
|
---|
118 | int 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 |
|
---|
124 | int 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 |
|
---|
130 | int 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 |
|
---|
139 | void 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 |
|
---|
169 | int 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 |
|
---|
198 | void 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 |
|
---|
228 | static 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)..)
|
---|
232 | void 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 |
|
---|
267 | void g1_tile_man_class::uninit()
|
---|
268 | {
|
---|
269 | select_remap.uninit();
|
---|
270 | if (array)
|
---|
271 | i4_free(array);
|
---|
272 | array=0;
|
---|
273 | }
|
---|
274 |
|
---|