commited Matzes Win32 patch
[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_TOP, 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   unsigned 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 < bad_guys.size(); ++i)
863     {
864       /* to support frames: img_bsod_left[(frame / 5) % 4] */
865       if(bad_guys[i].kind == BAD_BSOD)
866         texture_draw(&img_bsod_left[(le_frame / 5) % 4], bad_guys[i].base.x - pos_x, bad_guys[i].base.y, NO_UPDATE);
867       else if(bad_guys[i].kind == BAD_LAPTOP)
868         texture_draw(&img_laptop_left[(le_frame / 5) % 3], bad_guys[i].base.x - pos_x, bad_guys[i].base.y, NO_UPDATE);
869       else if (bad_guys[i].kind == BAD_MONEY)
870         texture_draw(&img_money_left[(le_frame / 5) % 2], bad_guys[i].base.x - pos_x, bad_guys[i].base.y, NO_UPDATE);
871     }
872
873
874   /* Draw the player: */
875   /* for now, the position is fixed at (0, 240) */
876   texture_draw(&tux_right[(frame / 5) % 3], 0 - pos_x, 240, NO_UPDATE);
877 }
878
879 void le_checkevents()
880 {
881   SDLKey key;
882   SDLMod keymod;
883   button_type* pbutton;
884   int x,y;
885
886   keymod = SDL_GetModState();
887
888   while(SDL_PollEvent(&event))
889     {
890       /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/
891       if(event.type == SDL_KEYDOWN || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > 0 && event.motion.x < screen->w - 64 &&
892                                        event.motion.y > 0 && event.motion.y < screen->h)))
893         {
894
895           switch(event.type)
896             {
897             case SDL_KEYDOWN:   // key pressed
898               key = event.key.keysym.sym;
899               if(show_menu)
900                 {
901                   menu_event(&event.key.keysym);
902                   if(key == SDLK_ESCAPE)
903                     {
904                       show_menu = NO;
905                       menu_set_current(&leveleditor_menu);
906                     }
907                   break;
908                 }
909               switch(key)
910                 {
911                 case SDLK_ESCAPE:
912                   if(!show_menu)
913                     show_menu = YES;
914                   else
915                     show_menu = NO;
916                   break;
917                 case SDLK_LEFT:
918                   if(fire == DOWN)
919                     cursor_x -= KEY_CURSOR_SPEED;
920                   else
921                     cursor_x -= KEY_CURSOR_FASTSPEED;
922
923                   if(cursor_x < pos_x + MOUSE_LEFT_MARGIN)
924                     pos_x = cursor_x - MOUSE_LEFT_MARGIN;
925
926                   break;
927                 case SDLK_RIGHT:
928                   if(fire == DOWN)
929                     cursor_x += KEY_CURSOR_SPEED;
930                   else
931                     cursor_x += KEY_CURSOR_FASTSPEED;
932
933                   if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32)
934                     pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32;
935
936                   break;
937                 case SDLK_UP:
938                   if(fire == DOWN)
939                     cursor_y -= KEY_CURSOR_SPEED;
940                   else
941                     cursor_y -= KEY_CURSOR_FASTSPEED;
942
943                   if(cursor_y < 0)
944                     cursor_y = 0;
945                   break;
946                 case SDLK_DOWN:
947                   if(fire == DOWN)
948                     cursor_y += KEY_CURSOR_SPEED;
949                   else
950                     cursor_y += KEY_CURSOR_FASTSPEED;
951
952                   if(cursor_y > screen->h-32)
953                     cursor_y = screen->h-32;
954                   break;
955                 case SDLK_LCTRL:
956                   fire =UP;
957                   break;
958                 case SDLK_F1:
959                   le_showhelp();
960                   break;
961                 case SDLK_HOME:
962                   cursor_x = 0;
963                   pos_x = cursor_x;
964                   break;
965                 case SDLK_END:
966                   cursor_x = (le_current_level->width * 32) - 32;
967                   pos_x = cursor_x;
968                   break;
969                 case SDLK_F9:
970                   le_show_grid = !le_show_grid;
971                   break;
972                 default:
973                   break;
974                 }
975               break;
976             case SDL_KEYUP:     /* key released */
977               switch(event.key.keysym.sym)
978                 {
979                 case SDLK_LCTRL:
980                   fire = DOWN;
981                   break;
982                 default:
983                   break;
984                 }
985               break;
986             case SDL_MOUSEBUTTONDOWN:
987               if(event.button.button == SDL_BUTTON_LEFT)
988                 {
989                   le_mouse_pressed[LEFT] = YES;
990
991                   selection.x1 = event.motion.x + pos_x;
992                   selection.y1 = event.motion.y;
993                   selection.x2 = event.motion.x + pos_x;
994                   selection.y2 = event.motion.y;
995                 }
996               else if(event.button.button == SDL_BUTTON_RIGHT)
997                 le_mouse_pressed[RIGHT] = YES;
998               break;
999             case SDL_MOUSEBUTTONUP:
1000               if(event.button.button == SDL_BUTTON_LEFT)
1001                 le_mouse_pressed[LEFT] = NO;
1002               else if(event.button.button == SDL_BUTTON_RIGHT)
1003                 le_mouse_pressed[RIGHT] = NO;
1004               break;
1005             case SDL_MOUSEMOTION:
1006               if(!show_menu)
1007                 {
1008                   x = event.motion.x;
1009                   y = event.motion.y;
1010
1011                   cursor_x = ((int)(pos_x + x) / 32) * 32;
1012                   cursor_y = ((int) y / 32) * 32;
1013
1014                   if(le_mouse_pressed[LEFT] == YES)
1015                     {
1016                       selection.x2 = x + pos_x;
1017                       selection.y2 = y;
1018                     }
1019
1020                   if(le_mouse_pressed[RIGHT] == YES)
1021                     {
1022                       pos_x += -1 * event.motion.xrel;
1023                     }
1024                 }
1025               break;
1026             case SDL_QUIT:      // window closed
1027               done = DONE_QUIT;
1028               break;
1029             default:
1030               break;
1031             }
1032         }
1033
1034       if(le_current_level != NULL)
1035         {
1036           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 &&
1037               event.motion.y > 0 && event.motion.y < screen->h)))
1038             {
1039               le_mouse_pressed[LEFT] = NO;
1040               le_mouse_pressed[RIGHT] = NO;
1041
1042               if(show_menu == NO)
1043                 {
1044                   /* Check for button events */
1045                   button_event(&le_test_level_bt,&event);
1046                   if(button_get_state(&le_test_level_bt) == BUTTON_CLICKED)
1047                     le_testlevel();
1048                   button_event(&le_save_level_bt,&event);
1049                   if(button_get_state(&le_save_level_bt) == BUTTON_CLICKED)
1050                     level_save(le_current_level,le_level_subset.name.c_str(),le_level);
1051                   button_event(&le_next_level_bt,&event);
1052                   if(button_get_state(&le_next_level_bt) == BUTTON_CLICKED)
1053                     {
1054                       if(le_level < le_level_subset.levels)
1055                         {
1056                           le_goto_level(++le_level);
1057                         }
1058                       else
1059                         {
1060                           st_level new_lev;
1061                           char str[1024];
1062                           int d = 0;
1063                           sprintf(str,"Level %d doesn't exist.",le_level+1);
1064                           text_drawf(&white_text,str,0,-18,A_HMIDDLE,A_VMIDDLE,2,NO_UPDATE);
1065                           text_drawf(&white_text,"Do you want to create it?",0,0,A_HMIDDLE,A_VMIDDLE,2,NO_UPDATE);
1066                           text_drawf(&red_text,"(Y)es/(N)o",0,20,A_HMIDDLE,A_VMIDDLE,2,NO_UPDATE);
1067                           flipscreen();
1068                           while(d == 0)
1069                             {
1070                               while(SDL_PollEvent(&event))
1071                                 switch(event.type)
1072                                   {
1073                                   case SDL_KEYDOWN:             // key pressed
1074                                     switch(event.key.keysym.sym)
1075                                       {
1076                                       case SDLK_y:
1077                                         level_default(&new_lev);
1078                                         level_save(&new_lev,le_level_subset.name.c_str(),++le_level);
1079                                         le_level_subset.levels = le_level;
1080                                         le_goto_level(le_level);
1081                                         d = 1;
1082                                         break;
1083                                       case SDLK_n:
1084                                         d = 1;
1085                                         break;
1086                                       default:
1087                                         break;
1088                                       }
1089                                     break;
1090                                   default:
1091                                     break;
1092                                   }
1093                               SDL_Delay(50);
1094                             }
1095                         }
1096                     }
1097                   button_event(&le_previous_level_bt,&event);
1098                   if(button_get_state(&le_previous_level_bt) == BUTTON_CLICKED)
1099                     {
1100                       if(le_level > 1)
1101                         le_goto_level(--le_level);
1102                     }
1103                   button_event(&le_rubber_bt,&event);
1104                   if(button_get_state(&le_rubber_bt) == BUTTON_CLICKED)
1105                     le_current_tile = '.';
1106                   button_event(&le_select_mode_one_bt,&event);
1107                   if(button_get_state(&le_select_mode_one_bt) == BUTTON_CLICKED)
1108                     le_selection_mode = CURSOR;
1109                   button_event(&le_select_mode_two_bt,&event);
1110                   if(button_get_state(&le_select_mode_two_bt) == BUTTON_CLICKED)
1111                     le_selection_mode = SQUARE;
1112
1113                   button_event(&le_bad_bt,&event);
1114                   if(button_get_state(&le_bad_bt) == BUTTON_CLICKED)
1115                     {
1116                       le_bad_panel.hidden = NO;
1117                       le_fgd_panel.hidden = YES;
1118                       le_bkgd_panel.hidden = YES;
1119                     }
1120
1121                   button_event(&le_fgd_bt,&event);
1122                   if(button_get_state(&le_fgd_bt) == BUTTON_CLICKED)
1123                     {
1124                       le_bad_panel.hidden = YES;
1125                       le_fgd_panel.hidden = NO;
1126                       le_bkgd_panel.hidden = YES;
1127                     }
1128                   button_event(&le_bkgd_bt,&event);
1129                   if(button_get_state(&le_bkgd_bt) == BUTTON_CLICKED)
1130                     {
1131                       le_bad_panel.hidden = YES;
1132                       le_fgd_panel.hidden = YES;
1133                       le_bkgd_panel.hidden = NO;
1134                     }
1135                   button_event(&le_settings_bt,&event);
1136                   if(button_get_state(&le_settings_bt) == BUTTON_CLICKED)
1137                     {
1138                       if(show_menu == NO)
1139                         {
1140                           update_level_settings_menu();
1141                           menu_set_current(&level_settings_menu);
1142                           show_menu = YES;
1143                         }
1144                       else
1145                         {
1146                           menu_set_current(&leveleditor_menu);
1147                           show_menu = NO;
1148                         }
1149                     }
1150                   if((pbutton = button_panel_event(&le_bkgd_panel,&event)) != NULL)
1151                     {
1152                       if(button_get_state(pbutton) == BUTTON_CLICKED)
1153                         {
1154                           char c = '\0';
1155                           if(pbutton->tag >= 0 && pbutton->tag <= 3)
1156                             c = 'G' + pbutton->tag;
1157                           else if(pbutton->tag >= 4 && pbutton->tag <= 7)
1158                             c = 'g' + pbutton->tag - 4;
1159                           else if(pbutton->tag >= 8 && pbutton->tag <= 11)
1160                             c = 'C' + pbutton->tag - 8;
1161                           else if(pbutton->tag >= 12 && pbutton->tag <= 15)
1162                             c = 'c' + pbutton->tag - 12;
1163                           if(c != '\0')
1164                             le_current_tile = c;
1165                         }
1166                     }
1167                   if((pbutton = button_panel_event(&le_fgd_panel,&event)) != NULL)
1168                     {
1169                       if(button_get_state(pbutton) == BUTTON_CLICKED)
1170                         {
1171                           char c = '\0';
1172                           if(pbutton->tag == 0)
1173                             c = '#' ;
1174                           else if(pbutton->tag == 1)
1175                             c = '[';
1176                           else if(pbutton->tag == 2)
1177                             c = '=';
1178                           else if(pbutton->tag == 3)
1179                             c = ']';
1180                           else if(pbutton->tag == 4)
1181                             c = '^';
1182                           else if(pbutton->tag == 5)
1183                             c = '&';
1184                           else if(pbutton->tag == 6)
1185                             c = '|';
1186                           else if(pbutton->tag == 7)
1187                             c = '*';
1188                           else if(pbutton->tag == 8)
1189                             c = '\\';
1190                           else if(pbutton->tag == 9)
1191                             c = 'a';
1192                           else if(pbutton->tag == 10)
1193                             c = 'B';
1194                           else if(pbutton->tag == 11)
1195                             c = 'A';
1196                           else if(pbutton->tag == 12)
1197                             c = '!';
1198                           else if(pbutton->tag == 13)
1199                             c = '$';
1200                           else if(pbutton->tag == 14)
1201                             c = 'X';
1202                           else if(pbutton->tag == 15)
1203                             c = 'Y';
1204                           else if(pbutton->tag == 16)
1205                             c = 'x';
1206                           else if(pbutton->tag == 17)
1207                             c = 'y';
1208                           if(c != '\0')
1209                             le_current_tile = c;
1210                         }
1211                     }
1212                   if((pbutton = button_panel_event(&le_bad_panel,&event)) != NULL)
1213                     {
1214                       if(button_get_state(pbutton) == BUTTON_CLICKED)
1215                         {
1216                           char c = '\0';
1217                           if(pbutton->tag >= 0 && pbutton->tag <= 2)
1218                             c = '0' + pbutton->tag;
1219                           if(c != '\0')
1220                             le_current_tile = c;
1221                         }
1222                     }
1223                 }
1224               else
1225                 {
1226                   button_event(&le_settings_bt,&event);
1227                   if(button_get_state(&le_settings_bt) == BUTTON_CLICKED)
1228                     {
1229                       if(show_menu == NO)
1230                         {
1231                           update_level_settings_menu();
1232                           menu_set_current(&level_settings_menu);
1233                           show_menu = YES;
1234                         }
1235                       else
1236                         {
1237                           menu_set_current(&leveleditor_menu);
1238                           show_menu = NO;
1239                         }
1240                     }
1241                 }
1242             }
1243           if(show_menu == NO)
1244             {
1245               button_event(&le_move_left_bt,&event);
1246               button_event(&le_move_right_bt,&event);
1247
1248               if(le_mouse_pressed[LEFT])
1249                 {
1250                   le_change(cursor_x, cursor_y, le_current_tile);
1251                 }
1252             }
1253         }
1254     }
1255   if(show_menu == NO)
1256     {
1257       if(button_get_state(&le_move_left_bt) == BUTTON_PRESSED)
1258         {
1259           pos_x -= 192;
1260         }
1261       else if(button_get_state(&le_move_left_bt) == BUTTON_HOVER)
1262         {
1263           pos_x -= 96;
1264         }
1265
1266       if(button_get_state(&le_move_right_bt) == BUTTON_PRESSED)
1267         {
1268           pos_x += 192;
1269         }
1270       else if(button_get_state(&le_move_right_bt) == BUTTON_HOVER)
1271         {
1272           pos_x += 96;
1273         }
1274     }
1275
1276 }
1277
1278 void le_highlight_selection()
1279 {
1280   int x1, x2, y1, y2;
1281
1282   if(selection.x1 < selection.x2)
1283     {
1284       x1 = selection.x1;
1285       x2 = selection.x2;
1286     }
1287   else
1288     {
1289       x1 = selection.x2;
1290       x2 = selection.x1;
1291     }
1292   if(selection.y1 < selection.y2)
1293     {
1294       y1 = selection.y1;
1295       y2 = selection.y2;
1296     }
1297   else
1298     {
1299       y1 = selection.y2;
1300       y2 = selection.y1;
1301     }
1302
1303   x1 /= 32;
1304   x2 /= 32;
1305   y1 /= 32;
1306   y2 /= 32;
1307
1308   fillrect(x1*32-pos_x, y1*32,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
1309 }
1310
1311 void le_change(float x, float y, unsigned char c)
1312 {
1313   if(le_current_level != NULL)
1314     {
1315       int xx,yy;
1316       int x1, x2, y1, y2;
1317       unsigned int i;
1318
1319       /*  level_changed = YES; */
1320
1321       switch(le_selection_mode)
1322         {
1323         case CURSOR:
1324           level_change(le_current_level,x,y,c);
1325
1326           yy = ((int)y / 32);
1327           xx = ((int)x / 32);
1328
1329           /* if there is a bad guy over there, remove it */
1330           for(i = 0; i < bad_guys.size(); ++i)
1331               if(xx == bad_guys[i].base.x/32 && yy == bad_guys[i].base.y/32)
1332                   bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(&bad_guys[i]));
1333
1334           if(c == '0')  /* if it's a bad guy */
1335             add_bad_guy(xx*32, yy*32, BAD_BSOD);
1336           else if(c == '1')
1337             add_bad_guy(xx*32, yy*32, BAD_LAPTOP);
1338           else if(c == '2')
1339             add_bad_guy(xx*32, yy*32, BAD_MONEY);
1340
1341           break;
1342         case SQUARE:
1343           if(selection.x1 < selection.x2)
1344             {
1345               x1 = selection.x1;
1346               x2 = selection.x2;
1347             }
1348           else
1349             {
1350               x1 = selection.x2;
1351               x2 = selection.x1;
1352             }
1353           if(selection.y1 < selection.y2)
1354             {
1355               y1 = selection.y1;
1356               y2 = selection.y2;
1357             }
1358           else
1359             {
1360               y1 = selection.y2;
1361               y2 = selection.y1;
1362             }
1363
1364           x1 /= 32;
1365           x2 /= 32;
1366           y1 /= 32;
1367           y2 /= 32;
1368
1369           /* if there is a bad guy over there, remove it */
1370           for(i = 0; i < bad_guys.size(); ++i)
1371               if(bad_guys[i].base.x/32 >= x1 && bad_guys[i].base.x/32 <= x2
1372                   && bad_guys[i].base.y/32 >= y1 && bad_guys[i].base.y/32 <= y2)
1373                   bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(&bad_guys[i]));
1374
1375           for(xx = x1; xx <= x2; xx++)
1376             for(yy = y1; yy <= y2; yy++)
1377               {
1378                 level_change(le_current_level, xx*32, yy*32, c);
1379
1380                 if(c == '0')  // if it's a bad guy
1381                   add_bad_guy(xx*32, yy*32, BAD_BSOD);
1382                 else if(c == '1')
1383                   add_bad_guy(xx*32, yy*32, BAD_LAPTOP);
1384                 else if(c == '2')
1385                   add_bad_guy(xx*32, yy*32, BAD_MONEY);
1386               }
1387           break;
1388         default:
1389           break;
1390         }
1391     }
1392 }
1393
1394 void le_testlevel()
1395 {
1396   level_save(le_current_level,"test",le_level);
1397   gameloop("test",le_level, ST_GL_TEST);
1398   menu_set_current(&leveleditor_menu);
1399   arrays_init();
1400   level_load_gfx(le_current_level);
1401   loadshared();
1402   le_activate_bad_guys();
1403 }
1404
1405 void le_showhelp()
1406 {
1407   SDL_Event event;
1408   unsigned int i, done;
1409   char *text[] = {
1410                    "  - This is SuperTux's built-in level editor -",
1411                    "It has been designed to be light and easy to use from the start.",
1412                    "",
1413                    "When you first load the level editor you are given a menu where you",
1414                    "can load level subsets, create a new level subset, edit the current",
1415                    "subset's settings, or simply quit the editor. You can access this menu",
1416                    "from the level editor at any time by pressing the escape key.",
1417                    "",
1418                    "To your right is your button bar. The center of this contains many",
1419                    "tiles you can use to make your level. To select a tile, click on it",
1420                    "with your left mouse button; your selection will be shown in the",
1421                    "bottom right corner of the button box. Click anywhere on your level",
1422                    "with the left mouse button to place that tile down. If you right click",
1423                    "a tile in the button bar, you can find out what its keyboard shortcut",
1424                    "is. The three buttons FGD, BGD and EMY let you pick from foreground,",
1425                    "background, and enemy tiles. The eraser lets you remove tiles.",
1426                    "The left and right arrow keys scroll back and forth through your level.",
1427                    "The button with the wrench and screwdriver, lets you change the",
1428                    "settings of your level, including how long it is or what music it will",
1429                    "play. When you are ready to give your level a test, click on the little",
1430                    "running Tux. If you like the changes you have made to your level,",
1431                                    "press the red save key to keep them.",
1432                    "To change which level in your subset you are editing, press the white",
1433                    "up and down arrow keys at the top of the button box.",
1434                                    "",
1435                    "Have fun making levels! If you make some good ones, send them to us on",
1436                                    "the SuperTux mailing list!",
1437                    "- SuperTux team"
1438                  };
1439
1440
1441   text_drawf(&blue_text, "- Help -", 0, 30, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
1442
1443   for(i = 0; i < sizeof(text)/sizeof(char *); i++)
1444     text_draw(&white_small_text, text[i], 5, 80+(i*12), 1, NO_UPDATE);
1445
1446   text_drawf(&gold_text, "Press Any Key to Continue", 0, 440, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1447
1448   flipscreen();
1449
1450   done = 0;
1451
1452   while(done == 0)
1453     {
1454       while(SDL_PollEvent(&event))
1455         switch(event.type)
1456           {
1457           case SDL_MOUSEBUTTONDOWN:             // mouse pressed
1458           case SDL_KEYDOWN:             // key pressed
1459             done = 1;
1460             break;
1461           default:
1462             break;
1463           }
1464       SDL_Delay(50);
1465     }
1466 }