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

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 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: 8.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 "map_man.hh"
10#include "map_cell.hh"
11#include "g1_object.hh"
12#include "tile.hh"
13#include "map.hh"
14#include "compress/rle.hh"
15#include "loaders/dir_save.hh"
16#include "loaders/dir_load.hh"
17#include "saver_id.hh"
18#include "map_vert.hh"
19
20g1_object_chain_class *g1_map_cell_class::get_solid_list()
21{
22  if (!object_list || !object_list->object->get_flag(g1_object_class::BLOCKING))
23    return 0;
24  else return object_list;
25}
26
27
28g1_object_chain_class *g1_map_cell_class::get_non_solid_list()
29{
30  g1_object_chain_class *p=object_list;
31
32  while (p && p->object->get_flag(g1_object_class::BLOCKING))
33    p=p->next;
34 
35  return p;
36}
37
38
39void g1_map_cell_class::add_object(g1_object_chain_class &o)
40{
41  if (!object_list ||
42      o.object->get_flag(g1_object_class::BLOCKING))  // add solids to front of list
43  {
44    o.next=object_list;
45    object_list=&o;
46  }
47  else
48  {
49    // add non solids after all solids
50    g1_object_chain_class *last=object_list, *p=object_list->next;
51    while (p && p->object->get_flag(g1_object_class::BLOCKING))
52    {
53      last=p;
54      p=p->next;
55    }
56    o.next=last->next;
57    last->next=&o;
58  }
59}
60
61i4_bool g1_map_cell_class::remove_object(g1_object_chain_class &o)
62{
63  if (&o==object_list)
64  {
65    object_list=o.next;
66    return i4_T;
67  }
68  else
69  {
70    g1_object_chain_class *c=object_list, *last;
71    while (c && c!=&o)
72    {
73      last=c;
74      c=c->next;     
75    }
76    if (!c)
77    {
78      i4_warning("map_cell::remove_object, object not in cell");
79      return i4_F;
80    }
81
82    last->next=o.next;
83    return i4_T;
84  }
85}
86
87
88void g1_map_cell_class::init(w16 _type, g1_rotation_type rot,
89                             i4_bool mirrored)
90{
91  object_list=0;
92  type=_type;
93  flags=FOGGED;
94  top_left_normal=0x8000;
95  bottom_right_normal=0x8000;
96 
97
98  g1_tile_man.get(_type)->apply_to_cell(*this); 
99  set_rotation(rot);
100  if (mirrored)
101    flags|=MIRRORED;
102}
103
104
105void g1_map_cell_class::recalc_top_left(int cx, int cy)
106{
107  int mw=g1_get_map()->width(), mh=g1_get_map()->height();
108
109  I4_ASSERT(cx<=mw && cy<=mh, "recalc normal : vert out of range");
110
111  if (cx==mw-1 || cy==mh-1)
112    top_left_normal=(31) | (15<<5) | (15<<10);     // normal = 0,0,1
113  else
114  {
115    g1_map_vertex_class *v=g1_get_map()->vertex(cx,cy);
116
117    float h0=v->get_height(), h2=v[mw+1].get_height(), h3=v[mw+1+1].get_height();
118 
119    i4_3d_vector v1(1, 0, h3-h2), v2(0, -1, h0-h2);
120
121    i4_3d_vector normal;
122    normal.cross(v2,v1);
123    normal.normalize();
124   
125    top_left_normal=g1_normal_to_16(normal);   
126  }
127
128}
129
130
131void g1_map_cell_class::recalc_bottom_right(int cx, int cy)
132{
133  int mw=g1_get_map()->width(), mh=g1_get_map()->height();
134  if (cx>=mw || cy>=mh)
135    bottom_right_normal=(31) | (15<<5) | (15<<10);     // normal = 0,0,1
136  else
137  {
138    g1_map_vertex_class *v=g1_get_map()->vertex(cx,cy);
139    float h0=v->get_height(), h1=v[1].get_height(), h3=v[mw+1+1].get_height();
140 
141    i4_3d_vector v1(-1, 0, h0-h1), v2(0, 1, h3-h1);
142
143    i4_3d_vector normal;
144    normal.cross(v2,v1);
145    normal.normalize();
146       
147    bottom_right_normal=g1_normal_to_16(normal);   
148  }
149
150}
151
152
153void g1_save_map_cells(g1_map_cell_class *list,
154                       int lsize, i4_saver_class *fp)
155{
156  int i,j;
157  i4_rle_class<w16> fp16(fp);
158
159  fp->mark_section("golgotha cell type v1");
160  for (i=0; i<lsize; i++)
161    fp16.write(list[i].type);
162  fp16.flush();
163
164
165  fp->mark_section("golgotha cell flags v2");
166  for (i=0; i<lsize; i++)
167    fp16.write(list[i].flags & g1_map_cell_class::SAVED_FLAGS);
168  fp16.flush();
169
170
171  fp->mark_section("golgotha cell normals v1");
172  for (i=0; i<lsize; i++)
173    fp16.write(list[i].top_left_normal);
174  for (i=0; i<lsize; i++)
175    fp16.write(list[i].bottom_right_normal);
176  fp16.flush();
177 
178}
179       
180
181
182i4_bool g1_load_map_cells(g1_map_cell_class *list, int lsize,
183                          w16 *tile_remap, i4_loader_class *fp)
184{
185  int i;
186  i4_rle_class<w16> fp16(fp);
187
188  //////////////////////////////////////////////////////////
189  // support for old formats
190  if (!fp->goto_section("golgotha cell type v1"))
191  {
192    g1_get_map()->mark_for_recalc(G1_RECALC_STATIC_LIGHT);
193
194    if (fp->goto_section(OLD_G1_SECTION_CELL_V6))
195    {
196      for (i=0; i<lsize; i++)
197        list[i].load_v6(fp, tile_remap);
198    } else if (fp->goto_section(OLD_G1_SECTION_CELL_V5))
199    {
200      for (i=0; i<lsize; i++)
201        list[i].load_v5(fp, tile_remap);
202    }
203    else if (fp->goto_section(OLD_G1_SECTION_CELL_V4))
204    {
205      for (i=0; i<lsize; i++)
206        list[i].load_v4(fp, tile_remap);
207    } else if (fp->goto_section(OLD_G1_SECTION_CELL_V3))
208    {
209      for (i=0; i<lsize; i++)
210        list[i].load_v3(fp, tile_remap);
211    } else if (fp->goto_section(OLD_G1_SECTION_CELL_V2))
212    {
213      for (i=0; i<lsize; i++)
214        list[i].load_v2(fp, tile_remap);
215    }
216    else
217      return i4_F;
218  }
219  else /////////////////////// new format : stored in rle arrays rather than structs
220  {   
221    for (i=0; i<lsize; i++)
222      list[i].type=tile_remap[fp16.read()];
223  }
224
225
226
227  if (fp->goto_section("golgotha cell flags v2"))
228  {
229    for (i=0; i<lsize; i++)
230      list[i].flags = fp16.read() & g1_map_cell_class::SAVED_FLAGS;
231  }
232  else if (fp->goto_section("golgotha cell flags v1"))
233  {
234    for (i=0; i<lsize; i++)
235    {
236      list[i].flags = (fp16.read() & g1_map_cell_class::SAVED_FLAGS) | g1_map_cell_class::FOGGED;
237      list[i].clear_restore_bits();
238    }
239  }
240
241  for (i=0; i<lsize; i++)
242    g1_tile_man.get(list[i].type)->apply_to_cell(list[i]); 
243
244
245  if (fp->goto_section("golgotha cell normals v1"))
246  {
247    for (i=0; i<lsize; i++)
248      list[i].top_left_normal=fp16.read();
249
250    for (i=0; i<lsize; i++)
251      list[i].bottom_right_normal=fp16.read();
252  }
253
254  return i4_T;
255}
256
257
258
259
260
261///////////////////// OLD LOAD CODE //////////////////////////
262
263
264void g1_map_cell_class::load_v2(i4_file_class *fp, w16 *tile_remap)
265{
266  object_list=0;
267  //  function_block=0xffff;
268
269  type=tile_remap[fp->read_16()];
270  flags=fp->read_8();
271  fp->read_8();
272  fp->read_16();            // nearest node gone
273
274  top_left_normal=0x8000;
275  bottom_right_normal=0x8000;
276}
277
278void g1_map_cell_class::load_v3(i4_file_class *fp, w16 *tile_remap)
279{
280  object_list=0;
281
282  type=tile_remap[fp->read_16()];
283  flags=fp->read_16();
284
285  fp->read_8();  // height not used anymore
286
287  fp->read_16();            // nearest node gone
288
289  top_left_normal=0x8000;
290  bottom_right_normal=0x8000;
291}
292
293void g1_map_cell_class::load_v4(i4_file_class *fp, w16 *tile_remap)
294{
295  object_list=0;
296
297  type=tile_remap[fp->read_16()];
298  flags=fp->read_16();
299
300  fp->read_16();            // nearest node gone
301
302  if (type==0)
303    flags |= IS_GROUND;
304
305  top_left_normal=0x8000;
306  bottom_right_normal=0x8000;
307}
308
309void g1_map_cell_class::load_v5(i4_file_class *fp, w16 *tile_remap)
310{
311  object_list=0;
312       
313  type     = tile_remap[fp->read_16()];
314  fp->read_8();
315
316
317  flags=fp->read_16();
318
319  fp->read_16();              // nearest_node gone
320
321  if (type==0)
322    flags |= IS_GROUND; 
323
324  top_left_normal=0x8000;
325  bottom_right_normal=0x8000;
326}
327
328void g1_map_cell_class::load_v6(i4_file_class *fp, w16 *tile_remap)
329{
330  object_list=0;
331  type     = tile_remap[fp->read_16()];
332  fp->read_8();
333
334  w32 blah = fp->read_32();     // height info not used anymoe
335  if (blah)
336  {
337    fp->read_8();
338    fp->read_16();
339    fp->read_float();
340    fp->read_float();
341  }
342
343
344  flags=fp->read_16();
345
346  fp->read_16();              // nearest_node gone
347
348  if (type==0)
349    flags |= IS_GROUND; 
350
351  top_left_normal=0x8000;
352  bottom_right_normal=0x8000;
353}
354
355
356
357void g1_map_cell_class::unfog(int x, int y)
358{
359  flags&=~FOGGED;
360  g1_map_vertex_class *v=g1_verts+x+y*(g1_map_width+1);
361  v->set_flag(g1_map_vertex_class::FOGGED,0);
362  v++;
363  v->set_flag(g1_map_vertex_class::FOGGED,0);
364  v+=g1_map_width;
365  v->set_flag(g1_map_vertex_class::FOGGED,0);
366  v++;
367  v->set_flag(g1_map_vertex_class::FOGGED,0);
368}
Note: See TracBrowser for help on using the repository browser.