source: golgotha/src/golg/editor/commands/map_dump.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_cell.hh"
10#include "map_vert.hh"
11#include "map_man.hh"
12#include "lisp/lisp.hh"
13#include "lisp/li_init.hh"
14#include "map.hh"
15#include "objs/path_object.hh"
16#include "g1_render.hh"
17#include "r1_api.hh"
18#include "tmanage.hh"
19#include "tile.hh"
20#include "app/app.hh"
21#include "window/window.hh"
22#include "r1_win.hh"
23#include "loaders/tga_write.hh"
24#include "window/wmanager.hh"
25
26
27
28static float tri1_s[8*3]={0,1,1, 1,1,0, 1,0,0, 0,0,1, 0,0,1, 1,0,0, 1,1,0, 0,1,1};
29static float tri1_t[8*3]={1,1,0, 1,0,0, 0,0,1, 0,1,1, 1,0,0, 1,1,0, 0,1,1, 0,0,1};
30
31static float tri2_s[8*3]={0,1,0, 1,0,0, 1,0,1, 0,1,1, 0,1,1, 1,0,1, 1,0,0, 0,1,0};
32static float tri2_t[8*3]={1,0,0, 1,0,1, 0,1,1, 0,1,0, 1,0,1, 1,0,0, 0,1,0, 0,1,1};
33
34
35class map_renderer_class : public i4_window_class
36{
37public:
38  i4_bool do_it_again;
39  int ax1, ay1, ax2, ay2;
40
41  map_renderer_class(int w, int h) : i4_window_class(w,h)
42  {
43    do_it_again=i4_T;
44  }
45
46  void request_redraw(i4_bool for_a_child=i4_F)
47  {
48    i4_window_class::request_redraw(for_a_child);
49    do_it_again=i4_T;
50  }
51
52  void draw(i4_draw_context_class &context)
53  {
54    r1_render_api_class *api=g1_render.r_api;
55    r1_texture_manager_class *tman=api->get_tmanager();
56   
57    do_it_again=i4_F;
58   
59    float s, t, s_step, t_step;
60    s_step=width()/(float)(ax2-ax1);
61    t_step=height()/(float)(ay2-ay1);
62
63    api->default_state();
64    api->clear_area(0,0,width()-1,height()-1, 0, 100); 
65
66    api->set_filter_mode(R1_NO_FILTERING);
67
68    int x,y;
69    t=0;
70    for (y=ay1; y<ay2; y++, t+=t_step)
71    {
72      s=0;
73      for (x=ax1; x<ax2; x++, s+=s_step)
74      {
75        g1_map_cell_class *c=g1_cells + g1_map_width*y+x;
76        g1_map_vertex_class *v1=g1_verts + (g1_map_width+1)*y+x, *v2,*v3,*v4;
77        v2=v1+1;
78        v3=v2+g1_map_width+1;
79        v4=v3-1;
80
81        int texture=g1_tile_man.get(c->type)->texture;
82        api->use_texture(texture, (int)s_step, 0);
83
84        int st_index=c->get_rotation();
85        if (c->mirrored())
86          st_index+=4;
87
88        st_index*=3;
89
90        r1_vert v[4];
91 
92        v[0].px=s;              v[0].py=t;
93        v[1].px=s+s_step;       v[1].py=t;
94        v[2].px=s+s_step;       v[2].py=t+t_step;
95        v[3].px=s;              v[3].py=t+t_step;
96 
97
98        v[0].s=tri1_s[st_index];      v[0].t=tri1_t[st_index];
99        v[1].s=tri1_s[st_index+1];    v[1].t=tri1_t[st_index+1];
100        v[2].s=tri1_s[st_index+2];    v[2].t=tri1_t[st_index+2];
101        v[3].s=tri2_s[st_index+2];    v[3].t=tri2_t[st_index+2];
102
103        float z=1.0;
104        float w=1.0/z;
105        v[0].w=w; v[0].v.z=z;
106        v[1].w=w; v[1].v.z=z;
107        v[2].w=w; v[2].v.z=z;
108        v[3].w=w; v[3].v.z=z;
109
110        v[0].a=v[1].a=v[2].a=v[3].a=1;
111
112#if 0
113        v[0].r=v[0].g=v[0].b=v1->get_non_dynamic_ligth_intensity(x,y);
114        v[1].r=v[1].g=v[1].b=v2->get_non_dynamic_ligth_intensity(x+1,y);
115        v[2].r=v[2].g=v[2].b=v3->get_non_dynamic_ligth_intensity(x+1,y+1);
116        v[3].r=v[3].g=v[3].b=v4->get_non_dynamic_ligth_intensity(x,y+1);
117#else
118        v[0].r = v[0].g = v[0].b = 1.0;
119        v[1].r = v[1].g = v[1].b = 1.0;
120        v[2].r = v[2].g = v[2].b = 1.0;
121        v[3].r = v[3].g = v[3].b = 1.0;
122#endif
123        api->render_poly(4, v);
124      }
125    }
126
127    api->set_filter_mode(R1_BILINEAR_FILTERING);
128  }
129  char *name() { return "renderer"; }
130};
131
132
133i4_image_class *render_map_section(int x1, int y1, int x2, int y2, int im_w, int im_h)
134{
135  r1_render_api_class *api=g1_render.r_api;
136
137  r1_render_window_class *rwin=api->create_render_window(im_w, im_h);
138  map_renderer_class *map_r=new map_renderer_class(im_w, im_h);
139
140  map_r->ax1=x1;
141  map_r->ay1=y1;
142  map_r->ax2=x2;
143  map_r->ay2=y2;
144
145
146  rwin->add_child(0,0, map_r);
147  i4_current_app->get_window_manager()->add_child(0,0,rwin);
148 
149 
150  i4_draw_context_class context(0,0,im_w-1, im_h-1);
151
152  i4_display_class *display=i4_current_app->get_display();
153 
154  int tries=0;
155  r1_texture_manager_class *tman=api->get_tmanager();
156  do
157  {
158    tman->next_frame();
159    rwin->draw(context);
160    display->flush();
161
162    tries++;
163    // repeat until textures have rez-ed in
164    // or it doens't look like it'll happen
165  } while (map_r->do_it_again && tries<100);
166
167
168
169  i4_pixel_format fmt;
170  fmt.default_format();
171  fmt.alpha_mask=0;
172  fmt.calc_shift();
173  const i4_pal *pal=i4_pal_man.register_pal(&fmt);
174
175  i4_image_class *fb;
176  i4_image_class *to=0;
177
178  fb=display->lock_frame_buffer(I4_BACK_FRAME_BUFFER, I4_FRAME_BUFFER_READ);
179  if (fb)
180  {
181    to = i4_create_image(im_w, im_h, pal);
182    fb->put_part(to, 0,0, 0,0, im_w-1, im_h-1, context);
183    display->unlock_frame_buffer(I4_BACK_FRAME_BUFFER);
184  }
185
186  delete rwin;
187
188  return to;
189}
190
191
192struct area
193{
194  int x1,y1,x2,y2;
195  area(int x1, int y1, int x2, int y2) : x1(x1),y1(y1),x2(x2),y2(y2) {}
196  area() {}
197};
198
199static i4_array<area *> *list;
200
201static void split_gather(int x1, int y1, int x2, int y2, int level)
202{
203  if (list->size()>=6)
204    return ;
205
206 
207  int xd=x2-x1+1, yd=y2-y1+1;
208  if (xd>yd)
209  {
210    int xs=(x2+x1)/2;
211    list->add(new area(x1, y1, xs, y2));
212    list->add(new area(xs, y1, x2, y2));
213
214    if (level!=1)
215    {
216      split_gather(x1, y1, xs, y2, level+1);
217      split_gather(xs, y1, x2, y2, level+1);
218    }
219  }
220  else
221  {
222    int ys=(y2+y1)/2;
223
224    list->add(new area(x1, y1, x2, ys));
225    list->add(new area(x1, ys, x2, y2));
226
227    if (level!=1)
228    {
229      split_gather(x1, y1, x2, ys, level+1);
230      split_gather(x1, ys, x2, y2, level+1);
231    }
232  }
233}
234
235li_object *g1_dump_level(li_object *o, li_environment *env)
236{
237  i4_file_class *fp=i4_open("dump_level", I4_WRITE);
238  if (!fp)
239    return 0;
240  g1_map_class *map=g1_get_map();
241
242  int w=map->width(), h=map->height(),i,x,y;
243  fp->write_32(0xabcf);   // version
244  fp->write_16(w);
245  fp->write_16(h);
246
247  // save off a 1 pixel bitmap
248  g1_map_cell_class *c=g1_cells;
249  for (y=0; y<h; y++)
250    for (x=0; x<w; x++, c++)
251    {
252      int type=g1_tile_man.get_texture(c->type);
253      w32 color= g1_render.r_api->get_tmanager()->average_texture_color(type, 0);
254      g1_map_vertex_class *v=g1_verts+x+y*(w+1);
255
256      float tr,tg,tb;
257      v->get_rgb(tr,tg,tb, x,y);
258
259      int r=int(((color>>16)&0xff) * tr);
260      int g=int(((color>> 8)&0xff) * tg);
261      int b=int(((color>> 0)&0xff) * tb);
262
263
264      fp->write_32((r<<16)|(g<<8)|b);
265    }
266 
267
268
269  // save vert hights and normals
270  g1_map_vertex_class *v=g1_verts;
271  for (y=0; y<=h; y++)
272    for (x=0; x<=w; x++, v++)
273    {
274      i4_3d_vector normal;
275      v->get_normal(normal, x,y);
276
277      fp->write_float(normal.x);
278      fp->write_float(normal.y);
279      fp->write_float(normal.z);
280      fp->write_float(v->get_height());
281     
282
283      float r,g,b;
284      v->get_rgb(r,g,b, x,y);
285      fp->write_float(r);
286      fp->write_float(g);
287      fp->write_float(b);
288    }
289
290
291  i4_array<area *> mlist(0,32);
292
293  // save cell texture names
294  c=g1_cells;
295  for (i=0; i<w*h; i++, c++)
296  {
297    int type=g1_tile_man.get_texture(c->type);
298    char *tname=g1_render.r_api->get_tmanager()->get_texture_name(type);
299    int len=strlen(tname)+1;
300    fp->write_16(len);
301    fp->write(tname,len);
302
303    int flags=c->get_rotation();
304    if (c->mirrored())
305      flags|=4;
306
307    fp->write_8(flags);
308  }
309
310
311  list=&mlist;
312  int x1=0,y1=0, x2=g1_map_width, y2=g1_map_height;
313  split_gather(x1,y1,x2,y2,0 );
314 
315  for (i=2; i<6; i++)
316  {
317    int x1=mlist[i]->x1, y1=mlist[i]->y1, x2=mlist[i]->x2, y2=mlist[i]->y2;
318
319    printf("%d %d %d %d\n",x1,y1,x2,y2);
320    i4_image_class *to;
321
322    if (to = render_map_section(x1,y1,x2,y2, 256,256))
323    {
324      char fn[100];
325      sprintf(fn,"x:/jc/lod_test/%d.tga", i-2);
326      i4_file_class *fp=i4_open(fn, I4_WRITE);
327      i4_tga_write(to, fp, 0);
328      delete to;
329    }
330  }
331
332  for (i=0; i<mlist.size(); i++)
333    delete mlist[i];
334
335  delete fp;
336  return 0;
337}
338
339li_automatic_add_function(g1_dump_level, "dump_level");
Note: See TracBrowser for help on using the repository browser.