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