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