From 433e5cdc9bb7b166454e210ba3a2666a7d5ac536 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tobias=20Gl=C3=A4=C3=9Fer?= Date: Sun, 9 May 2004 18:08:02 +0000 Subject: [PATCH] Added a static member function to the Surface class for screen capturing. Redesigned the confirm dialog using it. Minor leveleditor improvements. (Asks if you want to save a changed level etc.) SVN-Revision: 1053 --- src/leveleditor.cpp | 76 +++-- src/menu.cpp | 843 +++++++++++++++++++++++++++------------------------- src/menu.h | 2 +- src/texture.cpp | 71 ++++- src/texture.h | 5 + 5 files changed, 540 insertions(+), 457 deletions(-) diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index c6ef0baa4..133664a60 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -66,7 +66,7 @@ /* crutial ones (main loop) */ int le_init(); void le_quit(); -int le_load_level(char *filename); +int le_load_level_subset(char *filename); void le_drawlevel(); void le_drawinterface(); void le_checkevents(); @@ -75,7 +75,7 @@ void le_testlevel(); void le_showhelp(); void le_set_defaults(void); void le_activate_bad_guys(void); - +void le_goto_level(int levelnb); void le_highlight_selection(); void apply_level_settings_menu(); @@ -169,7 +169,7 @@ int leveleditor(char* filename) {} if(filename != NULL) - if(le_load_level(filename)) + if(le_load_level_subset(filename)) return 1; while(true) @@ -294,7 +294,7 @@ int leveleditor(char* filename) default: if(i >= 1) { - if(le_load_level(level_subsets.item[i-1])) + if(le_load_level_subset(level_subsets.item[i-1])) return 1; } break; @@ -314,8 +314,7 @@ int leveleditor(char* filename) LevelSubset::create(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input); le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input); leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO; - delete le_world; - le_world = new World(le_level_subset->name,1); + le_goto_level(1); subset_new_menu->get_item_by_id(MNID_SUBSETNAME).change_input(""); Menu::set_current(subset_settings_menu); @@ -361,13 +360,12 @@ int leveleditor(char* filename) return done; } -int le_load_level(char *filename) +int le_load_level_subset(char *filename) { le_level_subset->load(filename); leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO; le_level = 1; - delete le_world; - le_world = new World(filename,le_level); + le_goto_level(1); //GameSession* session = new GameSession(datadir + "/levels/" + le_level_subset->name + "/level1.stl", 0, ST_GL_DEMO_GAME); @@ -666,20 +664,35 @@ void save_subset_settings_menu() le_level_subset->save(); } -void le_goto_level(int levelnb) +void le_unload_level() { + if(le_level_changed) + { + le_drawlevel(); + le_drawinterface(); + char str[1024]; + sprintf(str,"Save changes to level %d of %s?",le_level,le_level_subset->name.c_str()); + if(confirm_dialog(str)) + { + le_world->get_level()->save(le_level_subset->name.c_str(),le_level); + } + } + delete le_world; + le_level_changed = false; +} + +void le_goto_level(int levelnb) +{ + le_unload_level(); le_world = new World(le_level_subset->name, levelnb); } void le_quit(void) { - /*if(level_changed == true) - if(askforsaving() == CANCEL) - return;*/ //FIXME - SDL_EnableKeyRepeat(0, 0); // disables key repeating + le_unload_level(); delete le_selection; delete leveleditor_menu; delete subset_load_menu; @@ -777,19 +790,19 @@ void le_drawinterface() { if(le_current.IsTile()) le_selection->draw( cursor_x - pos_x, cursor_y); - } - else if(le_selection_mode == SQUARE) - { - int w, h; - le_highlight_selection(); - /* draw current selection */ - w = selection.x2 - selection.x1; - h = selection.y2 - selection.y1; - fillrect(selection.x1 - pos_x, selection.y1, w, SELECT_W, SELECT_CLR); - fillrect(selection.x1 - pos_x + w, selection.y1, SELECT_W, h, SELECT_CLR); - fillrect(selection.x1 - pos_x, selection.y1 + h, w, SELECT_W, SELECT_CLR); - fillrect(selection.x1 - pos_x, selection.y1, SELECT_W, h, SELECT_CLR); - } + } + else if(le_selection_mode == SQUARE) + { + int w, h; + le_highlight_selection(); + /* draw current selection */ + w = selection.x2 - selection.x1; + h = selection.y2 - selection.y1; + fillrect(selection.x1 - pos_x, selection.y1, w, SELECT_W, SELECT_CLR); + fillrect(selection.x1 - pos_x + w, selection.y1, SELECT_W, h, SELECT_CLR); + fillrect(selection.x1 - pos_x, selection.y1 + h, w, SELECT_W, SELECT_CLR); + fillrect(selection.x1 - pos_x, selection.y1, SELECT_W, h, SELECT_CLR); + } /* draw button bar */ @@ -961,7 +974,7 @@ void le_checkevents() { Menu::current()->event(event); if(!le_world && !Menu::current()) - Menu::set_current(leveleditor_menu); + Menu::set_current(leveleditor_menu); } else { @@ -982,7 +995,7 @@ void le_checkevents() { case SDLK_ESCAPE: Menu::set_current(leveleditor_menu); - break; + break; case SDLK_LEFT: if(fire == DOWN) cursor_x -= KEY_CURSOR_SPEED; @@ -1341,6 +1354,7 @@ void le_checkevents() { if(le_current.IsObject()) { + le_level_changed = true; std::string type = le_current.obj->type(); if(type == "BadGuy") { @@ -1440,8 +1454,8 @@ void le_change(float x, float y, int tm, unsigned int c) int x1, x2, y1, y2; unsigned int i = 0; - /* level_changed = true; */ - + le_level_changed = true; + switch(le_selection_mode) { case CURSOR: diff --git a/src/menu.cpp b/src/menu.cpp index 9d9cb32cc..baa703252 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -1,5 +1,5 @@ // $Id$ -// +// // SuperTux // Copyright (C) 2004 Tobias Glaesser // @@ -12,7 +12,7 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -63,41 +63,57 @@ std::vector Menu::last_menus; Menu* Menu::current_ = 0; /* just displays a Yes/No text that can be used to confirm stuff */ -bool confirm_dialog(char *text) +bool confirm_dialog(std::string text) { -white_text->drawf(text,0,0,A_HMIDDLE,A_VMIDDLE,2); -red_text->drawf("(Y)es/(N)o",0,20,A_HMIDDLE,A_VMIDDLE,2); -flipscreen(); -SDL_Event event; -int done = 0; -bool confirm = false; -while(done == 0) + Surface* cap_screen = Surface::CaptureScreen(); + + Menu* dialog = new Menu; + dialog->additem(MN_DEACTIVE, text,0,0); + dialog->additem(MN_HL,"",0,0); + dialog->additem(MN_ACTION,"Yes",0,0,true); + dialog->additem(MN_ACTION,"No",0,0,false); + dialog->additem(MN_HL,"",0,0); + + Menu::set_current(dialog); + + while(true) { - while(SDL_PollEvent(&event)) - switch(event.type) - { - case SDL_KEYDOWN: // key pressed - switch(event.key.keysym.sym) - { - case SDLK_y: - done = 1; - confirm = true; - break; - case SDLK_n: - done = 1; - break; - default: - break; - } - break; - case SDL_QUIT: // quit signal - done = 1; - default: - break; - } - SDL_Delay(50); + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + dialog->event(event); + } + + cap_screen->draw(0,0); + + dialog->draw(); + dialog->action(); + + switch (dialog->check()) + { + case true: + delete cap_screen; + Menu::set_current(0); + delete dialog; + return true; + break; + case false: + delete cap_screen; + Menu::set_current(0); + delete dialog; + return false; + break; + default: + break; + } + + mouse_cursor->draw(); + flipscreen(); + SDL_Delay(25); } -return confirm; + + } void @@ -105,7 +121,7 @@ Menu::push_current(Menu* pmenu) { if (current_) last_menus.push_back(current_); - + current_ = pmenu; current_->effect.start(500); } @@ -114,16 +130,16 @@ void Menu::pop_current() { if (!last_menus.empty()) - { - current_ = last_menus.back(); - current_->effect.start(500); + { + current_ = last_menus.back(); + current_->effect.start(500); - last_menus.pop_back(); - } + last_menus.pop_back(); + } else - { - current_ = 0; - } + { + current_ = 0; + } } void @@ -133,7 +149,7 @@ Menu::set_current(Menu* menu) if (menu) menu->effect.start(500); - + current_ = menu; } @@ -142,7 +158,7 @@ MenuItem* MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu* target_menu_, int id, int* int_p_) { MenuItem *pnew_item = new MenuItem; - + pnew_item->kind = kind_; pnew_item->text = (char*) malloc(sizeof(char) * (strlen(text_) + 1)); strcpy(pnew_item->text, text_); @@ -157,10 +173,10 @@ MenuItem::create(MenuItemKind kind_, const char *text_, int init_toggle_, Menu* pnew_item->input[0] = '\0'; if(kind_ == MN_STRINGSELECT) - { - pnew_item->list = (string_list_type*) malloc(sizeof(string_list_type)); - string_list_init(pnew_item->list); - } + { + pnew_item->list = (string_list_type*) malloc(sizeof(string_list_type)); + string_list_init(pnew_item->list); + } else pnew_item->list = NULL; @@ -178,49 +194,49 @@ void MenuItem::change_text(const char *text_) { if (text_) - { - free(text); - text = (char*) malloc(sizeof(char )*(strlen(text_)+1)); - strcpy(text, text_); - } + { + free(text); + text = (char*) malloc(sizeof(char )*(strlen(text_)+1)); + strcpy(text, text_); + } } void MenuItem::change_input(const char *text_) { if(text) - { - free(input); - input = (char*) malloc(sizeof(char )*(strlen(text_)+1)); - strcpy(input, text_); - } + { + free(input); + input = (char*) malloc(sizeof(char )*(strlen(text_)+1)); + strcpy(input, text_); + } } std::string MenuItem::get_input_with_symbol(bool active_item) { -if(!active_item) - input_flickering = true; -else + if(!active_item) + input_flickering = true; + else { - if(input_flickering_timer.get_left() < 0) + if(input_flickering_timer.get_left() < 0) { - if(input_flickering) - input_flickering = false; - else - input_flickering = true; - input_flickering_timer.start(FLICK_CURSOR_TIME); + if(input_flickering) + input_flickering = false; + else + input_flickering = true; + input_flickering_timer.start(FLICK_CURSOR_TIME); } } -char str[1024]; -if(input_flickering) - sprintf(str,"%s_",input); -else - sprintf(str,"%s ",input); + char str[1024]; + if(input_flickering) + sprintf(str,"%s_",input); + else + sprintf(str,"%s ",input); -std::string string = str; + std::string string = str; -return string; + return string; } /* Set ControlField a key */ @@ -278,14 +294,14 @@ void Menu::get_controlfield_key_into_input(MenuItem *item) Menu::~Menu() { if(item.size() != 0) + { + for(unsigned int i = 0; i < item.size(); ++i) { - for(unsigned int i = 0; i < item.size(); ++i) - { - free(item[i].text); - free(item[i].input); - string_list_free(item[i].list); - } + free(item[i].text); + free(item[i].input); + string_list_free(item[i].list); } + } } @@ -295,7 +311,7 @@ Menu::Menu() menuaction = MENU_ACTION_NONE; delete_character = 0; mn_input_char = '\0'; - + pos_x = screen->w/2; pos_y = screen->h/2; arrange_left = 0; @@ -335,133 +351,133 @@ Menu::action() { hit_item = -1; if(item.size() != 0) + { + switch(menuaction) { - switch(menuaction) + case MENU_ACTION_UP: + if (active_item > 0) + --active_item; + else + active_item = int(item.size())-1; + break; + + case MENU_ACTION_DOWN: + if(active_item < int(item.size())-1) + ++active_item; + else + active_item = 0; + break; + + case MENU_ACTION_LEFT: + if(item[active_item].kind == MN_STRINGSELECT + && item[active_item].list->num_items != 0) + { + if(item[active_item].list->active_item > 0) + --item[active_item].list->active_item; + else + item[active_item].list->active_item = item[active_item].list->num_items-1; + } + break; + + case MENU_ACTION_RIGHT: + if(item[active_item].kind == MN_STRINGSELECT + && item[active_item].list->num_items != 0) + { + if(item[active_item].list->active_item < item[active_item].list->num_items-1) + ++item[active_item].list->active_item; + else + item[active_item].list->active_item = 0; + } + break; + + case MENU_ACTION_HIT: + { + hit_item = active_item; + switch (item[active_item].kind) { - case MENU_ACTION_UP: - if (active_item > 0) - --active_item; + case MN_GOTO: + if (item[active_item].target_menu != NULL) + Menu::push_current(item[active_item].target_menu); else - active_item = int(item.size())-1; + puts("NULLL"); break; - case MENU_ACTION_DOWN: - if(active_item < int(item.size())-1) - ++active_item; - else - active_item = 0; + case MN_TOGGLE: + item[active_item].toggled = !item[active_item].toggled; break; - case MENU_ACTION_LEFT: - if(item[active_item].kind == MN_STRINGSELECT - && item[active_item].list->num_items != 0) - { - if(item[active_item].list->active_item > 0) - --item[active_item].list->active_item; - else - item[active_item].list->active_item = item[active_item].list->num_items-1; - } + case MN_ACTION: + Menu::set_current(0); + item[active_item].toggled = true; + break; + case MN_TEXTFIELD: + case MN_NUMFIELD: + menuaction = MENU_ACTION_DOWN; + action(); break; - case MENU_ACTION_RIGHT: - if(item[active_item].kind == MN_STRINGSELECT - && item[active_item].list->num_items != 0) - { - if(item[active_item].list->active_item < item[active_item].list->num_items-1) - ++item[active_item].list->active_item; - else - item[active_item].list->active_item = 0; - } + case MN_BACK: + Menu::pop_current(); + break; + default: break; + } + } + break; + + case MENU_ACTION_REMOVE: + if(item[active_item].kind == MN_TEXTFIELD + || item[active_item].kind == MN_NUMFIELD) + { + if(item[active_item].input != NULL) + { + int i = strlen(item[active_item].input); - case MENU_ACTION_HIT: + while(delete_character > 0) /* remove charactes */ { - hit_item = active_item; - switch (item[active_item].kind) - { - case MN_GOTO: - if (item[active_item].target_menu != NULL) - Menu::push_current(item[active_item].target_menu); - else - puts("NULLL"); - break; - - case MN_TOGGLE: - item[active_item].toggled = !item[active_item].toggled; - break; - - case MN_ACTION: - Menu::set_current(0); - item[active_item].toggled = true; - break; - case MN_TEXTFIELD: - case MN_NUMFIELD: - menuaction = MENU_ACTION_DOWN; - action(); - break; - - case MN_BACK: - Menu::pop_current(); - break; - default: - break; - } + item[active_item].input[i-1] = '\0'; + delete_character--; } - break; - - case MENU_ACTION_REMOVE: - if(item[active_item].kind == MN_TEXTFIELD - || item[active_item].kind == MN_NUMFIELD) - { - if(item[active_item].input != NULL) - { - int i = strlen(item[active_item].input); - - while(delete_character > 0) /* remove charactes */ - { - item[active_item].input[i-1] = '\0'; - delete_character--; - } - } - } - break; + } + } + break; - case MENU_ACTION_INPUT: - if(item[active_item].kind == MN_TEXTFIELD - || (item[active_item].kind == MN_NUMFIELD && mn_input_char >= '0' && mn_input_char <= '9')) - { - if(item[active_item].input != NULL) - { - int i = strlen(item[active_item].input); - item[active_item].input = (char*) realloc(item[active_item].input,sizeof(char)*(i + 2)); - item[active_item].input[i] = mn_input_char; - item[active_item].input[i+1] = '\0'; - } - else - { - item[active_item].input = (char*) malloc(2*sizeof(char)); - item[active_item].input[0] = mn_input_char; - item[active_item].input[1] = '\0'; - } - } - - case MENU_ACTION_NONE: - break; + case MENU_ACTION_INPUT: + if(item[active_item].kind == MN_TEXTFIELD + || (item[active_item].kind == MN_NUMFIELD && mn_input_char >= '0' && mn_input_char <= '9')) + { + if(item[active_item].input != NULL) + { + int i = strlen(item[active_item].input); + item[active_item].input = (char*) realloc(item[active_item].input,sizeof(char)*(i + 2)); + item[active_item].input[i] = mn_input_char; + item[active_item].input[i+1] = '\0'; + } + else + { + item[active_item].input = (char*) malloc(2*sizeof(char)); + item[active_item].input[0] = mn_input_char; + item[active_item].input[1] = '\0'; } + } + + case MENU_ACTION_NONE: + break; } + } MenuItem& new_item = item[active_item]; if(new_item.kind == MN_DEACTIVE || new_item.kind == MN_LABEL || new_item.kind == MN_HL) - { - // Skip the horzontal line item - if (menuaction != MENU_ACTION_UP && menuaction != MENU_ACTION_DOWN) - menuaction = MENU_ACTION_DOWN; + { + // Skip the horzontal line item + if (menuaction != MENU_ACTION_UP && menuaction != MENU_ACTION_DOWN) + menuaction = MENU_ACTION_DOWN; - if (item.size() > 1) - action(); - } + if (item.size() > 1) + action(); + } menuaction = MENU_ACTION_NONE; } @@ -505,131 +521,131 @@ Menu::draw_item(int index, // Position of the current item in the menu x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2; if(index == active_item) - { - shadow_size = 3; - text_font = blue_text; - } + { + shadow_size = 3; + text_font = blue_text; + } switch (pitem.kind) + { + case MN_DEACTIVE: { - case MN_DEACTIVE: - { - black_text->draw_align(pitem.text, - x_pos, y_pos, - A_HMIDDLE, A_VMIDDLE, 2); - break; - } + black_text->draw_align(pitem.text, + x_pos, y_pos, + A_HMIDDLE, A_VMIDDLE, 2); + break; + } - case MN_HL: - { - int x = pos_x - menu_width/2; - int y = y_pos - 12 - effect_offset; - /* Draw a horizontal line with a little 3d effect */ - fillrect(x, y + 6, - menu_width, 4, - 150,200,255,225); - fillrect(x, y + 6, - menu_width, 2, - 255,255,255,255); - break; - } - case MN_LABEL: - { - white_big_text->draw_align(pitem.text, - x_pos, y_pos, - A_HMIDDLE, A_VMIDDLE, 2); - break; - } - case MN_TEXTFIELD: - case MN_NUMFIELD: - case MN_CONTROLFIELD: - { - int input_pos = input_width/2; - int text_pos = (text_width + font_width)/2; + case MN_HL: + { + int x = pos_x - menu_width/2; + int y = y_pos - 12 - effect_offset; + /* Draw a horizontal line with a little 3d effect */ + fillrect(x, y + 6, + menu_width, 4, + 150,200,255,225); + fillrect(x, y + 6, + menu_width, 2, + 255,255,255,255); + break; + } + case MN_LABEL: + { + white_big_text->draw_align(pitem.text, + x_pos, y_pos, + A_HMIDDLE, A_VMIDDLE, 2); + break; + } + case MN_TEXTFIELD: + case MN_NUMFIELD: + case MN_CONTROLFIELD: + { + int input_pos = input_width/2; + int text_pos = (text_width + font_width)/2; - fillrect(x_pos - input_pos + text_pos - 1, y_pos - 10, - input_width + font_width + 2, 20, - 255,255,255,255); - fillrect(x_pos - input_pos + text_pos, y_pos - 9, - input_width + font_width, 18, - 0,0,0,128); + fillrect(x_pos - input_pos + text_pos - 1, y_pos - 10, + input_width + font_width + 2, 20, + 255,255,255,255); + fillrect(x_pos - input_pos + text_pos, y_pos - 9, + input_width + font_width, 18, + 0,0,0,128); - if(pitem.kind == MN_CONTROLFIELD) - get_controlfield_key_into_input(&pitem); + if(pitem.kind == MN_CONTROLFIELD) + get_controlfield_key_into_input(&pitem); - if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD) - { - if(active_item == index) - gold_text->draw_align((pitem.get_input_with_symbol(true)).c_str(), x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2); - else - gold_text->draw_align((pitem.get_input_with_symbol(false)).c_str(), x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2); - } + if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD) + { + if(active_item == index) + gold_text->draw_align((pitem.get_input_with_symbol(true)).c_str(), x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2); else - gold_text->draw_align(pitem.input, + gold_text->draw_align((pitem.get_input_with_symbol(false)).c_str(), x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2); + } + else + gold_text->draw_align(pitem.input, x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2); - text_font->draw_align(pitem.text, - x_pos - (input_width + font_width)/2, y_pos, - A_HMIDDLE, A_VMIDDLE, shadow_size); - break; - } - case MN_STRINGSELECT: - { - int list_pos_2 = list_width + font_width; - int list_pos = list_width/2; - int text_pos = (text_width + font_width)/2; - - /* Draw arrows */ - arrow_left->draw( x_pos - list_pos + text_pos - 17, y_pos - 8); - arrow_right->draw( x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8); - - /* Draw input background */ - fillrect(x_pos - list_pos + text_pos - 1, y_pos - 10, - list_pos_2 + 2, 20, - 255,255,255,255); - fillrect(x_pos - list_pos + text_pos, y_pos - 9, - list_pos_2, 18, - 0,0,0,128); - - gold_text->draw_align(string_list_active(pitem.list), - x_pos + text_pos, y_pos, - A_HMIDDLE, A_VMIDDLE,2); - - text_font->draw_align(pitem.text, - x_pos - list_pos_2/2, y_pos, - A_HMIDDLE, A_VMIDDLE, shadow_size); - break; - } - case MN_BACK: - { - text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size); - back->draw( x_pos + text_width/2 + font_width, y_pos - 8); - break; - } - - case MN_TOGGLE: - { - text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size); - - if(pitem.toggled) - checkbox_checked->draw( - x_pos + (text_width+font_width)/2, - y_pos - 8); - else - checkbox->draw( - x_pos + (text_width+font_width)/2, - y_pos - 8); - break; - } - case MN_ACTION: + text_font->draw_align(pitem.text, + x_pos - (input_width + font_width)/2, y_pos, + A_HMIDDLE, A_VMIDDLE, shadow_size); + break; + } + case MN_STRINGSELECT: + { + int list_pos_2 = list_width + font_width; + int list_pos = list_width/2; + int text_pos = (text_width + font_width)/2; + + /* Draw arrows */ + arrow_left->draw( x_pos - list_pos + text_pos - 17, y_pos - 8); + arrow_right->draw( x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8); + + /* Draw input background */ + fillrect(x_pos - list_pos + text_pos - 1, y_pos - 10, + list_pos_2 + 2, 20, + 255,255,255,255); + fillrect(x_pos - list_pos + text_pos, y_pos - 9, + list_pos_2, 18, + 0,0,0,128); + + gold_text->draw_align(string_list_active(pitem.list), + x_pos + text_pos, y_pos, + A_HMIDDLE, A_VMIDDLE,2); + + text_font->draw_align(pitem.text, + x_pos - list_pos_2/2, y_pos, + A_HMIDDLE, A_VMIDDLE, shadow_size); + break; + } + case MN_BACK: + { text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size); + back->draw( x_pos + text_width/2 + font_width, y_pos - 8); break; + } - case MN_GOTO: + case MN_TOGGLE: + { text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size); + + if(pitem.toggled) + checkbox_checked->draw( + x_pos + (text_width+font_width)/2, + y_pos - 8); + else + checkbox->draw( + x_pos + (text_width+font_width)/2, + y_pos - 8); break; } + case MN_ACTION: + text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size); + break; + + case MN_GOTO: + text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size); + break; + } } int Menu::get_width() const @@ -638,15 +654,15 @@ int Menu::get_width() const with the most characters */ int menu_width = 0; for(unsigned int i = 0; i < item.size(); ++i) + { + int w = strlen(item[i].text) + (item[i].input ? strlen(item[i].input) + 1 : 0) + strlen(string_list_active(item[i].list)); + if( w > menu_width ) { - int w = strlen(item[i].text) + (item[i].input ? strlen(item[i].input) + 1 : 0) + strlen(string_list_active(item[i].list)); - if( w > menu_width ) - { - menu_width = w; - if( item[i].kind == MN_TOGGLE) - menu_width += 2; - } + menu_width = w; + if( item[i].kind == MN_TOGGLE) + menu_width += 2; } + } return (menu_width * 16 + 24); } @@ -670,15 +686,16 @@ Menu::draw() 150,180,200,125); for(unsigned int i = 0; i < item.size(); ++i) - { - draw_item(i, menu_width, menu_height); - } + { + draw_item(i, menu_width, menu_height); + } } MenuItem& Menu::get_item_by_id(int id) { - for(std::vector::iterator i = item.begin(); i != item.end(); ++i) { + for(std::vector::iterator i = item.begin(); i != item.end(); ++i) + { if(i->id == id) return *i; } @@ -690,7 +707,7 @@ Menu::get_item_by_id(int id) int Menu::get_active_item_id() { -return item[active_item].id; + return item[active_item].id; } bool @@ -705,126 +722,126 @@ Menu::event(SDL_Event& event) { SDLKey key; switch(event.type) + { + case SDL_KEYDOWN: + key = event.key.keysym.sym; + SDLMod keymod; + char ch[2]; + keymod = SDL_GetModState(); + int x,y; + + /* If the current unicode character is an ASCII character, + assign it to ch. */ + if ( (event.key.keysym.unicode & 0xFF80) == 0 ) { - case SDL_KEYDOWN: - key = event.key.keysym.sym; - SDLMod keymod; - char ch[2]; - keymod = SDL_GetModState(); - int x,y; - - /* If the current unicode character is an ASCII character, - assign it to ch. */ - if ( (event.key.keysym.unicode & 0xFF80) == 0 ) - { - ch[0] = event.key.keysym.unicode & 0x7F; - ch[1] = '\0'; - } - else - { - /* An International Character. */ - } + ch[0] = event.key.keysym.unicode & 0x7F; + ch[1] = '\0'; + } + else + { + /* An International Character. */ + } - if(item[active_item].kind == MN_CONTROLFIELD) - { - if(key == SDLK_ESCAPE) - { - Menu::pop_current(); - return; - } - *item[active_item].int_p = key; - menuaction = MENU_ACTION_DOWN; + if(item[active_item].kind == MN_CONTROLFIELD) + { + if(key == SDLK_ESCAPE) + { + Menu::pop_current(); return; - } + } + *item[active_item].int_p = key; + menuaction = MENU_ACTION_DOWN; + return; + } - switch(key) - { - case SDLK_UP: /* Menu Up */ - menuaction = MENU_ACTION_UP; - break; - case SDLK_DOWN: /* Menu Down */ - menuaction = MENU_ACTION_DOWN; - break; - case SDLK_LEFT: /* Menu Up */ - menuaction = MENU_ACTION_LEFT; - break; - case SDLK_RIGHT: /* Menu Down */ - menuaction = MENU_ACTION_RIGHT; - break; - case SDLK_SPACE: - if(item[active_item].kind == MN_TEXTFIELD) - { - menuaction = MENU_ACTION_INPUT; - mn_input_char = ' '; - break; - } - case SDLK_RETURN: /* Menu Hit */ - menuaction = MENU_ACTION_HIT; - break; - case SDLK_DELETE: - case SDLK_BACKSPACE: - menuaction = MENU_ACTION_REMOVE; - delete_character++; - break; - case SDLK_ESCAPE: - Menu::pop_current(); - break; - default: - if( (key >= SDLK_0 && key <= SDLK_9) || (key >= SDLK_a && key <= SDLK_z) || (key >= SDLK_SPACE && key <= SDLK_SLASH)) - { - menuaction = MENU_ACTION_INPUT; - mn_input_char = *ch; - } - else - { - mn_input_char = '\0'; - } - break; - } + switch(key) + { + case SDLK_UP: /* Menu Up */ + menuaction = MENU_ACTION_UP; break; - case SDL_JOYAXISMOTION: - if(event.jaxis.axis == joystick_keymap.y_axis) - { - if (event.jaxis.value > 1024) - menuaction = MENU_ACTION_DOWN; - else if (event.jaxis.value < -1024) - menuaction = MENU_ACTION_UP; - } + case SDLK_DOWN: /* Menu Down */ + menuaction = MENU_ACTION_DOWN; break; - case SDL_JOYBUTTONDOWN: + case SDLK_LEFT: /* Menu Up */ + menuaction = MENU_ACTION_LEFT; + break; + case SDLK_RIGHT: /* Menu Down */ + menuaction = MENU_ACTION_RIGHT; + break; + case SDLK_SPACE: + if(item[active_item].kind == MN_TEXTFIELD) + { + menuaction = MENU_ACTION_INPUT; + mn_input_char = ' '; + break; + } + case SDLK_RETURN: /* Menu Hit */ menuaction = MENU_ACTION_HIT; break; - case SDL_MOUSEBUTTONDOWN: - x = event.motion.x; - y = event.motion.y; - if(x > pos_x - get_width()/2 && - x < pos_x + get_width()/2 && - y > pos_y - get_height()/2 && - y < pos_y + get_height()/2) - { - menuaction = MENU_ACTION_HIT; - } + case SDLK_DELETE: + case SDLK_BACKSPACE: + menuaction = MENU_ACTION_REMOVE; + delete_character++; break; - case SDL_MOUSEMOTION: - x = event.motion.x; - y = event.motion.y; - if(x > pos_x - get_width()/2 && - x < pos_x + get_width()/2 && - y > pos_y - get_height()/2 && - y < pos_y + get_height()/2) - { - active_item = (y - (pos_y - get_height()/2)) / 24; - mouse_cursor->set_state(MC_LINK); - } - else - { - mouse_cursor->set_state(MC_NORMAL); - } + case SDLK_ESCAPE: + Menu::pop_current(); break; default: + if( (key >= SDLK_0 && key <= SDLK_9) || (key >= SDLK_a && key <= SDLK_z) || (key >= SDLK_SPACE && key <= SDLK_SLASH)) + { + menuaction = MENU_ACTION_INPUT; + mn_input_char = *ch; + } + else + { + mn_input_char = '\0'; + } break; } + break; + case SDL_JOYAXISMOTION: + if(event.jaxis.axis == joystick_keymap.y_axis) + { + if (event.jaxis.value > 1024) + menuaction = MENU_ACTION_DOWN; + else if (event.jaxis.value < -1024) + menuaction = MENU_ACTION_UP; + } + break; + case SDL_JOYBUTTONDOWN: + menuaction = MENU_ACTION_HIT; + break; + case SDL_MOUSEBUTTONDOWN: + x = event.motion.x; + y = event.motion.y; + if(x > pos_x - get_width()/2 && + x < pos_x + get_width()/2 && + y > pos_y - get_height()/2 && + y < pos_y + get_height()/2) + { + menuaction = MENU_ACTION_HIT; + } + break; + case SDL_MOUSEMOTION: + x = event.motion.x; + y = event.motion.y; + if(x > pos_x - get_width()/2 && + x < pos_x + get_width()/2 && + y > pos_y - get_height()/2 && + y < pos_y + get_height()/2) + { + active_item = (y - (pos_y - get_height()/2)) / 24; + mouse_cursor->set_state(MC_LINK); + } + else + { + mouse_cursor->set_state(MC_NORMAL); + } + break; + default: + break; + } } diff --git a/src/menu.h b/src/menu.h index 641b68ddf..449cf2366 100644 --- a/src/menu.h +++ b/src/menu.h @@ -92,7 +92,7 @@ enum LevelEditorSettingsMenuIDs { MNID_APPLY }; -bool confirm_dialog(char *text); +bool confirm_dialog(std::string text); /* Kinds of menu items */ enum MenuItemKind { diff --git a/src/texture.cpp b/src/texture.cpp index 0dea8f0a2..f9ed75a49 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -251,13 +251,60 @@ Surface::resize(int w_, int h_) { if (impl) { - w = w_; - h = h_; + w = w_; + h = h_; if (impl->resize(w_,h_) == -2) reload(); } } +Surface* Surface::CaptureScreen() +{ + Surface *cap_screen; + + if (!(screen->flags & SDL_OPENGL)) + { + cap_screen = new Surface(SDL_GetVideoSurface(),false); + } + +#ifndef NOOPENGL + if (use_gl) + { + SDL_Surface *temp; + unsigned char *pixels; + int i; + temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000FF, 0x0000FF00, 0x00FF0000, 0 +#else + 0x00FF0000, 0x0000FF00, 0x000000FF, 0 +#endif + ); + if (temp == NULL) + st_abort("Error while trying to capture the screen in OpenGL mode",""); + + pixels = (unsigned char*) malloc(3 * screen->w * screen->h); + if (pixels == NULL) + { + SDL_FreeSurface(temp); + st_abort("Error while trying to capture the screen in OpenGL mode",""); + } + + glReadPixels(0, 0, screen->w, screen->h, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + for (i=0; ih; i++) + memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*screen->w * (screen->h-i-1), screen->w*3); + free(pixels); + + cap_screen = new Surface(temp,false); + SDL_FreeSurface(temp); + + } +#endif + +return cap_screen; +} + SDL_Surface* sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h, int use_alpha) { @@ -400,7 +447,7 @@ int SurfaceImpl::resize(int w_, int h_) dest.w = w; dest.h = h; int ret = SDL_SoftStretch(sdl_surface, NULL, - sdl_surface, &dest); + sdl_surface, &dest); return ret; } @@ -789,7 +836,7 @@ int SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update) { SDL_Rect dest; - + dest.x = (int)x; dest.y = (int)y; dest.w = (int)sw; @@ -797,15 +844,15 @@ SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool u if(alpha != 255) SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha); - - - SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags, - sw, sh, sdl_surface->format->BitsPerPixel, - sdl_surface->format->Rmask, sdl_surface->format->Gmask, - sdl_surface->format->Bmask, - 0); - SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL); + + SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags, + sw, sh, sdl_surface->format->BitsPerPixel, + sdl_surface->format->Rmask, sdl_surface->format->Gmask, + sdl_surface->format->Bmask, + 0); + + SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL); SDL_SoftStretch(sdl_surface_copy, NULL, sdl_surface_copy, &dest); int ret = SDL_BlitSurface(sdl_surface_copy,NULL,screen,&dest); diff --git a/src/texture.h b/src/texture.h index 53cb3a189..3ba0e58a0 100644 --- a/src/texture.h +++ b/src/texture.h @@ -30,6 +30,8 @@ #include #include "screen.h" +SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha); + class SurfaceImpl; class SurfaceSDL; class SurfaceOpenGL; @@ -79,6 +81,9 @@ public: Surface(const std::string& file, int x, int y, int w, int h, int use_alpha); ~Surface(); + /** Captures the screen and returns it as Surface*, the user is expected to call the destructor. */ + static Surface* CaptureScreen(); + /** Reload the surface, which is necesarry in case of a mode swich */ void reload(); -- 2.11.0