improved the behaviour of the mouse-cursor in the leveleditor
[supertux.git] / src / leveleditor.cpp
1 /***************************************************************************
2  *                                                                         *
3  *   This program is free software; you can redistribute it and/or modify  *
4  *   it under the terms of the GNU General Public License as published by  *
5  *   the Free Software Foundation; either version 2 of the License, or     *
6  *   (at your option) any later version.                                   *
7  *                                                                         *
8  ***************************************************************************/
9
10 /*  December 28, 2003 - March 15, 2004 */
11
12 /* leveleditor.c - A built-in level editor for SuperTux
13  Ricardo Cruz <rick2@aeiou.pt>
14  Tobias Glaesser <tobi.web@gmx.de>                      */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <SDL.h>
22 #include <SDL_image.h>
23 #include "leveleditor.h"
24
25 #include "screen.h"
26 #include "defines.h"
27 #include "globals.h"
28 #include "setup.h"
29 #include "menu.h"
30 #include "level.h"
31 #include "badguy.h"
32 #include "scene.h"
33 #include "button.h"
34
35 /* definitions to aid development */
36 #define DONE_LEVELEDITOR 1
37 #define DONE_QUIT        2
38 #define DONE_CHANGELEVEL 3
39
40 /* definitions that affect gameplay */
41 #define KEY_CURSOR_SPEED 32
42 #define KEY_CURSOR_FASTSPEED 64
43
44 /* when pagedown/up pressed speed:*/
45 #define PAGE_CURSOR_SPEED 13*32
46
47 #define MOUSE_LEFT_MARGIN 80
48 #define MOUSE_RIGHT_MARGIN (560-32)
49 /* right_margin should noticed that the cursor is 32 pixels,
50    so it should subtract that value */
51 #define MOUSE_POS_SPEED 20
52
53 /* look */
54 #define SELECT_W 2 // size of the selections lines
55 #define SELECT_CLR 0, 255, 0, 255  // lines color (R, G, B, A)
56
57 /* gameloop funcs declerations */
58
59 void loadshared(void);
60 void unloadshared(void);
61
62 /* own declerations */
63 /* crutial ones (main loop) */
64 int le_init();
65 void le_quit();
66 void le_drawlevel();
67 void le_drawinterface();
68 void le_checkevents();
69 void le_change(float x, float y, int tm, unsigned int c);
70 void le_testlevel();
71 void le_showhelp();
72 void le_set_defaults(void);
73 void le_activate_bad_guys(void);
74
75 void le_highlight_selection();
76
77 void apply_level_settings_menu();
78 void update_subset_settings_menu();
79 void save_subset_settings_menu();
80 void le_update_buttons(const char*);
81
82 /* leveleditor internals */
83 static string_list_type level_subsets;
84 static bool le_level_changed;  /* if changes, ask for saving, when quiting*/
85 static int pos_x, cursor_x, cursor_y, fire;
86 static int le_level;
87 static st_level* le_current_level;
88 static st_subset le_level_subset;
89 static int le_show_grid;
90 static int le_frame;
91 static texture_type le_selection;
92 static int done;
93 static unsigned int le_current_tile;
94 static bool le_mouse_pressed[2];
95 static button_type le_save_level_bt;
96 static button_type le_test_level_bt;
97 static button_type le_next_level_bt;
98 static button_type le_previous_level_bt;
99 static button_type le_move_right_bt;
100 static button_type le_move_left_bt;
101 static button_type le_rubber_bt;
102 static button_type le_select_mode_one_bt;
103 static button_type le_select_mode_two_bt;
104 static button_type le_settings_bt;
105 static button_type le_bad_bt;
106 static button_type le_bkgd_bt;
107 static button_type le_fgd_bt;
108 static button_panel_type le_bkgd_panel;
109 static button_panel_type le_fgd_panel;
110 static button_panel_type le_bad_panel;
111 static Menu* leveleditor_menu;
112 static Menu* subset_load_menu;
113 static Menu* subset_new_menu;
114 static Menu* subset_settings_menu;
115 static Menu* level_settings_menu;
116
117 static square selection;
118 static int le_selection_mode;
119 static SDL_Event event;
120
121 void le_set_defaults()
122 {
123   if(le_current_level != NULL)
124     {
125       /* Set defaults: */
126
127       if(le_current_level->time_left == 0)
128         le_current_level->time_left = 255;
129     }
130 }
131
132 int leveleditor(int levelnb)
133 {
134   int last_time, now_time, i;
135
136   le_level = levelnb;
137   if(le_init() != 0)
138     return 1;
139
140   /* Clear screen: */
141
142   clearscreen(0, 0, 0);
143   updatescreen();
144
145   while (SDL_PollEvent(&event))
146   {}
147
148   while(true)
149     {
150       last_time = SDL_GetTicks();
151       le_frame++;
152
153       le_checkevents();
154
155       if(le_current_level != NULL)
156         {
157           /* making events results to be in order */
158           if(pos_x < 0)
159             pos_x = 0;
160           if(pos_x > (le_current_level->width * 32) - screen->w)
161             pos_x = (le_current_level->width * 32) - screen->w;
162
163           /* draw the level */
164           le_drawlevel();
165         }
166       else
167         clearscreen(0, 0, 0);
168
169       /* draw editor interface */
170       le_drawinterface();
171
172       if(show_menu)
173         {
174           menu_process_current();
175           if(current_menu == leveleditor_menu)
176             {
177               switch (leveleditor_menu->check())
178                 {
179                 case 2:
180                   show_menu = false;
181                   break;
182                 case 3:
183                   update_subset_settings_menu();
184                   break;
185                 case 7:
186                   done = DONE_LEVELEDITOR;
187                   break;
188                 }
189             }
190           else if(current_menu == level_settings_menu)
191             {
192               switch (level_settings_menu->check())
193                 {
194                 case 13:
195                   apply_level_settings_menu();
196                   Menu::set_current(leveleditor_menu);
197                   break;
198                 default:
199                   show_menu = true;
200                   break;
201                 }
202             }
203           else if(current_menu == subset_load_menu)
204             {
205               switch (i = subset_load_menu->check())
206                 {
207                 case 0:
208                   break;
209                 default:
210                   if(i != -1)
211                     {
212                       le_level_subset.load(level_subsets.item[i-2]);
213                       leveleditor_menu->item[3].kind = MN_GOTO;
214                       le_level = 1;
215                       arrays_init();
216                       loadshared();
217                       le_current_level = new st_level;
218                       if(level_load(le_current_level, le_level_subset.name.c_str(), le_level) != 0)
219                         {
220                           le_quit();
221                           return 1;
222                         }
223                       le_update_buttons(le_current_level->theme.c_str());
224                       le_set_defaults();
225                       level_load_gfx(le_current_level);
226                       show_menu = true;
227                     }
228                   break;
229                 }
230             }
231           else if(current_menu == subset_new_menu)
232             {
233               if(subset_new_menu->item[2].input[0] == '\0')
234                 subset_new_menu->item[3].kind = MN_DEACTIVE;
235               else
236                 {
237                   subset_new_menu->item[3].kind = MN_ACTION;
238
239                   switch (i = subset_new_menu->check())
240                     {
241                     case 3:
242                       st_subset::create(subset_new_menu->item[2].input);
243                       le_level_subset.load(subset_new_menu->item[2].input);
244                       leveleditor_menu->item[3].kind = MN_GOTO;
245                       le_level = 1;
246                       arrays_init();
247                       loadshared();
248                       le_current_level = new st_level;
249                       if(level_load(le_current_level, le_level_subset.name.c_str(), le_level) != 0)
250                         {
251                           le_quit();
252                           return 1;
253                         }
254                       le_update_buttons(le_current_level->theme.c_str());
255                       le_set_defaults();
256                       level_load_gfx(le_current_level);
257                       menu_item_change_input(&subset_new_menu->item[2],"");
258                       show_menu = true;
259                       break;
260                     }
261                 }
262             }
263           else if(current_menu == subset_settings_menu)
264             {
265               if(le_level_subset.title.compare(subset_settings_menu->item[2].input) == 0 && le_level_subset.description.compare(subset_settings_menu->item[3].input) == 0  )
266                 subset_settings_menu->item[5].kind = MN_DEACTIVE;
267               else
268                 subset_settings_menu->item[5].kind = MN_ACTION;
269
270               switch (i = subset_settings_menu->check())
271                 {
272                 case 5:
273                   save_subset_settings_menu();
274                   show_menu = true;
275                   break;
276                 }
277             }
278         }
279
280       mouse_cursor->draw();
281
282       if(done)
283         {
284           le_quit();
285           return 0;
286         }
287
288       if(done == DONE_QUIT)
289         {
290           le_quit();
291           return 1;
292         }
293
294       SDL_Delay(25);
295       now_time = SDL_GetTicks();
296       if (now_time < last_time + FPS)
297         SDL_Delay(last_time + FPS - now_time);  /* delay some time */
298
299       flipscreen();
300     }
301
302   return done;
303 }
304
305
306 void le_update_buttons(const char *theme)
307 {
308   int i;
309   char filename[1024];
310   char pathname[1024];
311   SDLKey key;
312   string_list_type bkgd_files;
313   string_list_type fgd_files;
314
315   sprintf(pathname,"images/themes/%s",theme);
316   bkgd_files =  dfiles(pathname,"bkgd-", NULL);
317   string_list_sort(&bkgd_files);
318
319   le_bkgd_panel.hidden = true;
320   key = SDLK_a;
321   for(i = 0; i < bkgd_files.num_items; ++i)
322     {
323       sprintf(filename,"%s/%s",pathname,bkgd_files.item[i]);
324       button_change_icon(&le_bkgd_panel.item[i],filename);
325     }
326
327   sprintf(pathname,"images/themes/%s",theme);
328   fgd_files =  dfiles(pathname,"solid", NULL);
329   string_list_sort(&fgd_files);
330   key = SDLK_a;
331   for(i = 0; i < fgd_files.num_items; ++i)
332     {
333       sprintf(filename,"%s/%s",pathname,fgd_files.item[i]);
334       button_change_icon(&le_fgd_panel.item[i],filename);
335     }
336
337   string_list_free(&fgd_files);
338   fgd_files =  dfiles(pathname,"brick", NULL);
339   string_list_sort(&fgd_files);
340
341   for(i = 0; i < fgd_files.num_items; ++i)
342     {
343       sprintf(filename,"%s/%s",pathname,fgd_files.item[i]);
344       button_change_icon(&le_fgd_panel.item[i+14],filename);
345     }
346 }
347
348 int le_init()
349 {
350   int i;
351   char filename[1024];
352   SDLKey key;
353   string_list_type fgd_files;
354   string_list_type bkgd_files;
355   string_list_type bad_files;
356   level_subsets = dsubdirs("/levels", "info");
357
358   le_show_grid = true;
359
360   /*  level_changed = NO;*/
361   fire = DOWN;
362   done = 0;
363   le_frame = 0; /* support for frames in some tiles, like waves and bad guys */
364   le_level_changed = false;
365   le_current_level = NULL;
366
367   le_current_tile = 0;
368   le_mouse_pressed[LEFT] = false;
369   le_mouse_pressed[RIGHT] = false;
370
371   texture_load(&le_selection, datadir + "/images/leveleditor/select.png", USE_ALPHA);
372
373   /* Load buttons */
374   button_load(&le_save_level_bt,"/images/icons/save.png","Save level", SDLK_F6,screen->w-64,32);
375   button_load(&le_next_level_bt,"/images/icons/up.png","Next level", SDLK_PAGEUP,screen->w-64,0);
376   button_load(&le_previous_level_bt,"/images/icons/down.png","Previous level",SDLK_PAGEDOWN,screen->w-32,0);
377   button_load(&le_rubber_bt,"/images/icons/rubber.png","Rubber",SDLK_DELETE,screen->w-32,48);
378   button_load(&le_select_mode_one_bt,"/images/icons/select-mode1.png","Select single tile",SDLK_F3,screen->w-64,48);
379   button_load(&le_select_mode_two_bt,"/images/icons/select-mode2.png","Select multiple tiles",SDLK_F3,screen->w-64,64);
380   button_load(&le_test_level_bt,"/images/icons/test-level.png","Test level",SDLK_F4,screen->w-64,screen->h - 64);
381   button_load(&le_settings_bt,"/images/icons/settings.png","Level settings",SDLK_F5,screen->w-32,screen->h - 64);
382   button_load(&le_move_left_bt,"/images/icons/left.png","Move left",SDLK_LEFT,0,0);
383   button_load(&le_move_right_bt,"/images/icons/right.png","Move right",SDLK_RIGHT,screen->w-80,0);
384   button_load(&le_fgd_bt,"/images/icons/fgd.png","Foreground tiles", SDLK_F7,screen->w-64,82);
385   button_load(&le_bkgd_bt,"/images/icons/bgd.png","Background tiles", SDLK_F8,screen->w-43,82);
386   button_load(&le_bad_bt,"/images/icons/emy.png","Enemies", SDLK_F9,screen->w-22,82);
387
388   bkgd_files =  dfiles("images/themes/antarctica","bkgd-", NULL);
389   string_list_sort(&bkgd_files);
390
391   button_panel_init(&le_bkgd_panel, screen->w - 64,98, 64, 318);
392   le_bkgd_panel.hidden = true;
393   key = SDLK_a;
394   for(i = 0; i < bkgd_files.num_items; ++i)
395     {
396       sprintf(filename,"images/themes/antarctica/%s",bkgd_files.item[i]);
397       button_panel_additem(&le_bkgd_panel,button_create(filename, "Background Tile",(SDLKey)((int)key+i),0,0),i);
398     }
399
400   string_list_free(&bkgd_files);
401   bkgd_files = dfiles("images/shared","cloud-", NULL);
402   string_list_sort(&bkgd_files);
403
404   for(i = 0; i < bkgd_files.num_items; ++i)
405     {
406       sprintf(filename,"images/shared/%s",bkgd_files.item[i]);
407       button_panel_additem(&le_bkgd_panel,button_create(filename, "Background Tile",(SDLKey)((int)key+i+8),0,0),i+8);
408     }
409
410   fgd_files =  dfiles("images/themes/antarctica","solid", NULL);
411   string_list_sort(&fgd_files);
412   key = SDLK_a;
413   button_panel_init(&le_fgd_panel, screen->w - 64,98, 64, 318);
414   for(i = 0; i < fgd_files.num_items; ++i)
415     {
416       sprintf(filename,"images/themes/antarctica/%s",fgd_files.item[i]);
417       button_panel_additem(&le_fgd_panel,button_create(filename, "Foreground Tile",(SDLKey)((int)key+i),0,0),i);
418     }
419
420   string_list_free(&fgd_files);
421   string_list_add_item(&fgd_files,"waves-0.png");
422   string_list_add_item(&fgd_files,"water.png");
423   string_list_add_item(&fgd_files,"pole.png");
424   string_list_add_item(&fgd_files,"poletop.png");
425   string_list_add_item(&fgd_files,"flag-0.png");
426   string_list_add_item(&fgd_files,"box-empty.png");
427   string_list_add_item(&fgd_files,"mints.png");
428   string_list_add_item(&fgd_files,"distro-0.png");
429   string_list_add_item(&fgd_files,"golden-herring.png");
430   string_list_add_item(&fgd_files,"distro-0.png");
431
432   for(i = 0; i < fgd_files.num_items; ++i)
433     {
434       sprintf(filename,"images/shared/%s",fgd_files.item[i]);
435       button_panel_additem(&le_fgd_panel,button_create(filename, "Foreground Tile",(SDLKey)((int)key+i+4),0,0),i+4);
436     }
437
438   string_list_free(&fgd_files);
439   fgd_files =  dfiles("images/themes/antarctica","brick", NULL);
440   string_list_sort(&fgd_files);
441
442   for(i = 0; i < fgd_files.num_items; ++i)
443     {
444       sprintf(filename,"images/themes/antarctica/%s",fgd_files.item[i]);
445       button_panel_additem(&le_fgd_panel,button_create(filename, "Foreground Tile",(SDLKey)((int)key+i+14),0,0),i+14);
446     }
447
448   string_list_free(&fgd_files);
449   string_list_add_item(&fgd_files,"distro-0.png");
450   string_list_add_item(&fgd_files,"distro-0.png");
451   for(i = 0; i < fgd_files.num_items; ++i)
452     {
453       sprintf(filename,"images/shared/%s",fgd_files.item[i]);
454       button_panel_additem(&le_fgd_panel,button_create(filename, "Foreground Tile",(SDLKey)((int)key+i+16),0,0),i+16);
455     }
456
457   le_fgd_panel.item[10].bkgd = &le_fgd_panel.item[9].icon;
458   le_fgd_panel.item[11].bkgd = &le_fgd_panel.item[9].icon;
459   le_fgd_panel.item[12].bkgd = &le_fgd_panel.item[9].icon;
460   le_fgd_panel.item[16].bkgd = &le_fgd_panel.item[14].icon;
461   le_fgd_panel.item[17].bkgd = &le_fgd_panel.item[15].icon;
462
463   string_list_init(&bad_files);
464   string_list_add_item(&bad_files,"bsod-left-0.png");
465   string_list_add_item(&bad_files,"laptop-left-0.png");
466   string_list_add_item(&bad_files,"bag-left-0.png");
467   button_panel_init(&le_bad_panel, screen->w - 64,98, 64, 318);
468   le_bad_panel.hidden = true;
469   key = SDLK_a;
470   for(i = 0; i < bad_files.num_items; ++i)
471     {
472       sprintf(filename,"images/shared/%s",bad_files.item[i]);
473       button_panel_additem(&le_bad_panel,button_create(filename, "Bad Guy",(SDLKey)((int)key+i),0,0),i);
474     }
475
476   leveleditor_menu = new Menu();
477   subset_load_menu = new Menu();
478   subset_new_menu  = new Menu();
479   subset_settings_menu = new Menu();
480   level_settings_menu  = new Menu();
481
482   leveleditor_menu->additem(MN_LABEL,"Level Editor Menu",0,0);
483   leveleditor_menu->additem(MN_HL,"",0,0);
484   leveleditor_menu->additem(MN_ACTION,"Return To Level Editor",0,0);
485   leveleditor_menu->additem(MN_DEACTIVE,"Level Subset Settings",0,subset_settings_menu);
486   leveleditor_menu->additem(MN_GOTO,"Load Level Subset",0,subset_load_menu);
487   leveleditor_menu->additem(MN_GOTO,"New Level Subset",0,subset_new_menu);
488   leveleditor_menu->additem(MN_HL,"",0,0);
489   leveleditor_menu->additem(MN_ACTION,"Quit Level Editor",0,0);
490
491   menu_reset();
492   Menu::set_current(leveleditor_menu);
493   show_menu = true;
494
495   subset_load_menu->additem(MN_LABEL, "Load Level Subset", 0, 0);
496   subset_load_menu->additem(MN_HL, "", 0, 0);
497
498   for(i = 0; i < level_subsets.num_items; ++i)
499     {
500       subset_load_menu->additem(MN_ACTION,level_subsets.item[i],0,0);
501     }
502   subset_load_menu->additem(MN_HL,"",0,0);
503   subset_load_menu->additem(MN_BACK,"Back",0,0);
504
505   subset_new_menu->additem(MN_LABEL,"New Level Subset",0,0);
506   subset_new_menu->additem(MN_HL,"",0,0);
507   subset_new_menu->additem(MN_TEXTFIELD,"Enter Name",0,0);
508   subset_new_menu->additem(MN_ACTION,"Create",0,0);
509   subset_new_menu->additem(MN_HL,"",0,0);
510   subset_new_menu->additem(MN_BACK,"Back",0,0);
511
512   subset_settings_menu->additem(MN_LABEL,"Level Subset Settings",0,0);
513   subset_settings_menu->additem(MN_HL,"",0,0);
514   subset_settings_menu->additem(MN_TEXTFIELD,"Title",0,0);
515   subset_settings_menu->additem(MN_TEXTFIELD,"Description",0,0);
516   subset_settings_menu->additem(MN_HL,"",0,0);
517   subset_settings_menu->additem(MN_ACTION,"Save Changes",0,0);
518   subset_settings_menu->additem(MN_HL,"",0,0);
519   subset_settings_menu->additem(MN_BACK,"Back",0,0);
520
521   level_settings_menu->arrange_left = true;
522   level_settings_menu->additem(MN_LABEL,"Level Settings",0,0);
523   level_settings_menu->additem(MN_HL,"",0,0);
524   level_settings_menu->additem(MN_TEXTFIELD,"Name    ",0,0);
525   level_settings_menu->additem(MN_STRINGSELECT,"Theme   ",0,0);
526   level_settings_menu->additem(MN_STRINGSELECT,"Song    ",0,0);
527   level_settings_menu->additem(MN_STRINGSELECT,"Bg-Image",0,0);
528   level_settings_menu->additem(MN_NUMFIELD,"Length ",0,0);
529   level_settings_menu->additem(MN_NUMFIELD,"Time   ",0,0);
530   level_settings_menu->additem(MN_NUMFIELD,"Gravity",0,0);
531   level_settings_menu->additem(MN_NUMFIELD,"Red    ",0,0);
532   level_settings_menu->additem(MN_NUMFIELD,"Green  ",0,0);
533   level_settings_menu->additem(MN_NUMFIELD,"Blue   ",0,0);
534   level_settings_menu->additem(MN_HL,"",0,0);
535   level_settings_menu->additem(MN_ACTION,"Apply Changes",0,0);
536
537   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
538
539   return 0;
540 }
541
542 void update_level_settings_menu()
543 {
544   char str[80];
545   int i;
546
547   menu_item_change_input(&level_settings_menu->item[2], le_current_level->name.c_str());
548   sprintf(str,"%d",le_current_level->width);
549
550   string_list_copy(level_settings_menu->item[3].list, dsubdirs("images/themes", "solid0.png"));
551   string_list_copy(level_settings_menu->item[4].list, dfiles("music/",NULL, "-fast"));
552   string_list_copy(level_settings_menu->item[5].list, dfiles("images/background",NULL, NULL));
553   string_list_add_item(level_settings_menu->item[5].list,"");
554   if((i = string_list_find(level_settings_menu->item[3].list,le_current_level->theme.c_str())) != -1)
555     level_settings_menu->item[3].list->active_item = i;
556   if((i = string_list_find(level_settings_menu->item[4].list,le_current_level->song_title.c_str())) != -1)
557     level_settings_menu->item[4].list->active_item = i;
558   if((i = string_list_find(level_settings_menu->item[5].list,le_current_level->bkgd_image.c_str())) != -1)
559     level_settings_menu->item[5].list->active_item = i;
560
561   menu_item_change_input(&level_settings_menu->item[6], str);
562   sprintf(str,"%d",le_current_level->time_left);
563   menu_item_change_input(&level_settings_menu->item[7], str);
564   sprintf(str,"%2.0f",le_current_level->gravity);
565   menu_item_change_input(&level_settings_menu->item[8], str);
566   sprintf(str,"%d",le_current_level->bkgd_red);
567   menu_item_change_input(&level_settings_menu->item[9], str);
568   sprintf(str,"%d",le_current_level->bkgd_green);
569   menu_item_change_input(&level_settings_menu->item[10], str);
570   sprintf(str,"%d",le_current_level->bkgd_blue);
571   menu_item_change_input(&level_settings_menu->item[11], str);
572 }
573
574 void update_subset_settings_menu()
575 {
576   menu_item_change_input(&subset_settings_menu->item[2], le_level_subset.title.c_str());
577   menu_item_change_input(&subset_settings_menu->item[3], le_level_subset.description.c_str());
578 }
579
580 void apply_level_settings_menu()
581 {
582   int i;
583   i = false;
584
585   le_current_level->name = level_settings_menu->item[2].input;
586
587   if(le_current_level->bkgd_image.compare(string_list_active(level_settings_menu->item[5].list)) != 0)
588     {
589       le_current_level->bkgd_image = string_list_active(level_settings_menu->item[5].list);
590       i = true;
591     }
592
593   if(le_current_level->theme.compare(string_list_active(level_settings_menu->item[3].list)) != 0)
594     {
595       le_current_level->theme = string_list_active(level_settings_menu->item[3].list);
596       le_update_buttons(le_current_level->theme.c_str());
597       i = true;
598     }
599
600   if(i)
601     {
602       level_free_gfx();
603       level_load_gfx(le_current_level);
604     }
605
606   le_current_level->song_title = string_list_active(level_settings_menu->item[4].list);
607
608   level_change_size(le_current_level, atoi(level_settings_menu->item[6].input));
609   le_current_level->time_left = atoi(level_settings_menu->item[7].input);
610   le_current_level->gravity = atof(level_settings_menu->item[8].input);
611   le_current_level->bkgd_red = atoi(level_settings_menu->item[9].input);
612   le_current_level->bkgd_green = atoi(level_settings_menu->item[10].input);
613   le_current_level->bkgd_blue = atoi(level_settings_menu->item[11].input);
614 }
615
616 void save_subset_settings_menu()
617 {
618   le_level_subset.title = subset_settings_menu->item[2].input;
619   le_level_subset.description = subset_settings_menu->item[3].input;
620   le_level_subset.save();
621 }
622
623 void le_goto_level(int levelnb)
624 {
625   arrays_free();
626   arrays_init();
627
628   level_free(le_current_level);
629   if(level_load(le_current_level, le_level_subset.name.c_str(), levelnb) != 0)
630     {
631       level_load(le_current_level, le_level_subset.name.c_str(), le_level);
632     }
633   else
634     {
635       le_level = levelnb;
636     }
637
638   le_set_defaults();
639
640   le_update_buttons(le_current_level->theme.c_str());
641
642   level_free_gfx();
643   level_load_gfx(le_current_level);
644 }
645
646 void le_quit(void)
647 {
648   /*if(level_changed == true)
649     if(askforsaving() == CANCEL)
650       return;*/ //FIXME
651
652   SDL_EnableKeyRepeat(0, 0);    // disables key repeating
653
654   texture_free(&le_selection);
655   delete leveleditor_menu;
656   delete subset_load_menu;
657   delete subset_new_menu;
658   delete subset_settings_menu;
659   delete level_settings_menu;
660   button_panel_free(&le_bkgd_panel);
661   button_panel_free(&le_fgd_panel);
662   button_panel_free(&le_bad_panel);
663   button_free(&le_save_level_bt);
664   button_free(&le_test_level_bt);
665   button_free(&le_next_level_bt);
666   button_free(&le_previous_level_bt);
667   button_free(&le_move_right_bt);
668   button_free(&le_move_left_bt);
669   button_free(&le_rubber_bt);
670   button_free(&le_select_mode_one_bt);
671   button_free(&le_select_mode_two_bt);
672   button_free(&le_settings_bt);
673   button_free(&le_bad_bt);
674   button_free(&le_bkgd_bt);
675   button_free(&le_fgd_bt);
676
677   if(le_current_level != NULL)
678     {
679       level_free_gfx();
680       level_free(le_current_level);
681       unloadshared();
682       arrays_free();
683     }
684 }
685
686 void le_drawinterface()
687 {
688   int x,y;
689   char str[80];
690
691   if(le_current_level != NULL)
692     {
693       /* draw a grid (if selected) */
694       if(le_show_grid)
695         {
696           for(x = 0; x < 19; x++)
697             fillrect(x*32 - ((int)pos_x % 32), 0, 1, screen->h, 225, 225, 225,255);
698           for(y = 0; y < 15; y++)
699             fillrect(0, y*32, screen->w - 32, 1, 225, 225, 225,255);
700         }
701     }
702
703   if(le_selection_mode == CURSOR)
704     texture_draw(&le_selection, cursor_x - pos_x, cursor_y);
705   else if(le_selection_mode == SQUARE)
706     {
707       int w, h;
708       le_highlight_selection();
709       /* draw current selection */
710       w = selection.x2 - selection.x1;
711       h = selection.y2 - selection.y1;
712       fillrect(selection.x1 - pos_x, selection.y1, w, SELECT_W, SELECT_CLR);
713       fillrect(selection.x1 - pos_x + w, selection.y1, SELECT_W, h, SELECT_CLR);
714       fillrect(selection.x1 - pos_x, selection.y1 + h, w, SELECT_W, SELECT_CLR);
715       fillrect(selection.x1 - pos_x, selection.y1, SELECT_W, h, SELECT_CLR);
716     }
717
718
719   /* draw button bar */
720   fillrect(screen->w - 64, 0, 64, screen->h, 50, 50, 50,255);
721   drawshape(19 * 32, 14 * 32, le_current_tile);
722   switch(le_current_tile)
723     {
724     case 'B':
725       texture_draw(&img_mints, 19 * 32, 14 * 32);
726       break;
727     case '!':
728       texture_draw(&img_golden_herring,19 * 32, 14 * 32);
729       break;
730     case 'x':
731     case 'y':
732     case 'A':
733       texture_draw(&img_distro[(le_frame / 5) % 4], 19 * 32, 14 * 32);
734       break;
735     case '0':
736       texture_draw(&img_bsod_left[(le_frame / 5) % 4],19 * 32, 14 * 32);
737       break;
738     case '1':
739       texture_draw(&img_laptop_left[(le_frame / 5) % 3],19 * 32, 14 * 32);
740       break;
741     case '2':
742       texture_draw(&img_money_left[0],19 * 32, 14 * 32);
743       break;
744     default:
745       break;
746     }
747
748   if(le_current_level != NULL)
749     {
750       button_draw(&le_save_level_bt);
751       button_draw(&le_test_level_bt);
752       button_draw(&le_next_level_bt);
753       button_draw(&le_previous_level_bt);
754       button_draw(&le_rubber_bt);
755       button_draw(&le_select_mode_one_bt);
756       button_draw(&le_select_mode_two_bt);
757       button_draw(&le_settings_bt);
758       button_draw(&le_move_right_bt);
759       button_draw(&le_move_left_bt);
760       button_draw(&le_bad_bt);
761       button_draw(&le_bkgd_bt);
762       button_draw(&le_fgd_bt);
763       button_panel_draw(&le_bkgd_panel);
764       button_panel_draw(&le_fgd_panel);
765       button_panel_draw(&le_bad_panel);
766
767       sprintf(str, "%d/%d", le_level,le_level_subset.levels);
768       text_drawf(&white_text, str, -8, 16, A_RIGHT, A_TOP, 1);
769
770       text_draw(&white_small_text, "F1 for Help", 10, 430, 1);
771     }
772   else
773     {
774       if(show_menu == false)
775         text_draw(&white_small_text, "No Level Subset loaded - Press ESC and choose one in the menu", 10, 430, 1);
776       else
777         text_draw(&white_small_text, "No Level Subset loaded", 10, 430, 1);
778     }
779
780 }
781
782 void le_drawlevel()
783 {
784   unsigned int y,x,i,s;
785
786   /* Draw the real background */
787   if(le_current_level->bkgd_image[0] != '\0')
788     {
789       s = pos_x / 30;
790       texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s - 32, img_bkgd.h);
791       texture_draw_part(&img_bkgd,0,0,screen->w - s - 32 ,0,s,img_bkgd.h);
792     }
793   else
794     {
795       clearscreen(le_current_level->bkgd_red, le_current_level->bkgd_green, le_current_level->bkgd_blue);
796     }
797
798   /*       clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */
799
800   for (y = 0; y < 15; ++y)
801     for (x = 0; x < 20; ++x)
802       {
803         drawshape(x * 32 - ((int)pos_x % 32), y * 32, le_current_level->ia_tiles[y][x + (int)(pos_x / 32)]);
804
805         /* draw whats inside stuff when cursor is selecting those */
806         /* (draw them all the time - is this the right behaviour?) */
807         switch(le_current_level->ia_tiles[y][x + (int)(pos_x/32)])
808           {
809           case 'B':
810             texture_draw(&img_mints, x * 32 - ((int)pos_x % 32), y*32);
811             break;
812           case '!':
813             texture_draw(&img_golden_herring, x * 32 - ((int)pos_x % 32), y*32);
814             break;
815           case 'x':
816           case 'y':
817           case 'A':
818             texture_draw(&img_distro[(global_frame_counter / 5) % 4], x * 32 - ((int)pos_x % 32), y*32);
819             break;
820           default:
821             break;
822           }
823       }
824
825   /* Draw the Bad guys: */
826   for (i = 0; i < bad_guys.size(); ++i)
827     {
828       /* to support frames: img_bsod_left[(frame / 5) % 4] */
829       if(bad_guys[i].kind == BAD_BSOD)
830         texture_draw(&img_bsod_left[(le_frame / 5) % 4], bad_guys[i].base.x - pos_x, bad_guys[i].base.y);
831       else if(bad_guys[i].kind == BAD_LAPTOP)
832         texture_draw(&img_laptop_left[(le_frame / 5) % 3], bad_guys[i].base.x - pos_x, bad_guys[i].base.y);
833       else if (bad_guys[i].kind == BAD_MONEY)
834         texture_draw(&img_money_left[(le_frame / 5) % 2], bad_guys[i].base.x - pos_x, bad_guys[i].base.y);
835     }
836
837
838   /* Draw the player: */
839   /* for now, the position is fixed at (0, 240) */
840   texture_draw(&tux_right[(global_frame_counter / 5) % 3], 0 - pos_x, 240);
841 }
842
843 void le_checkevents()
844 {
845   SDLKey key;
846   SDLMod keymod;
847   button_type* pbutton;
848   int x,y;
849
850   keymod = SDL_GetModState();
851
852   while(SDL_PollEvent(&event))
853     {
854       if(show_menu)
855           menu_event(event);
856       else
857           mouse_cursor->set_state(MC_NORMAL);
858
859       /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/
860       if(event.type == SDL_KEYDOWN || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > 0 && event.motion.x < screen->w - 64 &&
861                                        event.motion.y > 0 && event.motion.y < screen->h)))
862         {
863           switch(event.type)
864             {
865             case SDL_KEYDOWN:   // key pressed
866               key = event.key.keysym.sym;
867               if(show_menu)
868                 {
869                   if(key == SDLK_ESCAPE)
870                     {
871                       show_menu = false;
872                       Menu::set_current(leveleditor_menu);
873                     }
874                   break;
875                 }
876               switch(key)
877                 {
878                 case SDLK_ESCAPE:
879                   if(!show_menu)
880                     show_menu = true;
881                   else
882                     show_menu = false;
883                   break;
884                 case SDLK_LEFT:
885                   if(fire == DOWN)
886                     cursor_x -= KEY_CURSOR_SPEED;
887                   else
888                     cursor_x -= KEY_CURSOR_FASTSPEED;
889
890                   if(cursor_x < pos_x + MOUSE_LEFT_MARGIN)
891                     pos_x = cursor_x - MOUSE_LEFT_MARGIN;
892
893                   break;
894                 case SDLK_RIGHT:
895                   if(fire == DOWN)
896                     cursor_x += KEY_CURSOR_SPEED;
897                   else
898                     cursor_x += KEY_CURSOR_FASTSPEED;
899
900                   if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32)
901                     pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32;
902
903                   break;
904                 case SDLK_UP:
905                   if(fire == DOWN)
906                     cursor_y -= KEY_CURSOR_SPEED;
907                   else
908                     cursor_y -= KEY_CURSOR_FASTSPEED;
909
910                   if(cursor_y < 0)
911                     cursor_y = 0;
912                   break;
913                 case SDLK_DOWN:
914                   if(fire == DOWN)
915                     cursor_y += KEY_CURSOR_SPEED;
916                   else
917                     cursor_y += KEY_CURSOR_FASTSPEED;
918
919                   if(cursor_y > screen->h-32)
920                     cursor_y = screen->h-32;
921                   break;
922                 case SDLK_LCTRL:
923                   fire =UP;
924                   break;
925                 case SDLK_F1:
926                   le_showhelp();
927                   break;
928                 case SDLK_HOME:
929                   cursor_x = 0;
930                   pos_x = cursor_x;
931                   break;
932                 case SDLK_END:
933                   cursor_x = (le_current_level->width * 32) - 32;
934                   pos_x = cursor_x;
935                   break;
936                 case SDLK_F9:
937                   le_show_grid = !le_show_grid;
938                   break;
939                 default:
940                   break;
941                 }
942               break;
943             case SDL_KEYUP:     /* key released */
944               switch(event.key.keysym.sym)
945                 {
946                 case SDLK_LCTRL:
947                   fire = DOWN;
948                   break;
949                 default:
950                   break;
951                 }
952               break;
953             case SDL_MOUSEBUTTONDOWN:
954               if(event.button.button == SDL_BUTTON_LEFT)
955                 {
956                   le_mouse_pressed[LEFT] = true;
957
958                   selection.x1 = event.motion.x + pos_x;
959                   selection.y1 = event.motion.y;
960                   selection.x2 = event.motion.x + pos_x;
961                   selection.y2 = event.motion.y;
962                 }
963               else if(event.button.button == SDL_BUTTON_RIGHT)
964                 le_mouse_pressed[RIGHT] = true;
965               break;
966             case SDL_MOUSEBUTTONUP:
967               if(event.button.button == SDL_BUTTON_LEFT)
968                 le_mouse_pressed[LEFT] = false;
969               else if(event.button.button == SDL_BUTTON_RIGHT)
970                 le_mouse_pressed[RIGHT] = false;
971               break;
972             case SDL_MOUSEMOTION:
973               if(!show_menu)
974                 {
975                   x = event.motion.x;
976                   y = event.motion.y;
977
978                   cursor_x = ((int)(pos_x + x) / 32) * 32;
979                   cursor_y = ((int) y / 32) * 32;
980
981                   if(le_mouse_pressed[LEFT])
982                     {
983                       selection.x2 = x + pos_x;
984                       selection.y2 = y;
985                     }
986
987                   if(le_mouse_pressed[RIGHT])
988                     {
989                       pos_x += -1 * event.motion.xrel;
990                     }
991                 }
992               break;
993             case SDL_QUIT:      // window closed
994               done = DONE_QUIT;
995               break;
996             default:
997               break;
998             }
999         }
1000
1001       if(le_current_level != NULL)
1002         {
1003           if(event.type == SDL_KEYDOWN || event.type == SDL_KEYUP || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > screen->w-64 && event.motion.x < screen->w &&
1004               event.motion.y > 0 && event.motion.y < screen->h)))
1005             {
1006               le_mouse_pressed[LEFT] = false;
1007               le_mouse_pressed[RIGHT] = false;
1008
1009               if(show_menu == false)
1010                 {
1011                   /* Check for button events */
1012                   button_event(&le_test_level_bt,&event);
1013                   if(button_get_state(&le_test_level_bt) == BUTTON_CLICKED)
1014                     le_testlevel();
1015                   button_event(&le_save_level_bt,&event);
1016                   if(button_get_state(&le_save_level_bt) == BUTTON_CLICKED)
1017                     level_save(le_current_level,le_level_subset.name.c_str(),le_level);
1018                   button_event(&le_next_level_bt,&event);
1019                   if(button_get_state(&le_next_level_bt) == BUTTON_CLICKED)
1020                     {
1021                       if(le_level < le_level_subset.levels)
1022                         {
1023                           le_goto_level(++le_level);
1024                         }
1025                       else
1026                         {
1027                           st_level new_lev;
1028                           char str[1024];
1029                           int d = 0;
1030                           sprintf(str,"Level %d doesn't exist.",le_level+1);
1031                           text_drawf(&white_text,str,0,-18,A_HMIDDLE,A_VMIDDLE,2);
1032                           text_drawf(&white_text,"Do you want to create it?",0,0,A_HMIDDLE,A_VMIDDLE,2);
1033                           text_drawf(&red_text,"(Y)es/(N)o",0,20,A_HMIDDLE,A_VMIDDLE,2);
1034                           flipscreen();
1035                           while(d == 0)
1036                             {
1037                               while(SDL_PollEvent(&event))
1038                                 switch(event.type)
1039                                   {
1040                                   case SDL_KEYDOWN:             // key pressed
1041                                     switch(event.key.keysym.sym)
1042                                       {
1043                                       case SDLK_y:
1044                                         level_default(&new_lev);
1045                                         level_save(&new_lev,le_level_subset.name.c_str(),++le_level);
1046                                         le_level_subset.levels = le_level;
1047                                         le_goto_level(le_level);
1048                                         d = 1;
1049                                         break;
1050                                       case SDLK_n:
1051                                         d = 1;
1052                                         break;
1053                                       default:
1054                                         break;
1055                                       }
1056                                     break;
1057                                   default:
1058                                     break;
1059                                   }
1060                               SDL_Delay(50);
1061                             }
1062                         }
1063                     }
1064                   button_event(&le_previous_level_bt,&event);
1065                   if(button_get_state(&le_previous_level_bt) == BUTTON_CLICKED)
1066                     {
1067                       if(le_level > 1)
1068                         le_goto_level(--le_level);
1069                     }
1070                   button_event(&le_rubber_bt,&event);
1071                   if(button_get_state(&le_rubber_bt) == BUTTON_CLICKED)
1072                     le_current_tile = 0;
1073                   button_event(&le_select_mode_one_bt,&event);
1074                   if(button_get_state(&le_select_mode_one_bt) == BUTTON_CLICKED)
1075                     le_selection_mode = CURSOR;
1076                   button_event(&le_select_mode_two_bt,&event);
1077                   if(button_get_state(&le_select_mode_two_bt) == BUTTON_CLICKED)
1078                     le_selection_mode = SQUARE;
1079
1080                   button_event(&le_bad_bt,&event);
1081                   if(button_get_state(&le_bad_bt) == BUTTON_CLICKED)
1082                     {
1083                       le_bad_panel.hidden = false;
1084                       le_fgd_panel.hidden = true;
1085                       le_bkgd_panel.hidden = true;
1086                     }
1087
1088                   button_event(&le_fgd_bt,&event);
1089                   if(button_get_state(&le_fgd_bt) == BUTTON_CLICKED)
1090                     {
1091                       le_bad_panel.hidden = true;
1092                       le_fgd_panel.hidden = false;
1093                       le_bkgd_panel.hidden = true;
1094                     }
1095                   button_event(&le_bkgd_bt,&event);
1096                   if(button_get_state(&le_bkgd_bt) == BUTTON_CLICKED)
1097                     {
1098                       le_bad_panel.hidden = true;
1099                       le_fgd_panel.hidden = true;
1100                       le_bkgd_panel.hidden = false;
1101                     }
1102                   button_event(&le_settings_bt,&event);
1103                   if(button_get_state(&le_settings_bt) == BUTTON_CLICKED)
1104                     {
1105                       if(show_menu == false)
1106                         {
1107                           update_level_settings_menu();
1108                           Menu::set_current(level_settings_menu);
1109                           show_menu = true;
1110                         }
1111                       else
1112                         {
1113                           Menu::set_current(leveleditor_menu);
1114                           show_menu = false;
1115                         }
1116                     }
1117                   if((pbutton = button_panel_event(&le_bkgd_panel,&event)) != NULL)
1118                     {
1119                       if(button_get_state(pbutton) == BUTTON_CLICKED)
1120                         {
1121                           char c = '\0';
1122                           if(pbutton->tag >= 0 && pbutton->tag <= 3)
1123                             c = 'G' + pbutton->tag;
1124                           else if(pbutton->tag >= 4 && pbutton->tag <= 7)
1125                             c = 'g' + pbutton->tag - 4;
1126                           else if(pbutton->tag >= 8 && pbutton->tag <= 11)
1127                             c = 'C' + pbutton->tag - 8;
1128                           else if(pbutton->tag >= 12 && pbutton->tag <= 15)
1129                             c = 'c' + pbutton->tag - 12;
1130                           if(c != '\0')
1131                             le_current_tile = c;
1132                         }
1133                     }
1134                   if((pbutton = button_panel_event(&le_fgd_panel,&event)) != NULL)
1135                     {
1136                       if(button_get_state(pbutton) == BUTTON_CLICKED)
1137                         {
1138                           char c = '\0';
1139                           if(pbutton->tag == 0)
1140                             c = '#' ;
1141                           else if(pbutton->tag == 1)
1142                             c = '[';
1143                           else if(pbutton->tag == 2)
1144                             c = '=';
1145                           else if(pbutton->tag == 3)
1146                             c = ']';
1147                           else if(pbutton->tag == 4)
1148                             c = '^';
1149                           else if(pbutton->tag == 5)
1150                             c = '&';
1151                           else if(pbutton->tag == 6)
1152                             c = '|';
1153                           else if(pbutton->tag == 7)
1154                             c = '*';
1155                           else if(pbutton->tag == 8)
1156                             c = '\\';
1157                           else if(pbutton->tag == 9)
1158                             c = 'a';
1159                           else if(pbutton->tag == 10)
1160                             c = 'B';
1161                           else if(pbutton->tag == 11)
1162                             c = 'A';
1163                           else if(pbutton->tag == 12)
1164                             c = '!';
1165                           else if(pbutton->tag == 13)
1166                             c = '$';
1167                           else if(pbutton->tag == 14)
1168                             c = 'X';
1169                           else if(pbutton->tag == 15)
1170                             c = 'Y';
1171                           else if(pbutton->tag == 16)
1172                             c = 'x';
1173                           else if(pbutton->tag == 17)
1174                             c = 'y';
1175                           if(c != '\0')
1176                             le_current_tile = c;
1177                         }
1178                     }
1179                   if((pbutton = button_panel_event(&le_bad_panel,&event)) != NULL)
1180                     {
1181                       if(button_get_state(pbutton) == BUTTON_CLICKED)
1182                         {
1183                           char c = '\0';
1184                           if(pbutton->tag >= 0 && pbutton->tag <= 2)
1185                             c = '0' + pbutton->tag;
1186                           if(c != '\0')
1187                             le_current_tile = c;
1188                         }
1189                     }
1190                 }
1191               else
1192                 {
1193                   button_event(&le_settings_bt,&event);
1194                   if(button_get_state(&le_settings_bt) == BUTTON_CLICKED)
1195                     {
1196                       if(show_menu == false)
1197                         {
1198                           update_level_settings_menu();
1199                           Menu::set_current(level_settings_menu);
1200                           show_menu = true;
1201                         }
1202                       else
1203                         {
1204                           Menu::set_current(leveleditor_menu);
1205                           show_menu = false;
1206                         }
1207                     }
1208                 }
1209             }
1210           if(show_menu == false)
1211             {
1212               button_event(&le_move_left_bt,&event);
1213               button_event(&le_move_right_bt,&event);
1214
1215               if(le_mouse_pressed[LEFT])
1216                 {
1217                   le_change(cursor_x, cursor_y, TM_IA, le_current_tile);
1218                 }
1219             }
1220         }
1221     }
1222   if(show_menu == false)
1223     {
1224       if(button_get_state(&le_move_left_bt) == BUTTON_PRESSED)
1225         {
1226           pos_x -= 192;
1227         }
1228       else if(button_get_state(&le_move_left_bt) == BUTTON_HOVER)
1229         {
1230           pos_x -= 96;
1231         }
1232
1233       if(button_get_state(&le_move_right_bt) == BUTTON_PRESSED)
1234         {
1235           pos_x += 192;
1236         }
1237       else if(button_get_state(&le_move_right_bt) == BUTTON_HOVER)
1238         {
1239           pos_x += 96;
1240         }
1241     }
1242
1243 }
1244
1245 void le_highlight_selection()
1246 {
1247   int x1, x2, y1, y2;
1248
1249   if(selection.x1 < selection.x2)
1250     {
1251       x1 = selection.x1;
1252       x2 = selection.x2;
1253     }
1254   else
1255     {
1256       x1 = selection.x2;
1257       x2 = selection.x1;
1258     }
1259   if(selection.y1 < selection.y2)
1260     {
1261       y1 = selection.y1;
1262       y2 = selection.y2;
1263     }
1264   else
1265     {
1266       y1 = selection.y2;
1267       y2 = selection.y1;
1268     }
1269
1270   x1 /= 32;
1271   x2 /= 32;
1272   y1 /= 32;
1273   y2 /= 32;
1274
1275   fillrect(x1*32-pos_x, y1*32,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
1276 }
1277
1278 void le_change(float x, float y, int tm, unsigned int c)
1279 {
1280   if(le_current_level != NULL)
1281     {
1282       int xx,yy;
1283       int x1, x2, y1, y2;
1284       unsigned int i;
1285
1286       /*  level_changed = true; */
1287
1288       switch(le_selection_mode)
1289         {
1290         case CURSOR:
1291           level_change(le_current_level,x,y,tm,c);
1292
1293           yy = ((int)y / 32);
1294           xx = ((int)x / 32);
1295
1296           /* if there is a bad guy over there, remove it */
1297           for(i = 0; i < bad_guys.size(); ++i)
1298             if(xx == bad_guys[i].base.x/32 && yy == bad_guys[i].base.y/32)
1299               bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(&bad_guys[i]));
1300
1301           if(c == '0')  /* if it's a bad guy */
1302             add_bad_guy(xx*32, yy*32, BAD_BSOD);
1303           else if(c == '1')
1304             add_bad_guy(xx*32, yy*32, BAD_LAPTOP);
1305           else if(c == '2')
1306             add_bad_guy(xx*32, yy*32, BAD_MONEY);
1307
1308           break;
1309         case SQUARE:
1310           if(selection.x1 < selection.x2)
1311             {
1312               x1 = selection.x1;
1313               x2 = selection.x2;
1314             }
1315           else
1316             {
1317               x1 = selection.x2;
1318               x2 = selection.x1;
1319             }
1320           if(selection.y1 < selection.y2)
1321             {
1322               y1 = selection.y1;
1323               y2 = selection.y2;
1324             }
1325           else
1326             {
1327               y1 = selection.y2;
1328               y2 = selection.y1;
1329             }
1330
1331           x1 /= 32;
1332           x2 /= 32;
1333           y1 /= 32;
1334           y2 /= 32;
1335
1336           /* if there is a bad guy over there, remove it */
1337           for(i = 0; i < bad_guys.size(); ++i)
1338             if(bad_guys[i].base.x/32 >= x1 && bad_guys[i].base.x/32 <= x2
1339                 && bad_guys[i].base.y/32 >= y1 && bad_guys[i].base.y/32 <= y2)
1340               bad_guys.erase(static_cast<std::vector<BadGuy>::iterator>(&bad_guys[i]));
1341
1342           for(xx = x1; xx <= x2; xx++)
1343             for(yy = y1; yy <= y2; yy++)
1344               {
1345                 level_change(le_current_level, xx*32, yy*32, tm, c);
1346
1347                 if(c == '0')  // if it's a bad guy
1348                   add_bad_guy(xx*32, yy*32, BAD_BSOD);
1349                 else if(c == '1')
1350                   add_bad_guy(xx*32, yy*32, BAD_LAPTOP);
1351                 else if(c == '2')
1352                   add_bad_guy(xx*32, yy*32, BAD_MONEY);
1353               }
1354           break;
1355         default:
1356           break;
1357         }
1358     }
1359 }
1360
1361 void le_testlevel()
1362 {
1363   level_save(le_current_level,"test",le_level);
1364   gameloop("test",le_level, ST_GL_TEST);
1365   Menu::set_current(leveleditor_menu);
1366   arrays_init();
1367   level_load_gfx(le_current_level);
1368   loadshared();
1369 }
1370
1371 void le_showhelp()
1372 {
1373   SDL_Event event;
1374   unsigned int i, done;
1375   char *text[] = {
1376                    "  - This is SuperTux's built-in level editor -",
1377                    "It has been designed to be light and easy to use from the start.",
1378                    "",
1379                    "When you first load the level editor you are given a menu where you",
1380                    "can load level subsets, create a new level subset, edit the current",
1381                    "subset's settings, or simply quit the editor. You can access this menu",
1382                    "from the level editor at any time by pressing the escape key.",
1383                    "",
1384                    "To your right is your button bar. The center of this contains many",
1385                    "tiles you can use to make your level. To select a tile, click on it",
1386                    "with your left mouse button; your selection will be shown in the",
1387                    "bottom right corner of the button box. Click anywhere on your level",
1388                    "with the left mouse button to place that tile down. If you right click",
1389                    "a tile in the button bar, you can find out what its keyboard shortcut",
1390                    "is. The three buttons FGD, BGD and EMY let you pick from foreground,",
1391                    "background, and enemy tiles. The eraser lets you remove tiles.",
1392                    "The left and right arrow keys scroll back and forth through your level.",
1393                    "The button with the wrench and screwdriver, lets you change the",
1394                    "settings of your level, including how long it is or what music it will",
1395                    "play. When you are ready to give your level a test, click on the little",
1396                    "running Tux. If you like the changes you have made to your level,",
1397                    "press the red save key to keep them.",
1398                    "To change which level in your subset you are editing, press the white",
1399                    "up and down arrow keys at the top of the button box.",
1400                    "",
1401                    "Have fun making levels! If you make some good ones, send them to us on",
1402                    "the SuperTux mailing list!",
1403                    "- SuperTux team"
1404                  };
1405
1406
1407   text_drawf(&blue_text, "- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
1408
1409   for(i = 0; i < sizeof(text)/sizeof(char *); i++)
1410     text_draw(&white_small_text, text[i], 5, 80+(i*12), 1);
1411
1412   text_drawf(&gold_text, "Press Any Key to Continue", 0, 440, A_HMIDDLE, A_TOP, 1);
1413
1414   flipscreen();
1415
1416   done = 0;
1417
1418   while(done == 0)
1419     {
1420       while(SDL_PollEvent(&event))
1421         switch(event.type)
1422           {
1423           case SDL_MOUSEBUTTONDOWN:             // mouse pressed
1424           case SDL_KEYDOWN:             // key pressed
1425             done = 1;
1426             break;
1427           default:
1428             break;
1429           }
1430       SDL_Delay(50);
1431     }
1432 }