source: golgotha/src/golg/li_objref.cc

Last change on this file 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: 7.1 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 "li_objref.hh"
10#include "file/file.hh"
11#include "g1_object.hh"
12#include "lisp/lisp.hh"
13#include "lisp/li_init.hh"
14#include "saver.hh"
15#include "error/error.hh"
16#include "g1_render.hh"
17#include "g1_object.hh"
18#include "draw_context.hh"
19
20li_type_number li_g1_ref_type_number;
21li_object_pointer g1_null_ref;
22
23li_g1_ref::li_g1_ref(g1_object_class *o)
24  : li_object(li_g1_ref_type_number)
25{
26  if (o)
27    _global_id=o->global_id;
28  else
29    _global_id=g1_global_id.invalid_id();
30}
31
32li_g1_ref *li_g1_null_ref()
33{
34  return li_g1_ref::get(g1_null_ref.get(),0);
35}
36
37class li_g1_ref_function : public li_type_function_table
38{
39  virtual void print(li_object  *o, i4_file_class *stream)   
40  {
41    li_g1_ref *r=li_g1_ref::get(o,0);
42    g1_object_class *v=r->value();
43
44    stream->printf("(g1_object_class ");
45    if (v)
46      stream->printf(" %s (id=%d))", v->name(), v->global_id);
47    else
48      stream->printf(" null)");
49  }
50
51  virtual char *name() { return "object_ref"; }
52
53  virtual li_object *create(li_object *params, li_environment *env)
54  {
55    g1_object_class *o=0;
56    if (params)
57      o=li_g1_ref::get(li_eval(li_car(params,env), env),env)->value();
58
59    if (o)
60      return new li_g1_ref(o->global_id);
61    else
62      return li_g1_null_ref();
63  }
64
65  virtual void save_object(i4_saver_class *fp, li_object *o, li_environment *env)
66  {
67    ((g1_saver_class *)fp)->write_global_id(li_g1_ref::get(o, env)->_global_id);
68  }
69
70  virtual li_object *load_object(i4_loader_class *fp,  li_type_number *type_remap,
71                                 li_environment *env)
72  {
73    return new li_g1_ref(((g1_loader_class *)fp)->read_global_id());
74  }   
75};
76
77
78
79
80
81static w32 half_bright(w32 color)
82{
83  w32 r=((color&0xff0000)>>16)/4;
84  w32 g=((color&0xff00)>>8)/4;
85  w32 b=((color&0xff)/4);
86  return (r<<16)|(g<<8)|b;
87}
88
89inline float raise_dist() { return 0.05; }
90
91void li_g1_ref::draw(g1_object_class *start, w32 color, g1_draw_context_class *context)
92{
93  g1_object_class *o=value();
94  if (o)
95    g1_render.render_3d_line(i4_3d_point_class(start->x, start->y, start->h+raise_dist()),
96                             i4_3d_point_class(o->x, o->y, o->h+raise_dist()),
97                             color, half_bright(color),
98                             context->transform);
99}
100
101
102// ******************************** li_g1_ref_list ******************************
103
104
105void li_g1_ref_list::draw(g1_object_class *start, w32 color, g1_draw_context_class *context)
106{
107  int t=size();
108  for (int i=0; i<t; i++)
109  {
110    g1_object_class *o=value(i);
111    if (o)
112      g1_render.render_3d_line(i4_3d_point_class(start->x, start->y, start->h+raise_dist()),
113                               i4_3d_point_class(o->x, o->y, o->h+raise_dist()),
114                               color, half_bright(color),
115                               context->transform);
116  }
117}
118
119w32 li_g1_ref_list::get_id(int list_num)
120{
121  I4_ASSERT(list && list_num<list[0], "bad list_num");
122  return list[list_num+1];
123}
124
125g1_object_class *li_g1_ref_list::value(int list_num)
126{
127  w32 id=get_id(list_num);
128  if (g1_global_id.check_id(id))
129    return g1_global_id.get(id);
130  else
131    return 0;   
132}
133
134
135int li_g1_ref_list::find(w32 id)
136{
137  int t=size()+1;
138  for (int i=1; i<t; i++)     // object is already in list
139    if (list[i]==id)
140      return i-1;
141
142  return -1; 
143}
144
145int li_g1_ref_list::find(g1_object_class *o)
146{
147  return find(o->global_id);
148}
149
150
151void li_g1_ref_list::add(w32 id)
152{
153  if (find(id)==-1)
154  {
155    int t=size()+2;
156    list=(w32 *)i4_realloc(list, t * sizeof(w32),"li_g1_ref_list::list");
157    list[0]=t-1;
158    list[t-1]=id;
159  }
160}
161
162void li_g1_ref_list::add(g1_object_class *obj)
163{
164  add(obj->global_id);
165}
166
167li_g1_ref_list *li_g1_ref_list::clone()
168{
169  li_g1_ref_list *c=new li_g1_ref_list;
170 
171  int t=size();
172  for (int i=0; i<t; i++)
173  {
174    g1_object_class *o=value(i);
175    if (o)
176      c->add(o);
177  }
178  return c;
179}
180
181void li_g1_ref_list::remove(w32 id)
182{
183  int pos=find(id);
184
185  if (pos==-1)
186    i4_error("not in list");
187
188 
189  for (int i=pos+1; i<list[0]; i++)
190    list[i]=list[i+1];
191
192  list[0]--;
193}
194
195void li_g1_ref_list::remove(g1_object_class *o)
196{
197  remove(o->global_id);
198}
199
200void li_g1_ref_list::free()
201{
202  if (list)
203  {
204    i4_free(list);
205    list=0;
206  }
207}
208
209void li_g1_ref_list::compact()
210{
211  int t=size();
212  for (int i=0; i<t; i++)
213  {
214    w32 id=get_id(i);
215    if (!g1_global_id.check_id(id))
216    {
217      for (int j=i; j<t; j++)
218        list[j+1]=list[j+2];
219     
220      t--;
221      list[0]--;
222    }
223  }
224}
225
226li_type_number li_g1_ref_list_type_number;
227
228class li_g1_ref_list_function : public li_type_function_table
229{
230  virtual void free(li_object   *o)
231  {
232    li_g1_ref_list *p=li_g1_ref_list::get(o,0);
233    p->free();
234  }
235
236  virtual void print(li_object  *o, i4_file_class *stream)   
237  {
238    li_g1_ref_list *r=li_g1_ref_list::get(o,0);
239
240    stream->printf("(g1_object_list ");
241
242    for (int i=0; i<r->size(); i++)
243    {
244      g1_object_class *v=r->value(i);
245
246      if (v)
247        stream->printf(" %s (id=%d))", v->name(), v->global_id);
248      else
249        stream->printf(" null");
250    }
251    stream->printf(")");
252  }
253
254  virtual char *name() { return "object_ref_list"; }
255
256  virtual li_object *create(li_object *params, li_environment *env)
257  {
258    li_g1_ref_list *r=new li_g1_ref_list;
259
260    while (params)
261    {         
262      g1_object_class *o=li_g1_ref::get(li_eval(li_car(params,env), env),env)->value();
263      r->add(o);
264    }
265
266    return r;
267  }
268
269  virtual void save_object(i4_saver_class *fp, li_object *o, li_environment *env)
270  {
271
272    li_g1_ref_list *r=li_g1_ref_list::get(o,env);
273    r->compact();
274
275    int t=r->size();
276    fp->write_16(t);
277    for (int i=0; i<t; i++)     
278      ((g1_saver_class *)fp)->write_global_id(r->get_id(i));
279  }
280
281  virtual li_object *load_object(i4_loader_class *fp,  li_type_number *type_remap,
282                                 li_environment *env)
283  {
284    li_g1_ref_list *r=new li_g1_ref_list;
285    int t=fp->read_16();
286    for (int i=0; i<t; i++)
287      r->add(((g1_loader_class *)fp)->read_global_id());
288
289    return r;
290  }   
291};
292
293
294
295class li_g1_initer : public i4_init_class
296{
297public:
298  int init_type() { return I4_INIT_TYPE_LISP_FUNCTIONS; }
299  void init()
300  {
301    li_g1_ref_type_number=li_add_type(new li_g1_ref_function);
302    g1_null_ref=new li_g1_ref(g1_global_id.invalid_id());
303
304    li_g1_ref_list_type_number=li_add_type(new li_g1_ref_list_function);
305  }
306 
307  void uninit()
308  {
309    g1_null_ref=0;
310  }
311 
312} li_g1_initer_instance;
313
Note: See TracBrowser for help on using the repository browser.