source: golgotha/src/golg/editor/dialogs/path_win.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 14 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: 13.9 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 "editor/dialogs/path_win.hh"
10#include "window/window.hh"
11#include "window/style.hh"
12#include "gui/button.hh"
13#include "gui/image_win.hh"
14#include "gui/butbox.hh"
15
16#include "map.hh"
17#include "path_api.hh"
18#include "critical_graph.hh"
19#include "critical_map.hh"
20#include "solvemap_astar.hh"
21#include "solvegraph_breadth.hh"
22
23#include "image/depth.hh"
24#include "image/image32.hh"
25#include "device/keys.hh"
26
27#include "editor/editor.hh"
28
29enum {
30  P1_SET_START,
31  P1_SET_DESTINATION,
32  P1_SET_CRITICAL,
33  P1_LOAD_HOTSPOTS,
34
35  P1_SET_GRADE1,
36  P1_SET_GRADE2,
37  P1_SET_GRADE3,
38  P1_SET_GRADE4,
39
40  P1_SET_SIZE1,
41  P1_SET_SIZE3,
42
43  P1_RELOAD_MAP,
44
45  P1_SET_BLOCK,
46  P1_LAY_OBJECT,
47
48  P1_STOP,
49  P1_STEP,
50
51  P1_UNSET_BLOCK_EVENT
52};
53
54
55
56
57g1_path_tool_window_class::g1_path_tool_window_class(i4_graphical_style_class *style,
58                                                     i4_event_handler_class *send_to,
59                                                     int buttons, i4_image_class **img,
60                                                     i4_const_str **help_names)
61  : i4_button_box_class(send_to, i4_F)
62//{{{
63{
64  int x=0,y=0,ny=0;
65  for (int i=0; i<buttons; i++)
66  {
67    if (img[i])
68    {
69      i4_button_class *b;
70       
71      i4_user_message_event_class *uev=new i4_user_message_event_class(i);
72      i4_event_reaction_class *re=new i4_event_reaction_class(send_to, uev);
73       
74      b=new i4_button_class(help_names[i], new i4_image_window_class(img[i]), style, re);
75      b->set_popup(i4_T);
76
77      if (x+b->width()>40)
78      {
79        x=0;
80        y+=ny;
81        ny=0;
82      }
83      add_button(x,y, b);
84      x += b->width();
85      ny = b->height()>ny ? b->height() : ny;
86    }
87  }
88   
89  resize_to_fit_children();
90}
91//}}}
92
93
94g1_path_window_class::g1_path_window_class(g1_map_class *map,
95                                           i4_image_class **icons)
96  : map(map),
97    critical_graph(map->get_critical_graph()),
98    i4_parent_window_class(map->width()*CELL_SIZE,map->height()*CELL_SIZE)
99//{{{
100{
101  start_icon = icons[0];
102  dest_icon = icons[1];
103  crit_icon = icons[2];
104 
105  bitmap=0;
106  map_changed = 1;
107
108  grade = 0;
109  size = 2;
110  tofrom = 0;
111  points = 0;
112  maker = new g1_critical_map_maker_class();
113  maker->make_criticals(map, critical_graph);
114  solvemap = new g1_astar_map_solver_class(map->get_block_map(grade));
115  solvegraph = new g1_breadth_first_graph_solver_class(critical_graph);
116  solve();
117}
118//}}}
119
120g1_path_window_class::~g1_path_window_class()
121//{{{
122{
123  if (maker)
124    delete maker;
125  if (solvemap)
126    delete solvemap;
127  if (solvegraph)
128    delete solvegraph;
129  if (bitmap)
130    delete bitmap;
131}
132//}}}
133
134w32 g1_path_window_class::critical_color(w16 x, w16 y)
135//{{{
136{
137  w32 crit_col[6] = { 0x200000, 0x002000, 0x000020,
138                      0x400000, 0x004000, 0x000040 };
139  w32 col=0;
140  w16 crit;
141
142  crit = map->cell(x,y).nearest_critical[grade][tofrom][0];
143   
144  for (int i=0; i<6; i++)
145    if (crit & (1<<i))
146      col |= crit_col[i];
147   
148  return col;;
149}
150//}}}
151
152g1_astar_map_solver_class *g1_solvemap=0; //(OLI) Debug hack
153
154void g1_path_window_class::solve()
155//{{{
156{
157  g1_graph_node start_node = map->cell(start.x,start.y).nearest_critical[grade][tofrom][0];
158  g1_graph_node dest_node = map->cell(dest.x,dest.y).nearest_critical[grade][tofrom][0];
159
160  solvemap->path_solve(start.x, start.y, dest.x, dest.y, size, size, grade, point, points);
161  solvegraph->path_solve(start_node, dest_node, size, grade, point, points);
162
163  g1_solvemap = solvemap; //(OLI) Debug hack
164  printf("Corridor size %f!\n",
165         map->get_block_map(grade)->line_of_sight(start.x,start.y,dest.x,dest.y));
166  g1_solvemap = 0; //(OLI) Debug hack
167}
168//}}}
169
170void g1_path_window_class::draw_to_bitmap()
171//{{{
172{
173  map_changed=0;
174
175  int bmw=map->width()*CELL_SIZE, bmh=map->height()*CELL_SIZE, x,y, i,j,
176    mw=map->width(), mh=map->height(), px, py, ry;
177
178  if (bitmap && (bitmap->width() !=  bmw  ||  bitmap->height() != bmh))
179  {
180    delete bitmap;
181    bitmap=0;
182  }
183
184  if (!bitmap)
185  {
186    i4_pixel_format fmt;
187    fmt.default_format();
188    bitmap=new i4_image32(bmw, bmh, i4_pal_man.register_pal(&fmt));   
189  }
190
191  i4_image32::iterator block_pixel=bitmap->create_iterator(0,0), pixel;
192
193  g1_block_map_class *block_map = map->get_block_map(grade);
194  for (ry=0; ry<mh; ry++)
195  {
196    y = mh-1-ry;
197    for (x=0; x<mw; x++)
198    {
199      w32 color = map->vertex(x,y).height;
200     
201      color = critical_color(x,y);
202     
203      if (solvemap->is_visited(x,y))
204        color |= 0x004f00;
205      if (solvemap->is_ok(x,y))
206        color = 0x008f00;
207
208      if (block_map->is_blocked(x,y, G1_NORTH | G1_SOUTH | G1_EAST | G1_WEST))
209        color |= 0x800000;
210
211      w32 half_color = (color & 0xfefefe)>>1;
212
213      int blockN, blockW;
214
215      blockN = (y==mh-1 ||
216                block_map->is_blocked(x,y,G1_NORTH) ||
217                block_map->is_blocked(x,y+1,G1_SOUTH));
218      blockW = (x==0 ||
219                block_map->is_blocked(x,y,G1_WEST) ||
220                block_map->is_blocked(x-1,y,G1_EAST));
221      pixel=block_pixel;
222      for (py=0; py<CELL_SIZE; py++)
223      {
224        for (px=0; px<CELL_SIZE; px++, ++pixel)
225          bitmap->iterator_store(pixel, (  (px == 0 & blockW)? 0xffffff
226                                         : (py == 0 & blockN)? 0xffffff
227                                         : (px|py == 0)? half_color
228                                         : color ));
229
230        pixel += bitmap->width() - CELL_SIZE;
231      }
232
233      block_pixel += CELL_SIZE;
234
235    }
236    block_pixel += (CELL_SIZE-1) * bitmap->width();
237  }
238
239  i4_draw_context_class tmp_context(0,0,bitmap->width()-1,bitmap->height()-1);
240
241#if 0
242  //{{{ Draw Section Boundaries
243  test_block_map::CBounds::CBlockPoint *p,*q;
244  w16 pi=map->bounds.begin();
245  while (map->bounds.next_point(pi))
246  {
247    p = map->bounds.get_point(pi);
248    for (int l=0; l<4; l++)
249    {
250      if (p->edge[l]>pi) {
251        q = map->bounds.get_point(p->edge[l]);
252        bitmap->line(int(p->x*CELL_SIZE),int((mh-p->y)*CELL_SIZE-1),
253                     int(q->x*CELL_SIZE),int((mh-q->y)*CELL_SIZE-1),
254                     0x808080, tmp_context);
255      }
256      bitmap->put_pixel(int(p->x*CELL_SIZE),int((mh-p->y)*CELL_SIZE)-1, 0x0080ff, tmp_context);
257    }
258  }
259  //}}}
260#endif
261
262  for (j=1; j<critical_graph->criticals; j++)
263  {
264    g1_critical_graph_class::critical_point_class *crit = &critical_graph->critical[j];
265    for (i=0; i<crit->connections; i++)
266    {
267      if (crit->connection[i].size[grade])
268      {
269        w32 k=crit->connection[i].ref;
270        i4_float x1,y1, x2,y2, x3,y3, x4,y4;
271        x1 = crit->x*CELL_SIZE + CELL_SIZE/2;
272        y1 = (mh*CELL_SIZE-1) - (crit->y*CELL_SIZE + CELL_SIZE/2);
273        x4 = critical_graph->critical[k].x*CELL_SIZE + CELL_SIZE/2;
274        y4 = (mh*CELL_SIZE-1) - (critical_graph->critical[k].y*CELL_SIZE + CELL_SIZE/2);
275       
276        x2 = (x4-x1)*0.3 + x1;
277        y2 = (y4-y1)*0.3 + y1;
278        x3 = (x4-x1)*0.7 + x1;
279        y3 = (y4-y1)*0.7 + y1;
280       
281        bitmap->line((w16)x1,(w16)y1,(w16)x2,(w16)y2,
282                     0x000800*(crit->connection[i].size[grade]), tmp_context);
283        bitmap->line((w16)x2,(w16)y2,(w16)x3,(w16)y3, 0x404020, tmp_context);
284      }
285    }
286  }
287
288 
289  for (j=points-1; j>0; j--)    // points solved in backwards order
290  {
291    w32
292      x1 = w32(point[j*2-2])*CELL_SIZE + CELL_SIZE/2,
293      y1 = (mh*CELL_SIZE-1) - w32(point[j*2-1])*CELL_SIZE - CELL_SIZE/2,
294      x2 = w32(point[j*2+0])*CELL_SIZE + CELL_SIZE/2,
295      y2 = (mh*CELL_SIZE-1) - w32(point[j*2+1])*CELL_SIZE - CELL_SIZE/2;
296
297    bitmap->line(x1,y1,x2,y2,0xffff00, tmp_context);
298  }
299
300}
301//}}}
302
303void g1_path_window_class::parent_draw(i4_draw_context_class &context)
304//{{{
305{
306  int mw=map->width(), mh=map->height();
307
308  if (map_changed)
309    draw_to_bitmap();
310   
311  bitmap->put_image(local_image, 0,0, context);
312
313  int x,y;
314  x = start.x * CELL_SIZE + CELL_SIZE/2+1 - start_icon->width()/2;
315  y = (mh-1-start.y) * CELL_SIZE + CELL_SIZE/2+1 - start_icon->height()/2;
316
317  start_icon->put_image_trans(local_image, x, y, 0, context);
318
319  x = dest.x * CELL_SIZE + CELL_SIZE/2+1 - dest_icon->width()/2;
320  y = (mh-1-dest.y) * CELL_SIZE + CELL_SIZE/2+1 - dest_icon->height()/2;
321
322  dest_icon->put_image_trans(local_image, x, y, 0, context);
323
324  for (int i=0; i<critical_graph->criticals; i++)
325  {
326    x = sw32(critical_graph->critical[i].x)*CELL_SIZE
327      + CELL_SIZE/2+1 - crit_icon->width()/2;
328    y = (mh-1-sw32(critical_graph->critical[i].y))*CELL_SIZE
329      + CELL_SIZE/2+1 - crit_icon->height()/2;
330     
331    crit_icon->put_image_trans(local_image, x, y, 0, context);
332  }
333}
334//}}}
335 
336void g1_path_window_class::receive_event(i4_event *ev)
337{
338   
339  switch (ev->type())
340  {
341    case i4_event::MOUSE_MOVE:
342      //{{{
343    {
344      CAST_PTR(mev, i4_mouse_move_event_class, ev);
345       
346      last_x = mev->x; last_y = mev->y;
347    } break;
348    //}}}
349    case i4_event::MOUSE_BUTTON_UP:
350      //{{{
351    {
352      CAST_PTR(mbev, i4_mouse_button_up_event_class, ev);
353       
354      int cell_x=last_x/CELL_SIZE,
355        cell_y=map->height()-1-(last_y/CELL_SIZE);
356       
357      // determine type
358       
359      switch (mode)
360      {
361        case P1_SET_START :
362          //{{{
363        {
364          if (mbev->left())
365          {
366            start.x=cell_x;
367            start.y=cell_y;
368          }
369          else
370          {
371            dest.x=cell_x;
372            dest.y=cell_y;
373          }
374          solve();
375          changed();
376        } break;
377        //}}}
378        case P1_SET_DESTINATION :
379          //{{{
380        {
381          dest.x=cell_x;
382          dest.y=cell_y;
383          solve();
384          changed();
385        } break;
386        //}}}
387        case P1_SET_BLOCK:
388          //{{{
389        {
390          int flags=G1_NORTH | G1_EAST | G1_WEST | G1_SOUTH;
391             
392          if (mbev->left())
393            map->get_block_map(grade)->block(cell_x, cell_y, flags);
394          else
395            map->get_block_map(grade)->unblock(cell_x, cell_y, flags);
396             
397          maker->make_criticals(map, critical_graph);
398          solve();
399          changed();
400        } break;
401        //}}}
402        case P1_SET_CRITICAL:
403          //{{{
404        {
405          g1_editor_instance.add_undo(G1_MAP_CRITICAL_POINTS);
406          if (map) map->mark_for_recalc(G1_RECALC_CRITICAL_DATA);
407
408          if (mbev->left() && mbev->right())
409            critical_graph->criticals=0;
410          else if (mbev->left())
411            critical_graph->add_critical_point(cell_x, cell_y);
412          else if (mbev->right())
413          {
414            if (critical_graph->criticals>0)
415              --critical_graph->criticals;
416          }
417           
418          request_redraw();
419        } break;
420        //}}}
421      }
422       
423    } break;
424    //}}}
425    case i4_event::USER_MESSAGE:
426      //{{{
427    {
428      CAST_PTR(uev, i4_user_message_event_class, ev);
429      switch (uev->sub_type)
430      {
431        case P1_SET_BLOCK :
432        case P1_LAY_OBJECT :
433        case P1_SET_START :
434        case P1_SET_DESTINATION :
435        case P1_SET_CRITICAL :
436        case P1_STOP :
437        case P1_STEP :
438          mode=uev->sub_type;
439          break;
440
441        case P1_SET_GRADE1:
442        case P1_SET_GRADE2:
443        case P1_SET_GRADE3:
444        case P1_SET_GRADE4:
445          if (grade == uev->sub_type - P1_SET_GRADE1)
446            tofrom = !tofrom;
447          else
448          {
449            grade = uev->sub_type - P1_SET_GRADE1;
450            solvemap->set_block_map(map->get_block_map(grade));
451            solve();
452          }
453          changed();
454          break;
455
456        case P1_SET_SIZE1:
457        case P1_SET_SIZE3:
458          size = uev->sub_type - P1_SET_SIZE1 + 1;
459          solve();
460          changed();
461          break;
462
463        case P1_RELOAD_MAP:
464          //{{{
465        {
466          g1_editor_instance.add_undo(G1_MAP_CRITICAL_DATA);
467          critical_graph = map->get_critical_graph();
468          maker->make_criticals(map, critical_graph);
469          changed();
470        } break;
471        //}}}
472
473        case P1_LOAD_HOTSPOTS:
474          //{{{
475        {
476          int i,j,n;
477          g1_map_cell_class *c=&map->cell(0,0);
478
479          int g1_takeover_pad_type=g1_get_object_type("takeover_pad");
480
481          g1_editor_instance.add_undo(G1_MAP_CRITICAL_POINTS);
482          for (j=0; j<map->height(); j++)
483            for (i=0; i<map->height(); i++, c++)
484            {
485              for (g1_object_chain_class *obj=c->get_obj_list(); obj; obj=obj->next)
486              {
487                if (obj->object->id == g1_takeover_pad_type)
488                {
489                  int found=0;
490                  for (n=0; n<critical_graph->criticals; n++)
491                    if (critical_graph->critical[n].x==i &&
492                        critical_graph->critical[n].y==j)
493                      found = 1;
494                  if (!found)
495                  {
496                    critical_graph->critical[critical_graph->criticals].x = i;
497                    critical_graph->critical[critical_graph->criticals].y = j;
498                    critical_graph->criticals++;
499                  }
500                }
501              }
502            }
503             
504          changed();
505        } break;
506        //}}}
507      }     
508    }
509    //}}}
510  }
511}
512
513//{{{ Emacs Locals
514// Local Variables:
515// folded-file: t
516// End:
517//}}}
Note: See TracBrowser for help on using the repository browser.