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