source: golgotha/src/golg/editor/commands/resize_level.cc

Last change on this file 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: 6.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/editor.hh"
10#include "editor/pmenu.hh"
11#include "gui/create_dialog.hh"
12#include "gui/text_input.hh"                                       
13#include "remove_man.hh"
14#include "m_flow.hh"
15#include "editor/e_res.hh"
16#include "map_vert.hh"
17
18void g1_editor_class::open_resize_level_window()
19{
20  if (get_map())
21  {
22    create_modal(300, 250, "resize_title");
23
24    i4_create_dialog(g1_ges("resize_dialog"),
25                     modal_window.get(),
26                     style,
27                     get_map()->width(), get_map()->height(),
28
29                     G1_MIN_MAP_DIMENSION, G1_MAX_MAP_DIMENSION,
30                     &resize_dialog.w, get_map()->width(),
31
32                     G1_MIN_MAP_DIMENSION, G1_MAX_MAP_DIMENSION,
33                     &resize_dialog.h, get_map()->height(),
34
35                     this, G1_EDITOR_RESIZE_PLACE_LT,
36                     this, G1_EDITOR_RESIZE_PLACE_CT,
37                     this, G1_EDITOR_RESIZE_PLACE_RT,
38                     this, G1_EDITOR_RESIZE_PLACE_LC,
39                     this, G1_EDITOR_RESIZE_PLACE_CC,
40                     this, G1_EDITOR_RESIZE_PLACE_RC,
41                     this, G1_EDITOR_RESIZE_PLACE_BL,
42                     this, G1_EDITOR_RESIZE_PLACE_BC,
43                     this, G1_EDITOR_RESIZE_PLACE_BR,
44
45                     this, G1_EDITOR_RESIZE_MAP_OK,
46                     this, G1_EDITOR_MODAL_BOX_CANCEL);
47    resize_dialog.orient=4;
48  }
49
50}
51
52void g1_editor_class::resize_level()
53{
54  int w,h;
55
56  i4_str::iterator is=resize_dialog.w->get_edit_string()->begin();
57  w=is.read_number();
58  is=resize_dialog.h->get_edit_string()->begin();
59  h=is.read_number();
60 
61 
62  if (!(w>=G1_MIN_MAP_DIMENSION && h>=G1_MIN_MAP_DIMENSION
63        && w<=G1_MAX_MAP_DIMENSION && h<=G1_MAX_MAP_DIMENSION))
64  {
65    create_modal(300, 50, "bad_w_h_title");
66    i4_create_dialog(g1_ges("bad_map_w_h_dialog"),
67                     modal_window.get(), style, w, h,
68                     G1_MIN_MAP_DIMENSION,
69                     G1_MAX_MAP_DIMENSION,
70                     this, G1_EDITOR_MODAL_BOX_CANCEL);
71  }
72  else
73  {
74    if (g1_map_is_loaded())
75    {
76      int sx1,sy1,sx2,sy2, dx1,dy1,dx2,dy2, x,y, i;
77      int dir=resize_dialog.orient;
78   
79      if (w>=get_map()->width())
80      {
81        if (dir==0 || dir==3 || dir==6)
82          dx1=0;
83        else if (dir==1 || dir==4 || dir==7)
84          dx1=w/2-get_map()->width()/2;
85        else
86          dx1=w-get_map()->width();
87
88        dx2=dx1+w-1;
89
90        sx1=0; sx2=get_map()->width()-1;
91      }
92      else                                    // need to chop width
93      {
94        if (dir==0 || dir==3 || dir==6)       // chop off the right
95          sx1=0;
96        else if (dir==1 || dir==4 || dir==7)  // chop off left and right
97          sx1=get_map()->width()/2-w/2;
98        else
99          sx1=get_map()->width()-w;                // chop off left
100
101        sx2=sx1+w-1;
102        dx1=0; dx2=w-1;
103      }
104
105   
106      if (h>=get_map()->height())
107      {
108        if (dir==6 || dir==7 || dir==8)
109          dy1=0;
110        else if (dir==3 || dir==4 || dir==5)
111          dy1=h/2-get_map()->height()/2;
112        else
113          dy1=w-get_map()->height();
114
115        dy2=dy1+h-1;
116
117        sy1=0; sy2=get_map()->height()-1;
118      }
119      else                                    // need to chop height
120      {
121        if (dir==6 || dir==7 || dir==8)       // chop off the bottom
122          sy1=0;
123        else if (dir==3 || dir==4 || dir==5)  // chop off top and bottom
124          sy1=get_map()->height()/2-h/2;
125        else
126          sy1=get_map()->height()-h;                // chop off top
127
128        sy2=sy1+h-1;
129        dy1=0; dy2=h-1;
130      }
131
132
133      g1_map_cell_class *ncells=(g1_map_cell_class *)i4_malloc(w * h *sizeof(g1_map_cell_class),
134                                                               "map_cells");
135
136      g1_map_vertex_class *nverts=(g1_map_vertex_class *)i4_malloc((w+1) * (h+1) *
137                                                                   sizeof(g1_map_vertex_class),
138                                                                   "map_verts");
139     
140      // first initial all the new stuff
141      g1_map_cell_class *c1=ncells, *c2;
142      for (y=0; y<h; y++)
143        for (x=0; x<w; x++, c1++)
144        {
145          c1->init(0, G1_ROTATE_0, i4_F);
146          if (x==0 || y==0 || x==w-1 || y==h-1)
147            c1->flags=0;
148          else
149            c1->flags=g1_map_cell_class::IS_GROUND;
150        }
151     
152      g1_map_vertex_class *v1=nverts,*v2;
153      for (i=0; i<(w+1)*(h+1); i++, v1++)
154        v1->init();
155
156      // copy old area
157      int yl=sy2-sy1+1;
158      for (y=0; y<yl; y++)
159      {
160        c1=ncells + (dy1+y)*w + dx1;
161        c2=get_map()->cells + (sy1+y)*get_map()->width() + sx1;
162
163        for (x=sx1; x<=sx2; x++, c1++, c2++)
164        {
165          *c1=*c2;
166          c1->object_list=0;
167        }
168      }
169
170      yl=sy2-sy1+2;
171      for (y=0; y<yl; y++)
172      {
173        v1=nverts + (dy1+y)*(w+1) + dx1;
174        v2=get_map()->verts + (sy1+y)*(get_map()->width()+1) + sx1;
175
176        for (x=sx1; x<=sx2+1; x++, v1++, v2++)
177          *v1=*v2;
178      }   
179
180
181      // take objects off old map and move them
182      g1_object_class *olist[G1_MAX_OBJECTS];
183      sw32 t=get_map()->make_object_list(olist, G1_MAX_OBJECTS);
184      for (i=0; i<t; i++)
185      {
186        g1_object_class *o=olist[i];
187        o->unoccupy_location();
188        o->x+=(dx1-sx1);
189        o->y+=(dy1-sy1);
190
191        if (o->x<0 || o->y<0 || o->x>=w || o->y>=h)
192        {
193          get_map()->request_remove(o);
194          g1_remove_man.process_requests();
195          olist[i]=0;
196
197        }
198        else
199        {
200          o->lx=o->x;
201          o->ly=o->y;
202          o->lh=o->h;
203        }
204      }
205
206      i4_free(get_map()->cells);
207      i4_free(get_map()->verts);
208
209
210
211      get_map()->cells=ncells;            // swap data with new stuff
212      get_map()->verts=nverts;
213      get_map()->w=w;
214      get_map()->h=h;
215     
216      // add objects onto the map
217      for (i=0; i<t; i++)
218        if (olist[i])
219          olist[i]->occupy_location();
220
221      // move the movie
222      g1_movie_flow_class *movie=get_map()->current_movie;
223      if (movie)
224      {
225        for (i=0; i<movie->t_cut_scenes; i++)
226          movie->set[i]->move((dx1-sx1), (dy1-sy1), 0);
227      }
228
229      get_map()->mark_for_recalc(0xffffff);
230
231    }
232
233    close_modal();
234  }
235}
236
Note: See TracBrowser for help on using the repository browser.