4 // Copyright (C) 2003 Ricardo Cruz <rick2@aeiou.pt>
5 // Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include <SDL_image.h>
30 #include "leveleditor.h"
43 #include "resources.h"
44 #include "music_manager.h"
46 /* definitions to aid development */
48 /* definitions that affect gameplay */
49 #define KEY_CURSOR_SPEED 32
50 #define KEY_CURSOR_FASTSPEED 64
52 /* when pagedown/up pressed speed:*/
53 #define PAGE_CURSOR_SPEED 13*32
55 #define MOUSE_LEFT_MARGIN 80
56 #define MOUSE_RIGHT_MARGIN (560-32)
57 /* right_margin should noticed that the cursor is 32 pixels,
58 so it should subtract that value */
59 #define MOUSE_POS_SPEED 20
62 #define SELECT_W 2 // size of the selections lines
63 #define SELECT_CLR 0, 255, 0, 255 // lines color (R, G, B, A)
65 /* own declerations */
66 /* crutial ones (main loop) */
69 int le_load_level(char *filename);
71 void le_drawinterface();
72 void le_checkevents();
73 void le_change(float x, float y, int tm, unsigned int c);
76 void le_set_defaults(void);
77 void le_activate_bad_guys(void);
79 void le_highlight_selection();
81 void apply_level_settings_menu();
82 void update_subset_settings_menu();
83 void save_subset_settings_menu();
87 TileOrObject() : tile(0), obj(NULL) { is_tile = true; };
89 void Tile(unsigned int set_to) { tile = set_to; is_tile = true; }
90 void Object(GameObject* pobj) { obj = pobj; is_tile = false; }
91 //Returns true for a tile
92 bool IsTile() { return is_tile; };
93 //Returns true for a GameObject
94 bool IsObject() { return !is_tile; };
95 void Init() { tile = 0; obj = NULL; is_tile = true; };
97 bool is_tile; //true for tile (false for object)
102 /* leveleditor internals */
103 static string_list_type level_subsets;
104 static bool le_level_changed; /* if changes, ask for saving, when quiting*/
105 static bool show_minimap;
106 static bool le_help_shown;
107 static int pos_x, cursor_x, cursor_y, fire;
109 static World* le_world;
110 static LevelSubset* le_level_subset;
111 static int le_show_grid;
113 static Surface* le_selection;
115 static TileOrObject le_current;
116 static bool le_mouse_pressed[2];
117 static bool le_mouse_clicked[2];
118 static Button* le_save_level_bt;
119 static Button* le_exit_bt;
120 static Button* le_test_level_bt;
121 static Button* le_next_level_bt;
122 static Button* le_previous_level_bt;
123 static Button* le_move_right_bt;
124 static Button* le_move_left_bt;
125 static Button* le_rubber_bt;
126 static Button* le_select_mode_one_bt;
127 static Button* le_select_mode_two_bt;
128 static Button* le_settings_bt;
129 static Button* le_tilegroup_bt;
130 static Button* le_objects_bt;
131 static ButtonPanel* le_tilemap_panel;
132 static Menu* leveleditor_menu;
133 static Menu* subset_load_menu;
134 static Menu* subset_new_menu;
135 static Menu* subset_settings_menu;
136 static Menu* level_settings_menu;
137 static Menu* select_tilegroup_menu;
138 static Menu* select_objects_menu;
139 static Timer select_tilegroup_menu_effect;
140 static Timer select_objects_menu_effect;
141 typedef std::map<std::string, ButtonPanel*> ButtonPanelMap;
142 static ButtonPanelMap tilegroups_map;
143 static ButtonPanelMap objects_map;
144 static std::string cur_tilegroup;
145 static std::string cur_objects;
147 static square selection;
148 static int le_selection_mode;
149 static SDL_Event event;
150 TileMapType active_tm;
152 int leveleditor(char* filename)
154 int last_time, now_time, i;
163 clearscreen(0, 0, 0);
166 music_manager->halt_music();
168 while (SDL_PollEvent(&event))
172 if(le_load_level(filename))
177 last_time = SDL_GetTicks();
182 if(Menu::current() == select_tilegroup_menu)
184 if(select_tilegroup_menu_effect.check())
186 select_tilegroup_menu->set_pos(screen->w - 64 + select_tilegroup_menu_effect.get_left(),
190 select_tilegroup_menu->set_pos(screen->w - 64,66,-0.5,0.5);
192 else if(Menu::current() == select_objects_menu)
194 if(select_objects_menu_effect.check())
196 select_objects_menu->set_pos(screen->w - 64 + select_objects_menu_effect.get_left(),82,-0.5,0.5);
199 select_objects_menu->set_pos(screen->w - 64,82,-0.5,0.5);
204 /* making events results to be in order */
207 if(pos_x > (le_world->get_level()->width * 32) - screen->w)
208 pos_x = (le_world->get_level()->width * 32) - screen->w;
214 clearscreen(0, 0, 0);
216 /* draw editor interface */
219 Menu* menu = Menu::current();
225 if(menu == leveleditor_menu)
227 switch (leveleditor_menu->check())
229 case MNID_RETURNLEVELEDITOR:
231 Menu::set_current(0);
233 Menu::set_current(leveleditor_menu);
235 case MNID_SUBSETSETTINGS:
236 update_subset_settings_menu();
238 case MNID_QUITLEVELEDITOR:
243 else if(menu == level_settings_menu)
245 switch (level_settings_menu->check())
248 apply_level_settings_menu();
249 Menu::set_current(NULL);
256 else if(menu == select_tilegroup_menu)
259 switch (it = select_tilegroup_menu->check())
264 cur_tilegroup = select_tilegroup_menu->get_item_by_id(it).text;
265 Menu::set_current(0);
272 else if(menu == select_objects_menu)
275 switch (it = select_objects_menu->check())
280 cur_objects = select_objects_menu->get_item_by_id(it).text;
283 Menu::set_current(0);
288 else if(menu == subset_load_menu)
290 switch (i = subset_load_menu->check())
297 if(le_load_level(level_subsets.item[i-1]))
303 else if(menu == subset_new_menu)
305 if(subset_new_menu->item[2].input[0] == '\0')
306 subset_new_menu->item[3].kind = MN_DEACTIVE;
309 subset_new_menu->item[3].kind = MN_ACTION;
311 switch (i = subset_new_menu->check())
313 case MNID_CREATESUBSET:
314 LevelSubset::create(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
315 le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
316 leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
318 le_world = new World(le_level_subset->name,1);
319 subset_new_menu->get_item_by_id(MNID_SUBSETNAME).change_input("");
321 Menu::set_current(subset_settings_menu);
326 else if(menu == subset_settings_menu)
328 if(le_level_subset->title.compare(subset_settings_menu->get_item_by_id(MNID_SUBSETTITLE).input) == 0 && le_level_subset->description.compare(subset_settings_menu->get_item_by_id(MNID_SUBSETDESCRIPTION).input) == 0 )
329 subset_settings_menu->get_item_by_id(MNID_SUBSETSAVECHANGES).kind = MN_DEACTIVE;
331 subset_settings_menu->get_item_by_id(MNID_SUBSETSAVECHANGES).kind = MN_ACTION;
333 switch (i = subset_settings_menu->check())
335 case MNID_SUBSETSAVECHANGES:
336 save_subset_settings_menu();
337 Menu::set_current(leveleditor_menu);
343 mouse_cursor->draw();
351 ++global_frame_counter;
354 now_time = SDL_GetTicks();
355 if (now_time < last_time + FPS)
356 SDL_Delay(last_time + FPS - now_time); /* delay some time */
364 int le_load_level(char *filename)
366 le_level_subset->load(filename);
367 leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
370 le_world = new World(filename,le_level);
372 //GameSession* session = new GameSession(datadir + "/levels/" + le_level_subset->name + "/level1.stl", 0, ST_GL_DEMO_GAME);
374 Menu::set_current(NULL);
383 leveleditor_menu = new Menu();
384 subset_load_menu = new Menu();
385 subset_new_menu = new Menu();
386 subset_settings_menu = new Menu();
387 level_settings_menu = new Menu();
388 select_tilegroup_menu = new Menu();
389 select_objects_menu = new Menu();
391 leveleditor_menu->additem(MN_LABEL,"Level Editor Menu",0,0);
392 leveleditor_menu->additem(MN_HL,"",0,0);
393 leveleditor_menu->additem(MN_ACTION,"Return To Level Editor",0,0,MNID_RETURNLEVELEDITOR);
394 leveleditor_menu->additem(MN_DEACTIVE,"Level Subset Settings",0,subset_settings_menu,MNID_SUBSETSETTINGS);
395 leveleditor_menu->additem(MN_GOTO,"Load Level Subset",0,subset_load_menu);
396 leveleditor_menu->additem(MN_GOTO,"New Level Subset",0,subset_new_menu);
397 leveleditor_menu->additem(MN_HL,"",0,0);
398 leveleditor_menu->additem(MN_ACTION,"Quit Level Editor",0,0,MNID_QUITLEVELEDITOR);
400 Menu::set_current(leveleditor_menu);
402 subset_load_menu->additem(MN_LABEL, "Load Level Subset", 0, 0);
403 subset_load_menu->additem(MN_HL, "", 0, 0);
405 for(i = 0; i < level_subsets.num_items; ++i)
407 subset_load_menu->additem(MN_ACTION,level_subsets.item[i],0,0, i+1);
409 subset_load_menu->additem(MN_HL,"",0,0);
410 subset_load_menu->additem(MN_BACK,"Back",0,0);
412 subset_new_menu->additem(MN_LABEL,"New Level Subset",0,0);
413 subset_new_menu->additem(MN_HL,"",0,0);
414 subset_new_menu->additem(MN_TEXTFIELD,"Enter Name",0,0,MNID_SUBSETNAME);
415 subset_new_menu->additem(MN_ACTION,"Create",0,0, MNID_CREATESUBSET);
416 subset_new_menu->additem(MN_HL,"",0,0);
417 subset_new_menu->additem(MN_BACK,"Back",0,0);
419 subset_settings_menu->additem(MN_LABEL,"Level Subset Settings",0,0);
420 subset_settings_menu->additem(MN_HL,"",0,0);
421 subset_settings_menu->additem(MN_TEXTFIELD,"Title",0,0,MNID_SUBSETTITLE);
422 subset_settings_menu->additem(MN_TEXTFIELD,"Description",0,0,MNID_SUBSETDESCRIPTION);
423 subset_settings_menu->additem(MN_HL,"",0,0);
424 subset_settings_menu->additem(MN_ACTION,"Save Changes",0,0,MNID_SUBSETSAVECHANGES);
425 subset_settings_menu->additem(MN_HL,"",0,0);
426 subset_settings_menu->additem(MN_BACK,"Back",0,0);
428 level_settings_menu->arrange_left = true;
429 level_settings_menu->additem(MN_LABEL,"Level Settings",0,0);
430 level_settings_menu->additem(MN_HL,"",0,0);
431 level_settings_menu->additem(MN_TEXTFIELD, "Name ",0,0,MNID_NAME);
432 level_settings_menu->additem(MN_TEXTFIELD, "Author ",0,0,MNID_AUTHOR);
433 level_settings_menu->additem(MN_STRINGSELECT,"Song ",0,0,MNID_SONG);
434 level_settings_menu->additem(MN_STRINGSELECT,"Bg-Image",0,0,MNID_BGIMG);
435 level_settings_menu->additem(MN_STRINGSELECT,"Particle",0,0,MNID_PARTICLE);
436 level_settings_menu->additem(MN_NUMFIELD, "Length ",0,0,MNID_LENGTH);
437 level_settings_menu->additem(MN_NUMFIELD, "Time ",0,0,MNID_TIME);
438 level_settings_menu->additem(MN_NUMFIELD, "Gravity ",0,0,MNID_GRAVITY);
439 level_settings_menu->additem(MN_NUMFIELD, "Bg-Img-Speed",0,0,MNID_BGSPEED);
440 level_settings_menu->additem(MN_NUMFIELD, "Top Red ",0,0,MNID_TopRed);
441 level_settings_menu->additem(MN_NUMFIELD, "Top Green ",0,0,MNID_TopGreen);
442 level_settings_menu->additem(MN_NUMFIELD, "Top Blue ",0,0,MNID_TopBlue);
443 level_settings_menu->additem(MN_NUMFIELD, "Bottom Red ",0,0,MNID_BottomRed);
444 level_settings_menu->additem(MN_NUMFIELD, "Bottom Green",0,0,MNID_BottomGreen);
445 level_settings_menu->additem(MN_NUMFIELD, "Bottom Blue",0,0,MNID_BottomBlue);
446 level_settings_menu->additem(MN_HL,"",0,0);
447 level_settings_menu->additem(MN_ACTION,"Apply Changes",0,0,MNID_APPLY);
449 select_tilegroup_menu->arrange_left = true;
450 select_tilegroup_menu->additem(MN_LABEL,"Tilegroup",0,0);
451 select_tilegroup_menu->additem(MN_HL,"",0,0);
452 select_tilegroup_menu->additem(MN_ACTION,"asd",0,0);
453 std::set<TileGroup>* tilegroups = TileManager::tilegroups();
455 for(std::set<TileGroup>::iterator it = tilegroups->begin();
456 it != tilegroups->end(); ++it )
458 select_tilegroup_menu->additem(MN_ACTION, it->name, 0, 0, tileid);
460 tilegroups_map[(*it).name] = new ButtonPanel(screen->w - 64,96, 64, 318);
463 for(std::vector<int>::const_iterator sit = (*it).tiles.begin();
464 sit != (*it).tiles.end(); ++sit, ++i)
466 std::string imagefile = "/images/tilesets/" ;
467 bool only_editor_image = false;
468 if(!TileManager::instance()->get(*sit)->filenames.empty())
470 imagefile += TileManager::instance()->get(*sit)->filenames[0];
472 else if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
474 imagefile += TileManager::instance()->get(*sit)->editor_filenames[0];
475 only_editor_image = true;
479 imagefile += "notile.png";
481 Button* button = new Button(imagefile, it->name, SDLKey(SDLK_a + i),
483 if(!only_editor_image)
484 if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
486 imagefile = "/images/tilesets/" + TileManager::instance()->get(*sit)->editor_filenames[0];
487 button->add_icon(imagefile,32,32);
489 tilegroups_map[it->name]->additem(button, *sit);
492 select_tilegroup_menu->additem(MN_HL,"",0,0);
494 select_objects_menu->arrange_left = true;
495 select_objects_menu->additem(MN_LABEL,"Objects",0,0);
496 select_objects_menu->additem(MN_HL,"",0,0);
497 select_objects_menu->additem(MN_ACTION,"BadGuys",0,0,1);
498 objects_map["BadGuys"] = new ButtonPanel(screen->w - 64,96, 64, 318);
500 for(int i = 0; i < NUM_BadGuyKinds; ++i)
502 BadGuy bad_tmp(0,0,BadGuyKind(i),false);
503 objects_map["BadGuys"]->additem(new Button("", "BadGuy",(SDLKey)(i+'a'),0,0,32,32),1000000+i);
504 objects_map["BadGuys"]->manipulate_button(i)->set_game_object(new BadGuy(objects_map["BadGuys"]->manipulate_button(i)->get_pos().x,objects_map["BadGuys"]->manipulate_button(i)->get_pos().y,BadGuyKind(i),false));
507 select_objects_menu->additem(MN_HL,"",0,0);
515 level_subsets = dsubdirs("/levels", "level1.stl");
516 le_level_subset = new LevelSubset;
526 le_frame = 0; /* support for frames in some tiles, like waves and bad guys */
527 le_level_changed = false;
528 le_help_shown = false;
530 le_mouse_pressed[LEFT] = false;
531 le_mouse_pressed[RIGHT] = false;
533 le_mouse_clicked[LEFT] = false;
534 le_mouse_clicked[RIGHT] = false;
536 le_selection = new Surface(datadir + "/images/leveleditor/select.png", USE_ALPHA);
538 select_tilegroup_menu_effect.init(false);
539 select_objects_menu_effect.init(false);
542 le_save_level_bt = new Button("/images/icons/save.png","Save level", SDLK_F6,screen->w-64,32);
543 le_exit_bt = new Button("/images/icons/exit.png","Exit", SDLK_F6,screen->w-32,32);
544 le_next_level_bt = new Button("/images/icons/up.png","Next level", SDLK_PAGEUP,screen->w-64,0);
545 le_previous_level_bt = new Button("/images/icons/down.png","Previous level",SDLK_PAGEDOWN,screen->w-32,0);
546 le_rubber_bt = new Button("/images/icons/rubber.png","Rubber",SDLK_DELETE,screen->w-32,48);
547 le_select_mode_one_bt = new Button ("/images/icons/select-mode1.png","Select single tile",SDLK_F3,screen->w-64,48);
548 le_select_mode_two_bt = new Button("/images/icons/select-mode2.png","Select multiple tiles",SDLK_F3,screen->w-64,48);
549 le_test_level_bt = new Button("/images/icons/test-level.png","Test level",SDLK_F4,screen->w-64,screen->h - 64);
550 le_settings_bt = new Button("/images/icons/settings.png","Level settings",SDLK_F5,screen->w-32,screen->h - 64);
551 le_move_left_bt = new Button("/images/icons/left.png","Move left",SDLK_LEFT,0,0);
552 le_move_right_bt = new Button("/images/icons/right.png","Move right",SDLK_RIGHT,screen->w-80,0);
553 le_tilegroup_bt = new Button("/images/icons/tilegroup.png","Select Tilegroup", SDLK_F7,screen->w-64,64);
554 le_objects_bt = new Button("/images/icons/objects.png","Select Objects", SDLK_F7,screen->w-64,80);
556 le_tilemap_panel = new ButtonPanel(screen->w-64,screen->h-32,32,32);
557 le_tilemap_panel->set_button_size(32,10);
558 le_tilemap_panel->additem(new Button("/images/icons/bkgrd.png","Background",SDLK_b,0,0),TM_BG);
559 le_tilemap_panel->additem(new Button("/images/icons/intact.png","Interactive",SDLK_i,0,0),TM_IA);
560 le_tilemap_panel->additem(new Button("/images/icons/frgrd.png","Foreground",SDLK_f,0,0),TM_FG);
561 le_tilemap_panel->highlight_last(true);
562 le_tilemap_panel->set_last_clicked(TM_IA);
568 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
574 void update_level_settings_menu()
579 level_settings_menu->get_item_by_id(MNID_NAME).change_input(le_world->get_level()->name.c_str());
580 level_settings_menu->get_item_by_id(MNID_AUTHOR).change_input(le_world->get_level()->author.c_str());
582 string_list_copy(level_settings_menu->get_item_by_id(MNID_SONG).list, dfiles("music/",NULL, "-fast"));
583 string_list_copy(level_settings_menu->get_item_by_id(MNID_BGIMG).list, dfiles("images/background",NULL, NULL));
584 string_list_add_item(level_settings_menu->get_item_by_id(MNID_BGIMG).list,"");
585 string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"");
586 string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"snow");
587 string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"clouds");
589 if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_SONG).list,le_world->get_level()->song_title.c_str())) != -1)
590 level_settings_menu->get_item_by_id(MNID_SONG).list->active_item = i;
591 if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_BGIMG).list,le_world->get_level()->bkgd_image.c_str())) != -1)
592 level_settings_menu->get_item_by_id(MNID_BGIMG).list->active_item = i;
593 if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,le_world->get_level()->particle_system.c_str())) != -1)
594 level_settings_menu->get_item_by_id(MNID_PARTICLE).list->active_item = i;
596 sprintf(str,"%d",le_world->get_level()->width);
597 level_settings_menu->get_item_by_id(MNID_LENGTH).change_input(str);
598 sprintf(str,"%d",le_world->get_level()->time_left);
599 level_settings_menu->get_item_by_id(MNID_TIME).change_input(str);
600 sprintf(str,"%2.0f",le_world->get_level()->gravity);
601 level_settings_menu->get_item_by_id(MNID_GRAVITY).change_input(str);
602 sprintf(str,"%d",le_world->get_level()->bkgd_speed);
603 level_settings_menu->get_item_by_id(MNID_BGSPEED).change_input(str);
604 sprintf(str,"%d",le_world->get_level()->bkgd_top.red);
605 level_settings_menu->get_item_by_id(MNID_TopRed).change_input(str);
606 sprintf(str,"%d",le_world->get_level()->bkgd_top.green);
607 level_settings_menu->get_item_by_id(MNID_TopGreen).change_input(str);
608 sprintf(str,"%d",le_world->get_level()->bkgd_top.blue);
609 level_settings_menu->get_item_by_id(MNID_TopBlue).change_input(str);
610 sprintf(str,"%d",le_world->get_level()->bkgd_bottom.red);
611 level_settings_menu->get_item_by_id(MNID_BottomRed).change_input(str);
612 sprintf(str,"%d",le_world->get_level()->bkgd_bottom.green);
613 level_settings_menu->get_item_by_id(MNID_BottomGreen).change_input(str);
614 sprintf(str,"%d",le_world->get_level()->bkgd_bottom.blue);
615 level_settings_menu->get_item_by_id(MNID_BottomBlue).change_input(str);
618 void update_subset_settings_menu()
620 subset_settings_menu->item[2].change_input(le_level_subset->title.c_str());
621 subset_settings_menu->item[3].change_input(le_level_subset->description.c_str());
624 void apply_level_settings_menu()
629 le_world->get_level()->name = level_settings_menu->get_item_by_id(MNID_NAME).input;
630 le_world->get_level()->author = level_settings_menu->get_item_by_id(MNID_AUTHOR).input;
632 if(le_world->get_level()->bkgd_image.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_BGIMG).list)) != 0)
634 le_world->get_level()->bkgd_image = string_list_active(level_settings_menu->get_item_by_id(MNID_BGIMG).list);
638 if(le_world->get_level()->particle_system.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list)) != 0)
640 le_world->get_level()->particle_system = string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list);
645 le_world->get_level()->load_gfx();
648 le_world->get_level()->song_title = string_list_active(level_settings_menu->get_item_by_id(MNID_SONG).list);
650 le_world->get_level()->change_size(atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input));
651 le_world->get_level()->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input);
652 le_world->get_level()->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input);
653 le_world->get_level()->bkgd_speed = atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input);
654 le_world->get_level()->bkgd_top.red = atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input);
655 le_world->get_level()->bkgd_top.green = atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input);
656 le_world->get_level()->bkgd_top.blue = atoi(level_settings_menu->get_item_by_id(MNID_TopBlue).input);
657 le_world->get_level()->bkgd_bottom.red = atoi(level_settings_menu->get_item_by_id(MNID_BottomRed).input);
658 le_world->get_level()->bkgd_bottom.green = atoi(level_settings_menu->get_item_by_id(MNID_BottomGreen).input);
659 le_world->get_level()->bkgd_bottom.blue = atoi(level_settings_menu->get_item_by_id(MNID_BottomBlue).input);
662 void save_subset_settings_menu()
664 le_level_subset->title = subset_settings_menu->item[2].input;
665 le_level_subset->description = subset_settings_menu->item[3].input;
666 le_level_subset->save();
669 void le_goto_level(int levelnb)
672 le_world = new World(le_level_subset->name, levelnb);
677 /*if(level_changed == true)
678 if(askforsaving() == CANCEL)
681 SDL_EnableKeyRepeat(0, 0); // disables key repeating
684 delete leveleditor_menu;
685 delete subset_load_menu;
686 delete subset_new_menu;
687 delete subset_settings_menu;
688 delete level_settings_menu;
689 delete select_tilegroup_menu;
690 delete select_objects_menu;
691 delete le_save_level_bt;
693 delete le_test_level_bt;
694 delete le_next_level_bt;
695 delete le_previous_level_bt;
696 delete le_move_right_bt;
697 delete le_move_left_bt;
699 delete le_select_mode_one_bt;
700 delete le_select_mode_two_bt;
701 delete le_settings_bt;
702 delete le_tilegroup_bt;
703 delete le_objects_bt;
704 delete le_tilemap_panel;
706 delete le_level_subset;
709 for(ButtonPanelMap::iterator i = tilegroups_map.begin();
710 i != tilegroups_map.end(); ++i)
714 for(ButtonPanelMap::iterator i = objects_map.begin();
715 i != objects_map.end(); ++i)
721 void le_drawminimap()
727 if(screen->w - 64 > le_world->get_level()->width * 4)
729 else if(screen->w - 64 > le_world->get_level()->width * 2)
733 int left_offset = (screen->w - 64 - le_world->get_level()->width*mini_tile_width) / 2;
735 for (int y = 0; y < 15; ++y)
736 for (int x = 0; x < le_world->get_level()->width; ++x)
739 Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4, mini_tile_width , 4, le_world->get_level()->bg_tiles[y][x]);
741 Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4, mini_tile_width , 4, le_world->get_level()->ia_tiles[y][x]);
743 Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4, mini_tile_width , 4, le_world->get_level()->fg_tiles[y][x]);
747 fillrect(left_offset, 0, le_world->get_level()->width*mini_tile_width, 15*4, 200, 200, 200, 128);
749 fillrect(left_offset + (pos_x/32)*mini_tile_width, 0, 19*mini_tile_width, 2, 200, 200, 200, 200);
750 fillrect(left_offset + (pos_x/32)*mini_tile_width, 0, 2, 15*4, 200, 200, 200, 200);
751 fillrect(left_offset + (pos_x/32)*mini_tile_width + 19*mini_tile_width - 2, 0, 2, 15*4, 200, 200, 200, 200);
752 fillrect(left_offset + (pos_x/32)*mini_tile_width, 15*4-2, 19*mini_tile_width, 2, 200, 200, 200, 200);
756 void le_drawinterface()
763 /* draw a grid (if selected) */
766 for(x = 0; x < 19; x++)
767 fillrect(x*32 - ((int)pos_x % 32), 0, 1, screen->h, 225, 225, 225,255);
768 for(y = 0; y < 15; y++)
769 fillrect(0, y*32, screen->w - 32, 1, 225, 225, 225,255);
773 if(show_minimap) // use_gl because the minimap isn't shown correctly in software mode. Any idea? FIXME Possible reasons: SDL_SoftStretch is a hack itsself || an alpha blitting issue SDL can't handle in software mode
776 if(le_selection_mode == CURSOR)
778 if(le_current.IsTile())
779 le_selection->draw( cursor_x - pos_x, cursor_y);
781 else if(le_selection_mode == SQUARE)
784 le_highlight_selection();
785 /* draw current selection */
786 w = selection.x2 - selection.x1;
787 h = selection.y2 - selection.y1;
788 fillrect(selection.x1 - pos_x, selection.y1, w, SELECT_W, SELECT_CLR);
789 fillrect(selection.x1 - pos_x + w, selection.y1, SELECT_W, h, SELECT_CLR);
790 fillrect(selection.x1 - pos_x, selection.y1 + h, w, SELECT_W, SELECT_CLR);
791 fillrect(selection.x1 - pos_x, selection.y1, SELECT_W, h, SELECT_CLR);
795 /* draw button bar */
796 fillrect(screen->w - 64, 0, 64, screen->h, 50, 50, 50,255);
798 if(le_current.IsTile())
800 Tile::draw(19 * 32, 14 * 32, le_current.tile);
801 if(TileManager::instance()->get(le_current.tile)->editor_images.size() > 0)
802 TileManager::instance()->get(le_current.tile)->editor_images[0]->draw( 19 * 32, 14 * 32);
804 if(le_current.IsObject())
806 le_current.obj->draw_on_screen(19 * 32, 14 * 32);
807 le_current.obj->draw_on_screen(cursor_x,cursor_y);
812 le_save_level_bt->draw();
814 le_test_level_bt->draw();
815 le_next_level_bt->draw();
816 le_previous_level_bt->draw();
817 le_rubber_bt->draw();
818 if(le_selection_mode == SQUARE)
819 le_select_mode_one_bt->draw();
820 else if(le_selection_mode == CURSOR)
821 le_select_mode_two_bt->draw();
822 le_settings_bt->draw();
823 le_move_right_bt->draw();
824 le_move_left_bt->draw();
825 le_tilegroup_bt->draw();
826 le_objects_bt->draw();
827 if(!cur_tilegroup.empty())
828 tilegroups_map[cur_tilegroup]->draw();
829 else if(!cur_objects.empty())
831 objects_map[cur_objects]->draw();
834 le_tilemap_panel->draw();
836 sprintf(str, "%d/%d", le_level,le_level_subset->levels);
837 white_text->drawf(str, (le_level_subset->levels < 10) ? -10 : 0, 16, A_RIGHT, A_TOP, 0);
840 white_small_text->draw("F1 for Help", 10, 430, 1);
845 white_small_text->draw("No Level Subset loaded - Press ESC and choose one in the menu", 10, 430, 1);
847 white_small_text->draw("No Level Subset loaded", 10, 430, 1);
857 /* Draw the real background */
858 if(le_world->get_level()->bkgd_image[0] != '\0')
860 s = (int)((float)pos_x * ((float)le_world->get_level()->bkgd_speed/60.)) % screen->w;
861 le_world->get_level()->img_bkgd->draw_part(s,0,0,0,
862 le_world->get_level()->img_bkgd->w - s - 32, le_world->get_level()->img_bkgd->h);
863 le_world->get_level()->img_bkgd->draw_part(0,0,screen->w - s - 32 ,0,s,
864 le_world->get_level()->img_bkgd->h);
868 drawgradient(le_world->get_level()->bkgd_top, le_world->get_level()->bkgd_bottom);
871 if(le_current.IsTile())
873 Tile::draw(cursor_x-pos_x, cursor_y,le_current.tile,128);
874 if(!TileManager::instance()->get(le_current.tile)->images.empty())
875 fillrect(cursor_x-pos_x,cursor_y,TileManager::instance()->get(le_current.tile)->images[0]->w,TileManager::instance()->get(le_current.tile)->images[0]->h,50,50,50,50);
877 if(le_current.IsObject())
879 le_current.obj->move_to(cursor_x, cursor_y);
882 /* clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */
884 for (y = 0; y < 15; ++y)
885 for (x = 0; x < 20; ++x)
888 if(active_tm == TM_BG)
893 Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->bg_tiles[y][x + (int)(pos_x / 32)],a);
895 if(active_tm == TM_IA)
900 Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->ia_tiles[y][x + (int)(pos_x / 32)],a);
902 if(active_tm == TM_FG)
907 Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->fg_tiles[y][x + (int)(pos_x / 32)],a);
909 /* draw whats inside stuff when cursor is selecting those */
910 /* (draw them all the time - is this the right behaviour?) */
911 Tile* edit_image = TileManager::instance()->get(le_world->get_level()->ia_tiles[y][x + (int)(pos_x / 32)]);
912 if(edit_image && !edit_image->editor_images.empty())
913 edit_image->editor_images[0]->draw( x * 32 - ((int)pos_x % 32), y*32);
917 /* Draw the Bad guys: */
918 for (std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it)
920 /* to support frames: img_bsod_left[(frame / 5) % 4] */
927 /* Draw the player: */
928 /* for now, the position is fixed at (100, 240) */
929 largetux.walk_right->draw( 100 - pos_x, 240);
932 void le_change_object_properties(GameObject *pobj)
934 Menu* object_properties_menu = new Menu();
936 object_properties_menu->additem(MN_LABEL,pobj->type() + " Properties",0,0);
937 object_properties_menu->additem(MN_HL,"",0,0);
938 /*object_properties_menu->additem(MN_TEXTFIELD,"Title",0,0,MNID_SUBSETTITLE);
939 object_properties_menu->additem(MN_TEXTFIELD,"Description",0,0,MNID_SUBSETDESCRIPTION);
940 object_properties_menu->additem(MN_HL,"",0,0);
941 object_properties_menu->additem(MN_ACTION,"Save Changes",0,0,MNID_SUBSETSAVECHANGES);*/
942 object_properties_menu->additem(MN_HL,"",0,0);
943 object_properties_menu->additem(MN_BACK,"Apply",0,0);
945 delete object_properties_menu;
949 void le_checkevents()
956 keymod = SDL_GetModState();
958 while(SDL_PollEvent(&event))
962 Menu::current()->event(event);
963 if(!le_world && !Menu::current())
964 Menu::set_current(leveleditor_menu);
968 mouse_cursor->set_state(MC_NORMAL);
970 /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/
971 if(event.type == SDL_KEYDOWN
972 || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION)
973 && (event.motion.x > 0
974 && event.motion.x < screen->w - 64 &&
975 event.motion.y > 0 && event.motion.y < screen->h)))
979 case SDL_KEYDOWN: // key pressed
980 key = event.key.keysym.sym;
984 Menu::set_current(leveleditor_menu);
988 cursor_x -= KEY_CURSOR_SPEED;
990 cursor_x -= KEY_CURSOR_FASTSPEED;
992 if(cursor_x < pos_x + MOUSE_LEFT_MARGIN)
993 pos_x = cursor_x - MOUSE_LEFT_MARGIN;
998 cursor_x += KEY_CURSOR_SPEED;
1000 cursor_x += KEY_CURSOR_FASTSPEED;
1002 if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32)
1003 pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32;
1008 cursor_y -= KEY_CURSOR_SPEED;
1010 cursor_y -= KEY_CURSOR_FASTSPEED;
1017 cursor_y += KEY_CURSOR_SPEED;
1019 cursor_y += KEY_CURSOR_FASTSPEED;
1021 if(cursor_y > screen->h-32)
1022 cursor_y = screen->h-32;
1028 if(le_world != NULL)
1036 cursor_x = (le_world->get_level()->width * 32) - 32;
1040 le_show_grid = !le_show_grid;
1046 case SDL_KEYUP: /* key released */
1047 switch(event.key.keysym.sym)
1056 case SDL_MOUSEBUTTONDOWN:
1057 if(event.button.button == SDL_BUTTON_LEFT)
1059 le_mouse_pressed[LEFT] = true;
1061 selection.x1 = event.motion.x + pos_x;
1062 selection.y1 = event.motion.y;
1063 selection.x2 = event.motion.x + pos_x;
1064 selection.y2 = event.motion.y;
1066 else if(event.button.button == SDL_BUTTON_RIGHT)
1068 le_mouse_pressed[RIGHT] = true;
1071 case SDL_MOUSEBUTTONUP:
1072 if(event.button.button == SDL_BUTTON_LEFT)
1074 le_mouse_pressed[LEFT] = false;
1075 le_mouse_clicked[LEFT] = true;
1077 else if(event.button.button == SDL_BUTTON_RIGHT)
1079 le_mouse_pressed[RIGHT] = false;
1080 le_mouse_clicked[RIGHT] = true;
1083 case SDL_MOUSEMOTION:
1085 if(!Menu::current())
1090 if(le_current.IsTile())
1092 cursor_x = ((int)(pos_x + x) / 32) * 32;
1093 cursor_y = ((int) y / 32) * 32;
1101 if(le_mouse_pressed[LEFT])
1103 selection.x2 = x + pos_x;
1107 if(le_mouse_pressed[RIGHT])
1109 pos_x += -1 * event.motion.xrel;
1113 case SDL_QUIT: // window closed
1122 if(le_world != NULL)
1124 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 &&
1125 event.motion.y > 0 && event.motion.y < screen->h)))
1127 le_mouse_pressed[LEFT] = false;
1128 le_mouse_pressed[RIGHT] = false;
1130 if(!Menu::current())
1132 /* Check for button events */
1133 le_test_level_bt->event(event);
1134 if(le_test_level_bt->get_state() == BUTTON_CLICKED)
1136 le_save_level_bt->event(event);
1137 if(le_save_level_bt->get_state() == BUTTON_CLICKED)
1138 le_world->get_level()->save(le_level_subset->name.c_str(),le_level);
1139 le_exit_bt->event(event);
1140 if(le_exit_bt->get_state() == BUTTON_CLICKED)
1142 Menu::set_current(leveleditor_menu);
1144 le_next_level_bt->event(event);
1145 if(le_next_level_bt->get_state() == BUTTON_CLICKED)
1147 if(le_level < le_level_subset->levels)
1149 le_goto_level(++le_level);
1155 sprintf(str,"Level %d doesn't exist. Create it?",le_level+1);
1156 if(confirm_dialog(str))
1158 new_lev.init_defaults();
1159 new_lev.save(le_level_subset->name.c_str(),++le_level);
1160 le_level_subset->levels = le_level;
1161 le_goto_level(le_level);
1165 le_previous_level_bt->event(event);
1166 if(le_previous_level_bt->get_state() == BUTTON_CLICKED)
1169 le_goto_level(--le_level);
1171 le_rubber_bt->event(event);
1172 if(le_rubber_bt->get_state() == BUTTON_CLICKED)
1175 if(le_selection_mode == SQUARE)
1177 le_select_mode_one_bt->event(event);
1178 if(le_select_mode_one_bt->get_state() == BUTTON_CLICKED)
1179 le_selection_mode = CURSOR;
1183 le_select_mode_two_bt->event(event);
1184 if(le_select_mode_two_bt->get_state() == BUTTON_CLICKED)
1185 le_selection_mode = SQUARE;
1187 ButtonPanelMap::iterator it;
1188 le_tilegroup_bt->event(event);
1189 switch (le_tilegroup_bt->get_state())
1191 case BUTTON_CLICKED:
1192 Menu::set_current(select_tilegroup_menu);
1193 select_tilegroup_menu_effect.start(200);
1194 select_tilegroup_menu->set_pos(screen->w - 64,100,-0.5,0.5);
1196 case BUTTON_WHEELUP:
1197 if(cur_tilegroup.empty())
1199 cur_tilegroup = tilegroups_map.begin()->first;
1203 it = tilegroups_map.find(cur_tilegroup);
1204 if((++it) == tilegroups_map.end())
1206 cur_tilegroup = tilegroups_map.begin()->first;
1210 cur_tilegroup = (*it).first;
1216 case BUTTON_WHEELDOWN:
1217 it = tilegroups_map.find(cur_tilegroup);
1218 if(it == tilegroups_map.begin())
1220 cur_tilegroup = tilegroups_map.rbegin()->first;
1224 if(--it != --tilegroups_map.begin())
1225 cur_tilegroup = (*it).first;
1227 cur_tilegroup = tilegroups_map.rbegin()->first;
1235 le_objects_bt->event(event);
1236 switch (le_objects_bt->get_state())
1238 case BUTTON_CLICKED:
1239 Menu::set_current(select_objects_menu);
1240 select_objects_menu_effect.start(200);
1241 select_objects_menu->set_pos(screen->w - 64,100,-0.5,0.5);
1243 case BUTTON_WHEELUP:
1244 it = objects_map.find(cur_objects);
1245 if(it == objects_map.end())
1247 cur_objects = objects_map.begin()->first;
1251 if(++it != objects_map.end())
1252 cur_objects = (*it).first;
1254 cur_objects = objects_map.begin()->first;
1258 case BUTTON_WHEELDOWN:
1259 it = objects_map.find(cur_objects);
1260 if(it == objects_map.begin())
1262 cur_objects = objects_map.rbegin()->first;
1266 if(--it != --objects_map.begin())
1267 cur_objects = (*it).first;
1269 cur_objects = objects_map.rbegin()->first;
1278 le_settings_bt->event(event);
1279 if(le_settings_bt->get_state() == BUTTON_CLICKED)
1281 update_level_settings_menu();
1282 Menu::set_current(level_settings_menu);
1284 if(!cur_tilegroup.empty())
1286 if((pbutton = tilegroups_map[cur_tilegroup]->event(event)) != NULL)
1288 if(pbutton->get_state() == BUTTON_CLICKED)
1290 le_current.Tile(pbutton->get_tag());
1294 else if(!cur_objects.empty())
1296 if((pbutton = objects_map[cur_objects]->event(event)) != NULL)
1298 if(pbutton->get_state() == BUTTON_CLICKED)
1300 le_current.Object(pbutton->get_game_object());
1305 if((pbutton = le_tilemap_panel->event(event)) != NULL)
1307 if(pbutton->get_state() == BUTTON_CLICKED)
1309 active_tm = static_cast<TileMapType>(pbutton->get_tag());
1315 le_settings_bt->event(event);
1316 if(le_settings_bt->get_state() == BUTTON_CLICKED)
1318 Menu::set_current(0);
1320 le_tilegroup_bt->event(event);
1321 if(le_tilegroup_bt->get_state() == BUTTON_CLICKED)
1323 Menu::set_current(0);
1325 le_objects_bt->event(event);
1326 if(le_objects_bt->get_state() == BUTTON_CLICKED)
1328 Menu::set_current(0);
1333 if(!Menu::current() && !show_minimap)
1335 if(le_mouse_pressed[LEFT])
1337 if(le_current.IsTile())
1338 le_change(cursor_x, cursor_y, active_tm, le_current.tile);
1340 else if(le_mouse_clicked[LEFT])
1342 if(le_current.IsObject())
1344 std::string type = le_current.obj->type();
1345 if(type == "BadGuy")
1347 BadGuy* pbadguy = dynamic_cast<BadGuy*>(le_current.obj);
1349 le_world->bad_guys.push_back(new BadGuy(cursor_x+scroll_x, cursor_y,pbadguy->kind,false));
1350 le_world->get_level()->badguy_data.push_back(le_world->bad_guys.back());
1353 le_mouse_clicked[LEFT] = false;
1358 if(!Menu::current())
1360 show_minimap = false;
1362 le_move_left_bt->event(event);
1363 le_move_right_bt->event(event);
1364 switch(le_move_left_bt->get_state())
1366 case BUTTON_PRESSED:
1368 show_minimap = true;
1372 show_minimap = true;
1374 case BUTTON_CLICKED:
1375 show_minimap = true;
1381 switch(le_move_right_bt->get_state())
1383 case BUTTON_PRESSED:
1385 show_minimap = true;
1389 show_minimap = true;
1391 case BUTTON_CLICKED:
1392 show_minimap = true;
1402 void le_highlight_selection()
1406 if(selection.x1 < selection.x2)
1416 if(selection.y1 < selection.y2)
1432 fillrect(x1*32-pos_x, y1*32,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
1435 void le_change(float x, float y, int tm, unsigned int c)
1437 if(le_world != NULL)
1443 /* level_changed = true; */
1445 switch(le_selection_mode)
1448 le_world->get_level()->change(x,y,tm,c);
1450 base_type cursor_base;
1453 cursor_base.width = 32;
1454 cursor_base.height = 32;
1456 /* if there is a bad guy over there, remove it */
1457 for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it, ++i)
1458 if(rectcollision(cursor_base,(*it)->base))
1461 le_world->bad_guys.erase(it);
1462 le_world->get_level()->badguy_data.erase(le_world->get_level()->badguy_data.begin() + i);
1468 if(selection.x1 < selection.x2)
1478 if(selection.y1 < selection.y2)
1494 /* if there is a bad guy over there, remove it */
1495 for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin();
1496 it != le_world->bad_guys.end(); /* will be at end of loop */)
1498 if((*it)->base.x/32 >= x1 && (*it)->base.x/32 <= x2
1499 && (*it)->base.y/32 >= y1 && (*it)->base.y/32 <= y2)
1502 it = le_world->bad_guys.erase(it);
1503 le_world->get_level()->badguy_data.erase(le_world->get_level()->badguy_data.begin() + i);
1513 for(xx = x1; xx <= x2; xx++)
1514 for(yy = y1; yy <= y2; yy++)
1516 le_world->get_level()->change(xx*32, yy*32, tm, c);
1528 //Make sure a time value is set when testing the level
1529 if(le_world->get_level()->time_left == 0)
1530 le_world->get_level()->time_left = 250;
1532 le_world->get_level()->save("test", le_level);
1534 GameSession session("test",le_level, ST_GL_TEST);
1536 player_status.reset();
1538 music_manager->halt_music();
1540 Menu::set_current(NULL);
1541 World::set_current(le_world);
1546 bool tmp_show_grid = le_show_grid;
1547 le_show_grid = false;
1548 le_help_shown = true;
1550 drawgradient(Color(0,0,0), Color(255,255,255));
1554 unsigned int i, done_;
1557 " - Supertux level editor tutorial - ",
1559 "To make your map, click the ",
1560 "tilegroup button and choose a ",
1562 "Pick a tile and simply hold down ",
1563 "the left mouse button over the map",
1564 "to \"paint\" your selection over",
1566 "There are three layers for painting",
1567 "tiles upon, Background layer,",
1568 "the Interactive layer, and the",
1569 "Foreground layer, which can be",
1570 "toggled by the BkGrd, IntAct and",
1571 "FrGrd buttons. The Foreground and",
1572 "Background layers do not effect",
1573 "Tux in the gameplay, but lie in",
1574 "front of him or lie behind him in",
1580 " - Supertux level editor tutorial - ",
1582 "The tiles placed on",
1583 "the Interactive layer are those",
1584 "which actually effect Tux in the",
1586 "Click the objects menu to put ",
1587 "bad guys and other objects in the",
1588 "game. Unlike placing tiles, you",
1589 "cannot \"paint\" enemies. Click",
1590 "them onto the screen one at a time.",
1591 "To change the settings of your",
1592 "level, click the button with the",
1593 "screwdriver and wrench. From here",
1594 "you can change the background,",
1595 "music, length of the level, and more.",
1596 "You may have more than one levelset.",
1597 "Pressing the up and down buttons",
1598 "above the button bar lets you choose",
1599 "which one you are working on.",
1600 "If you would like to speed up your",
1601 "level editing, a useful trick is",
1602 "to learn the keyboard shortcuts. They",
1603 "are easy to learn, just right-",
1604 "Have fun making levels! If you make",
1605 "some good ones, send them to us on",
1606 "the SuperTux mailing list!",
1611 blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
1613 for(i = 0; i < sizeof(text)/sizeof(char *); i++)
1614 white_text->draw(text[i], 5, 80+(i*white_text->h), 1);
1616 gold_text->drawf("Press Any Key to Continue - Page 1/2", 0, 0, A_LEFT, A_BOTTOM, 1);
1624 done_ = wait_for_event(event);
1628 drawgradient(Color(0,0,0), Color(255,255,255));
1632 blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
1634 for(i = 0; i < sizeof(text2)/sizeof(char *); i++)
1635 white_text->draw(text2[i], 5, 80+(i*white_text->h), 1);
1637 gold_text->drawf("Press Any Key to Continue - Page 2/2", 0, 0, A_LEFT, A_BOTTOM, 1);
1645 done_ = wait_for_event(event);
1649 le_show_grid = tmp_show_grid;
1650 le_help_shown = false;