source: golgotha/src/golg/objs/model_id.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: 4.8 KB
RevLine 
[80]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 "objs/model_id.hh"
10#include "string/string.hh"
11#include "error/alert.hh"
12#include "error/error.hh"
13#include "load3d.hh"
14#include "obj3d.hh"
15#include "saver.hh"
16#include "r1_api.hh"
17#include "status/status.hh"
18#include "time/profile.hh"
19
20i4_profile_class pf_load_models("load_models");
21g1_model_list_class g1_model_list_man;
22
23g1_model_ref *model_references=0;
24
25
26g1_model_ref::g1_model_ref(char *name)
27{
28  next = model_references;
29  model_references = this;
30  set_name(name);
31}
32
33void g1_model_ref::set_name(char *_name)
34{
35  name=_name;
36  value=g1_model_list_man.find_handle(name);
37}
38
39g1_model_ref::~g1_model_ref()
40{
41//   i4_debug->printf("cleaning up for %s\n", name);
42
43//   for (g1_model_ref *m=model_references; m; m=m->next)
44//     i4_debug->printf("%s ", m->name);
45//   i4_debug->printf("\n");
46
47
48  if (model_references==this)
49    model_references = next;
50  else
51  {
52    g1_model_ref *p;
53
54    for (p = model_references; p->next && p->next!=this; p=p->next) ;
55
56    if (!p->next)
57      i4_error("model reference not in list");
58    else
59      p->next = p->next->next;
60  }
61}
62
63
64i4_grow_heap_class *g1_object_heap=0;
65
66
67int g1_model_info_compare(const void *a, const void *b)
68{
69  return strcmp(((g1_model_list_class::model_info *)a)->name_start,
70                ((g1_model_list_class::model_info *)b)->name_start);
71}
72
73void g1_model_list_class::cleanup()
74{
75  if (g1_object_heap) 
76    delete g1_object_heap;
77
78  if (name_buffer)
79    delete name_buffer;
80 
81  if (array)
82  {
83    i4_free(array);
84    array=0;
85  }
86}
87
88static i4_profile_class pf_model_load_open("models:open");
89
90
91void g1_model_list_class::reset(i4_array<i4_str *> &model_names, r1_texture_manager_class *tmap)
92{
93  if (g1_object_heap) 
94    g1_object_heap->clear();
95
96  if (name_buffer)
97    name_buffer->clear();
98 
99  if (array)
100  {
101    i4_free(array);
102    array=0;
103  }
104
105  pf_load_models.start();
106
107  i4_status_class *stat=i4_create_status(i4gets("loading_models"));
108
109  total_models=model_names.size();
110  array=(model_info *)i4_malloc(total_models * sizeof(model_info), "model list");
111
112  int actual_total=0;
113  g1_quad_object_loader_class loader(g1_object_heap);
114
115  for (int i=0; i<model_names.size(); i++)
116  {
117    if (stat)
118      stat->update(i/(float)model_names.size());
119
120    pf_model_load_open.start();
121    i4_file_class *in_file=i4_open(*model_names[i]);
122    if (in_file)
123    {
124      g1_loader_class *fp=g1_open_save_file(in_file);       
125      pf_model_load_open.stop();
126      if (fp)
127      {
128        array[actual_total].model=loader.load(fp, *model_names[i], tmap);
129
130        if (array[actual_total].model)
131        {
132          i4_filename_struct fn;
133          i4_split_path(*model_names[i], fn);
134
135          array[actual_total].model->scale(0.1);
136
137          // copy the name into the name buffer
138          int len=strlen(fn.filename)+1;
139          char *c=(char *)name_buffer->malloc(len, "name");
140          strcpy(c, fn.filename);
141
142          array[actual_total].name_start=c;
143          actual_total++;       
144        }
145        delete fp;
146
147      }
148      else
149        i4_alert(i4gets("old_model_file"),200, model_names[i]);
150
151    }
152    else
153    {
154      pf_model_load_open.stop();
155      i4_alert(i4gets("file_missing"), 200, model_names[i]);
156    }
157
158  }
159
160  delete stat;
161
162  total_models=actual_total;
163  qsort(array, total_models, sizeof(model_info), g1_model_info_compare);
164
165
166  // reset the model_reference values
167  for (g1_model_ref *mi=model_references; mi; mi=mi->next)
168    mi->value=find_handle(mi->name);
169
170  pf_load_models.stop();
171
172}
173
174w16 g1_model_list_class::find_handle(const char *name) const
175{
176  if (!name || !total_models) return 0;
177
178  sw32 lo=0,hi=total_models-1,mid;
179
180  mid=(lo+hi+1)/2;
181  while (1)
182  {
183    int comp=strcmp(array[mid].name_start,name);
184    if (comp==0)
185      return mid;
186    else if (comp<0)
187      lo=mid+1;
188    else hi=mid-1;
189   
190    w32 last_mid=mid;
191    mid=(hi+lo)/2;
192
193    if (last_mid==mid)
194    {
195      i4_warning("Unable to find model %s, using default", name);
196      return 0;
197    }
198  }
199  return 0;
200}
201
202void g1_model_list_class::init()
203{
204  name_buffer=new i4_grow_heap_class(2048,1024);
205  g1_object_heap=new i4_grow_heap_class(1000*1024,0);
206  array=0;
207}
208
209void g1_model_list_class::uninit()
210{
211  cleanup();
212}
Note: See TracBrowser for help on using the repository browser.