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