|
Atrinik Client 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <global.h> 00031 00033 static button_struct button_password; 00034 00036 enum 00037 { 00038 BUTTON_SETTINGS, 00039 BUTTON_KEY_SETTINGS, 00040 BUTTON_LOGOUT, 00041 BUTTON_BACK, 00042 00043 BUTTON_NUM 00044 }; 00045 00047 static const char *const button_names[BUTTON_NUM] = 00048 { 00049 "Client Settings", "Key Settings", "Logout", "Back to Play" 00050 }; 00051 00053 static uint8 setting_type = SETTING_TYPE_NONE; 00055 static size_t button_selected; 00057 static size_t setting_category_selected; 00059 static uint32 list_row_clicked; 00061 static uint32 list_clicked = 0; 00063 static uint8 setting_keybind_step; 00065 static SDLKey setting_keybind_key; 00067 static SDLMod setting_keybind_mod; 00069 static sint32 setting_keybind_id; 00073 static uint8 setting_password_confirmed; 00074 00078 static void settings_list_reload(list_struct *list) 00079 { 00080 size_t i; 00081 00082 /* Clear all the rows. */ 00083 list_clear_rows(list); 00084 00085 /* Settings? */ 00086 if (setting_type == SETTING_TYPE_SETTINGS) 00087 { 00088 setting_struct *setting; 00089 00090 for (i = 0; i < setting_categories[setting_category_selected]->settings_num; i++) 00091 { 00092 setting = setting_categories[setting_category_selected]->settings[i]; 00093 00094 /* Internal, no need to go any further. */ 00095 if (setting->internal) 00096 { 00097 break; 00098 } 00099 00100 list_add(list, list->rows, 0, ""); 00101 } 00102 } 00103 /* Keybindings? */ 00104 else if (setting_type == SETTING_TYPE_KEYBINDINGS) 00105 { 00106 char buf[MAX_BUF]; 00107 00108 for (i = 0; i < keybindings_num; i++) 00109 { 00110 list_add(list, i, 0, keybindings[i]->command); 00111 list_add(list, i, 1, keybind_get_key_shortcut(keybindings[i]->key, keybindings[i]->mod, buf, sizeof(buf))); 00112 list_add(list, i, 2, keybindings[i]->repeat ? "on" : "off"); 00113 } 00114 } 00115 00116 list_offsets_ensure(list); 00117 } 00118 00124 static void list_handle_mouse_row(list_struct *list, uint32 row, SDL_Event *event) 00125 { 00126 if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT) 00127 { 00128 list_row_clicked = row; 00129 list_clicked = 1; 00130 } 00131 else if (event->type == SDL_MOUSEMOTION) 00132 { 00133 list->row_selected = row + 1; 00134 } 00135 } 00136 00142 static void list_handle_esc(list_struct *list) 00143 { 00144 (void) list; 00145 popup_destroy_visible(); 00146 } 00147 00153 static void setting_change_value(int cat, int set, sint64 val) 00154 { 00155 setting_struct *setting = setting_categories[cat]->settings[set]; 00156 00157 if (setting->type == OPT_TYPE_BOOL) 00158 { 00159 setting_set_int(cat, set, !setting_get_int(cat, set)); 00160 } 00161 else if (setting->type == OPT_TYPE_SELECT || setting->type == OPT_TYPE_RANGE) 00162 { 00163 sint64 old_val, new_val, advance; 00164 00165 if (!val) 00166 { 00167 return; 00168 } 00169 00170 new_val = old_val = setting_get_int(cat, set); 00171 advance = 1; 00172 00173 if (setting->type == OPT_TYPE_RANGE) 00174 { 00175 advance = SETTING_RANGE(setting)->advance; 00176 } 00177 00178 new_val = old_val + (advance * val); 00179 00180 if (setting->type == OPT_TYPE_SELECT) 00181 { 00182 setting_select *s_select = SETTING_SELECT(setting); 00183 00184 if (new_val >= (sint64) s_select->options_len) 00185 { 00186 new_val = 0; 00187 } 00188 else if (new_val < 0) 00189 { 00190 new_val = s_select->options_len - 1; 00191 } 00192 } 00193 else if (setting->type == OPT_TYPE_RANGE) 00194 { 00195 setting_range *range = SETTING_RANGE(setting); 00196 00197 new_val = MAX(range->min, MIN(range->max, new_val)); 00198 } 00199 00200 if (old_val != new_val) 00201 { 00202 setting_set_int(cat, set, new_val); 00203 } 00204 } 00205 } 00206 00212 static void list_post_column(list_struct *list, uint32 row, uint32 col) 00213 { 00214 int x, y; 00215 00216 (void) col; 00217 00218 x = list->x + list->frame_offset; 00219 y = LIST_ROWS_START(list) + (row * LIST_ROW_HEIGHT(list)) + list->frame_offset; 00220 00221 /* Settings list. */ 00222 if (setting_type == SETTING_TYPE_SETTINGS) 00223 { 00224 setting_struct *setting; 00225 int mx, my, mstate; 00226 00227 setting = setting_categories[setting_category_selected]->settings[row]; 00228 00229 if (setting->internal) 00230 { 00231 return; 00232 } 00233 00234 /* Show the actual setting name. */ 00235 string_blt_shadow_format(list->surface, FONT_ARIAL11, x + 4, y + 5, list->row_selected == row + 1 ? COLOR_HGOLD : COLOR_WHITE, COLOR_BLACK, 0, NULL, "%s:", setting->name); 00236 00237 mstate = SDL_GetMouseState(&mx, &my); 00238 00239 /* Checkbox? */ 00240 if (setting->type == OPT_TYPE_BOOL) 00241 { 00242 SDL_Rect checkbox; 00243 00244 checkbox.x = x + list->width - 17; 00245 checkbox.y = y + 1; 00246 checkbox.w = 14; 00247 checkbox.h = 14; 00248 SDL_FillRect(list->surface, &checkbox, SDL_MapRGB(list->surface->format, 0, 0, 0)); 00249 00250 if (setting_get_int(setting_category_selected, row)) 00251 { 00252 lineRGBA(list->surface, checkbox.x, checkbox.y, checkbox.x + checkbox.w, checkbox.y + checkbox.h, 212, 213, 83, 255); 00253 lineRGBA(list->surface, checkbox.x + checkbox.w, checkbox.y, checkbox.x, checkbox.y + checkbox.h, 212, 213, 83, 255); 00254 } 00255 00256 draw_frame(list->surface, checkbox.x, checkbox.y, checkbox.w, checkbox.h); 00257 00258 if (mx >= checkbox.x && mx <= checkbox.x + checkbox.w && my >= checkbox.y && my <= checkbox.y + checkbox.h) 00259 { 00260 border_create_color(list->surface, &checkbox, "b09a9a"); 00261 00262 if (list_clicked && list_row_clicked == row && mstate == SDL_BUTTON_LEFT) 00263 { 00264 setting_change_value(setting_category_selected, row, 0); 00265 list_clicked = 0; 00266 } 00267 } 00268 else 00269 { 00270 border_create_color(list->surface, &checkbox, "8c7a7a"); 00271 } 00272 } 00273 /* Select or range. */ 00274 else if (setting->type == OPT_TYPE_SELECT || setting->type == OPT_TYPE_RANGE) 00275 { 00276 SDL_Rect dst; 00277 sint64 val; 00278 00279 val = setting_get_int(setting_category_selected, row); 00280 00281 x += list->width - 1; 00282 y += 1; 00283 00284 x -= Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w; 00285 00286 if (button_show(BITMAP_BUTTON_ROUND, -1, BITMAP_BUTTON_ROUND_DOWN, x, y, ">", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00287 { 00288 setting_change_value(setting_category_selected, row, 1); 00289 } 00290 00291 dst.x = x - 150; 00292 dst.y = y; 00293 dst.w = 150; 00294 dst.h = LIST_ROW_HEIGHT(list) - 2; 00295 00296 SDL_FillRect(list->surface, &dst, SDL_MapRGB(list->surface->format, 0, 0, 0)); 00297 00298 if (setting->type == OPT_TYPE_SELECT) 00299 { 00300 string_blt(list->surface, FONT_ARIAL10, SETTING_SELECT(setting)->options[val], dst.x, dst.y, COLOR_WHITE, TEXT_ALIGN_CENTER, &dst); 00301 } 00302 else if (setting->type == OPT_TYPE_RANGE) 00303 { 00304 string_blt_format(list->surface, FONT_ARIAL10, dst.x, dst.y, COLOR_WHITE, TEXT_ALIGN_CENTER, &dst, "%"FMT64, val); 00305 } 00306 00307 dst.x -= Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w + 1; 00308 00309 if (button_show(BITMAP_BUTTON_ROUND, -1, BITMAP_BUTTON_ROUND_DOWN, dst.x, y, "<", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00310 { 00311 setting_change_value(setting_category_selected, row, -1); 00312 } 00313 } 00314 } 00315 } 00316 00320 static void setting_keybind_apply(list_struct *list) 00321 { 00322 /* Nothing to apply. */ 00323 if (text_input_string[0] == '\0' || setting_keybind_key == SDLK_UNKNOWN) 00324 { 00325 return; 00326 } 00327 00328 /* Add new. */ 00329 if (setting_keybind_id == -1) 00330 { 00331 keybind_add(setting_keybind_key, setting_keybind_mod, text_input_string); 00332 /* It'll be added to the end, so select it. */ 00333 list->row_selected = list->rows + 1; 00334 list->row_offset = MIN(list->rows + 1 - list->max_rows, list->row_selected - 1); 00335 } 00336 /* Edit existing. */ 00337 else 00338 { 00339 keybind_edit(setting_keybind_id, setting_keybind_key, setting_keybind_mod, text_input_string); 00340 } 00341 00342 text_input_string_flag = 0; 00343 settings_list_reload(list); 00344 } 00345 00351 static int setting_keybind_action(SDLKey key, list_struct *list) 00352 { 00353 /* Create a new keybinding. */ 00354 if (key == SDLK_n) 00355 { 00356 text_input_open(255); 00357 setting_keybind_step = KEYBIND_STEP_COMMAND; 00358 setting_keybind_key = SDLK_UNKNOWN; 00359 setting_keybind_mod = KMOD_NONE; 00360 setting_keybind_id = -1; 00361 return 1; 00362 } 00363 /* Delete existing keybinding. */ 00364 else if (key == SDLK_DELETE) 00365 { 00366 keybind_remove(list->row_selected - 1); 00367 settings_list_reload(list); 00368 return 1; 00369 } 00370 /* Toggle repeat on/off. */ 00371 else if (key == SDLK_r) 00372 { 00373 keybind_repeat_toggle(list->row_selected - 1); 00374 settings_list_reload(list); 00375 return 1; 00376 } 00377 00378 return 0; 00379 } 00380 00385 static void setting_category_change(int advance) 00386 { 00387 size_t new_cat = setting_category_selected; 00388 00389 if (advance == 1) 00390 { 00391 if (new_cat == setting_categories_num - 1) 00392 { 00393 new_cat = 0; 00394 } 00395 else 00396 { 00397 new_cat++; 00398 } 00399 } 00400 else if (advance == -1) 00401 { 00402 if (new_cat == 0) 00403 { 00404 new_cat = setting_categories_num - 1; 00405 } 00406 else 00407 { 00408 new_cat--; 00409 } 00410 } 00411 00412 if (new_cat != setting_category_selected) 00413 { 00414 setting_category_selected = new_cat; 00415 settings_list_reload(list_exists(LIST_SETTINGS)); 00416 } 00417 } 00418 00422 static void settings_popup_draw_func_post(popup_struct *popup) 00423 { 00424 list_struct *list = list_exists(LIST_SETTINGS); 00425 int x, y, mx, my, mstate; 00426 00427 mstate = SDL_GetMouseState(&mx, &my); 00428 00429 if (setting_type == SETTING_TYPE_NONE) 00430 { 00431 if (GameStatus == GAME_STATUS_PLAY) 00432 { 00433 button_password.x = popup->x + 15; 00434 button_password.y = popup->y + 15; 00435 button_render(&button_password, "Password"); 00436 } 00437 } 00438 else if (setting_type == SETTING_TYPE_SETTINGS) 00439 { 00440 setting_struct *setting; 00441 SDL_Rect dst; 00442 00443 x = popup->x + 30; 00444 y = popup->y + 50; 00445 00446 if (button_show(BITMAP_BUTTON_ROUND, -1, BITMAP_BUTTON_ROUND_DOWN, x, y, "<", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00447 { 00448 setting_category_change(-1); 00449 } 00450 00451 dst.w = list->width + 8 - Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w; 00452 dst.h = 0; 00453 00454 if (button_show(BITMAP_BUTTON_ROUND, -1, BITMAP_BUTTON_ROUND_DOWN, x + dst.w, y, ">", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00455 { 00456 setting_category_change(1); 00457 } 00458 00459 setting = setting_categories[setting_category_selected]->settings[list->row_selected - 1]; 00460 00461 dst.w -= Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w; 00462 string_blt(list->surface, FONT_SERIF14, setting_categories[setting_category_selected]->name, x + Bitmaps[BITMAP_BUTTON_ROUND]->bitmap->w, y - 3, COLOR_HGOLD, TEXT_ALIGN_CENTER, &dst); 00463 00464 dst.h = 66; 00465 string_blt_shadow(list->surface, FONT_ARIAL11, setting->desc ? setting->desc : "", x - 2, popup->y + popup->surface->h - 75, COLOR_WHITE, COLOR_BLACK, TEXT_WORD_WRAP | TEXT_MARKUP, &dst); 00466 00467 list_show(list, x, y); 00468 00469 if (button_show(BITMAP_BUTTON, -1, BITMAP_BUTTON_DOWN, popup->x + popup->surface->w - 10 - Bitmaps[BITMAP_BUTTON]->bitmap->w, popup->y + popup->surface->h - 55, "Apply", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00470 { 00471 settings_apply_change(); 00472 } 00473 00474 if (button_show(BITMAP_BUTTON, -1, BITMAP_BUTTON_DOWN, popup->x + popup->surface->w - 10 - Bitmaps[BITMAP_BUTTON]->bitmap->w, popup->y + popup->surface->h - 30, "Done", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00475 { 00476 popup_destroy_visible(); 00477 } 00478 } 00479 else if (setting_type == SETTING_TYPE_KEYBINDINGS) 00480 { 00481 SDL_Rect dst; 00482 char key_buf[MAX_BUF]; 00483 00484 x = popup->x + 30; 00485 y = popup->y + 50; 00486 list_show(list, x, y); 00487 00488 if (button_show(BITMAP_BUTTON, -1, BITMAP_BUTTON_DOWN, popup->x + 30, popup->y + popup->surface->h - 74, "Add", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00489 { 00490 setting_keybind_action(SDLK_n, list); 00491 } 00492 00493 if (button_show(BITMAP_BUTTON, -1, BITMAP_BUTTON_DOWN, popup->x + 30, popup->y + popup->surface->h - 51, "Remove", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00494 { 00495 setting_keybind_action(SDLK_DELETE, list); 00496 } 00497 00498 if (button_show(BITMAP_BUTTON, -1, BITMAP_BUTTON_DOWN, popup->x + 30, popup->y + popup->surface->h - 28, "Repeat", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00499 { 00500 setting_keybind_action(SDLK_r, list); 00501 } 00502 00503 if (text_input_string_flag) 00504 { 00505 string_blt_shadow(ScreenSurface, FONT_ARIAL11, "Command: ", popup->x + 100, popup->y + popup->surface->h - 70, COLOR_WHITE, COLOR_BLACK, 0, NULL); 00506 string_blt_shadow(ScreenSurface, FONT_ARIAL11, "Key: ", popup->x + 100, popup->y + popup->surface->h - 47, COLOR_WHITE, COLOR_BLACK, 0, NULL); 00507 string_blt_shadow(ScreenSurface, FONT_ARIAL10, "Press ESC to cancel.", popup->x + 160, popup->y + popup->surface->h - 34, COLOR_WHITE, COLOR_BLACK, 0, NULL); 00508 00509 dst.x = popup->x + 160; 00510 dst.y = popup->y + popup->surface->h - 74; 00511 dst.w = Bitmaps[BITMAP_LOGIN_INP]->bitmap->w; 00512 dst.h = Bitmaps[BITMAP_LOGIN_INP]->bitmap->h; 00513 00514 if (mstate == SDL_BUTTON_LEFT && mx >= dst.x && mx < dst.x + dst.w && my >= dst.y && my < dst.y + dst.h) 00515 { 00516 setting_keybind_step = KEYBIND_STEP_COMMAND; 00517 } 00518 00519 if (setting_keybind_step == KEYBIND_STEP_COMMAND) 00520 { 00521 text_input_show(ScreenSurface, dst.x, dst.y, FONT_ARIAL11, text_input_string, COLOR_WHITE, 0, BITMAP_LOGIN_INP, NULL); 00522 } 00523 else 00524 { 00525 text_input_draw_background(ScreenSurface, dst.x, dst.y, BITMAP_LOGIN_INP); 00526 text_input_draw_text(ScreenSurface, dst.x, dst.y, FONT_ARIAL11, text_input_string, COLOR_WHITE, 0, BITMAP_LOGIN_INP, NULL); 00527 } 00528 00529 dst.y += 20; 00530 00531 if (mstate == SDL_BUTTON_LEFT && mx >= dst.x && mx < dst.x + dst.w && my >= dst.y && my < dst.y + dst.h) 00532 { 00533 setting_keybind_step = KEYBIND_STEP_KEY; 00534 } 00535 00536 if (setting_keybind_step == KEYBIND_STEP_COMMAND || setting_keybind_step == KEYBIND_STEP_DONE) 00537 { 00538 keybind_get_key_shortcut(setting_keybind_key, setting_keybind_mod, key_buf, sizeof(key_buf)); 00539 } 00540 else if (setting_keybind_step == KEYBIND_STEP_KEY) 00541 { 00542 strcpy(key_buf, "Press keyboard shortcut"); 00543 } 00544 00545 text_input_draw_background(ScreenSurface, dst.x, dst.y, BITMAP_LOGIN_INP); 00546 text_input_draw_text(ScreenSurface, dst.x, dst.y, FONT_ARIAL11, key_buf, COLOR_WHITE, TEXT_ALIGN_CENTER, BITMAP_LOGIN_INP, NULL); 00547 00548 if (button_show(BITMAP_BUTTON, -1, BITMAP_BUTTON_DOWN, dst.x + dst.w - Bitmaps[BITMAP_BUTTON]->bitmap->w, dst.y + 20, "Apply", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00549 { 00550 setting_keybind_apply(list); 00551 } 00552 } 00553 } 00554 } 00555 00559 static void settings_popup_draw_func(popup_struct *popup) 00560 { 00561 SDL_Rect box; 00562 00563 box.x = 0; 00564 box.y = 10; 00565 box.w = popup->surface->w; 00566 box.h = 0; 00567 00568 string_blt(popup->surface, FONT_SERIF20, "<u>Settings</u>", box.x, box.y, COLOR_HGOLD, TEXT_ALIGN_CENTER | TEXT_MARKUP, &box); 00569 00570 if (setting_type == SETTING_TYPE_NONE) 00571 { 00572 size_t i; 00573 00574 box.y += 50; 00575 00576 for (i = 0; i < BUTTON_NUM; i++) 00577 { 00578 if (GameStatus != GAME_STATUS_PLAY && (i == BUTTON_BACK || i == BUTTON_LOGOUT)) 00579 { 00580 continue; 00581 } 00582 00583 if (button_selected == i) 00584 { 00585 string_blt_shadow_format(popup->surface, FONT_SERIF40, box.x, box.y, COLOR_HGOLD, COLOR_BLACK, TEXT_ALIGN_CENTER | TEXT_MARKUP, &box, "<c=#9f0408>></c> %s <c=#9f0408><</c>", button_names[i]); 00586 } 00587 else 00588 { 00589 00590 string_blt_shadow(popup->surface, FONT_SERIF40, button_names[i], box.x, box.y, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00591 } 00592 00593 box.y += FONT_HEIGHT(FONT_SERIF40); 00594 } 00595 } 00596 else if (setting_type == SETTING_TYPE_PASSWORD) 00597 { 00598 char buf[MAX_BUF]; 00599 int i; 00600 00601 for (i = 0; i < text_input_count; i++) 00602 { 00603 buf[i] = '*'; 00604 } 00605 00606 buf[i] = '\0'; 00607 00608 box.x = popup->surface->w / 2 - Bitmaps[BITMAP_LOGIN_INP]->bitmap->w / 2; 00609 box.y = popup->surface->h / 2 - Bitmaps[BITMAP_LOGIN_INP]->bitmap->h / 2 - 50; 00610 00611 text_input_show(popup->surface, box.x, box.y, FONT_ARIAL10, buf, COLOR_WHITE, 0, BITMAP_LOGIN_INP, NULL); 00612 00613 if (!setting_password_confirmed) 00614 { 00615 string_blt_shadow(popup->surface, FONT_ARIAL11, "Enter your current password:", 0, box.y - 14, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00616 string_blt_shadow(popup->surface, FONT_ARIAL11, "Allows you to change your character's", 0, box.y + 24, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00617 string_blt_shadow(popup->surface, FONT_ARIAL11, "password. Press Esc to cancel.", 0, box.y + 36, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00618 } 00619 else 00620 { 00621 string_blt_shadow(popup->surface, FONT_ARIAL11, "Enter the new password:", 0, box.y - 14, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00622 string_blt_shadow(popup->surface, FONT_ARIAL11, "Make sure to use a strong password.", 0, box.y + 24, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00623 string_blt_shadow(popup->surface, FONT_ARIAL11, "A good password usually consists of a ", 0, box.y + 36, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00624 string_blt_shadow(popup->surface, FONT_ARIAL11, "mix of uppercase and lowercase letters,", 0, box.y + 48, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00625 string_blt_shadow(popup->surface, FONT_ARIAL11, "numbers, symbols, and does not include", 0, box.y + 60, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00626 string_blt_shadow(popup->surface, FONT_ARIAL11, "words found in common dictionaries.", 0, box.y + 72, COLOR_WHITE, COLOR_BLACK, TEXT_ALIGN_CENTER, &box); 00627 } 00628 } 00629 } 00630 00635 static int settings_popup_destroy_callback(popup_struct *popup) 00636 { 00637 (void) popup; 00638 settings_apply_change(); 00639 list_remove(list_exists(LIST_SETTINGS)); 00640 00641 if (text_input_string_flag) 00642 { 00643 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); 00644 text_input_string_flag = 0; 00645 } 00646 00647 keybind_save(); 00648 00649 return 1; 00650 } 00651 00655 static void list_handle_enter(list_struct *list) 00656 { 00657 if (list->text && list->row_selected) 00658 { 00659 if (setting_type == SETTING_TYPE_KEYBINDINGS) 00660 { 00661 setting_keybind_action(SDLK_n, list); 00662 00663 setting_keybind_id = list->row_selected - 1; 00664 text_input_add_string(keybindings[setting_keybind_id]->command); 00665 setting_keybind_key = keybindings[setting_keybind_id]->key; 00666 setting_keybind_mod = keybindings[setting_keybind_id]->mod; 00667 } 00668 else if (setting_type == SETTING_TYPE_SETTINGS) 00669 { 00670 setting_change_value(setting_category_selected, list->row_selected - 1, 0); 00671 list_clicked = 0; 00672 } 00673 } 00674 } 00675 00681 static int list_key_event(list_struct *list, SDLKey key) 00682 { 00683 switch (key) 00684 { 00685 case SDLK_RIGHT: 00686 if (SDL_GetModState() & KMOD_SHIFT) 00687 { 00688 setting_category_change(1); 00689 } 00690 else 00691 { 00692 setting_change_value(setting_category_selected, list->row_selected - 1, 1); 00693 } 00694 00695 break; 00696 00697 case SDLK_LEFT: 00698 if (SDL_GetModState() & KMOD_SHIFT) 00699 { 00700 setting_category_change(-1); 00701 } 00702 else 00703 { 00704 setting_change_value(setting_category_selected, list->row_selected - 1, -1); 00705 } 00706 00707 break; 00708 00709 default: 00710 return -1; 00711 } 00712 00713 return 1; 00714 } 00715 00719 static void settings_button_handle(size_t button) 00720 { 00721 if (button == BUTTON_KEY_SETTINGS || button == BUTTON_SETTINGS) 00722 { 00723 list_struct *list; 00724 uint32 cols, max_rows; 00725 00726 if (button == BUTTON_SETTINGS) 00727 { 00728 setting_type = SETTING_TYPE_SETTINGS; 00729 cols = 1; 00730 max_rows = 9; 00731 } 00732 else if (button == BUTTON_KEY_SETTINGS) 00733 { 00734 setting_type = SETTING_TYPE_KEYBINDINGS; 00735 cols = 3; 00736 max_rows = 12; 00737 } 00738 00739 setting_category_selected = 0; 00740 00741 list = list_create(LIST_SETTINGS, max_rows, cols, 8); 00742 list->handle_esc_func = list_handle_esc; 00743 list->handle_enter_func = list_handle_enter; 00744 list_scrollbar_enable(list); 00745 00746 if (button == BUTTON_SETTINGS) 00747 { 00748 list_set_column(list, 0, 430, 7, NULL, -1); 00749 list_set_font(list, FONT_SANS14); 00750 list->handle_mouse_row_func = list_handle_mouse_row; 00751 list->key_event_func = list_key_event; 00752 list->row_highlight_func = NULL; 00753 list->row_selected_func = NULL; 00754 list->post_column_func = list_post_column; 00755 } 00756 else if (button == BUTTON_KEY_SETTINGS) 00757 { 00758 list_set_font(list, FONT_ARIAL11); 00759 list_set_column(list, 0, 273, 7, "Command", -1); 00760 list_set_column(list, 1, 93, 7, "Key", 1); 00761 list_set_column(list, 2, 50, 7, "Repeat", 1); 00762 list->header_height = 7; 00763 } 00764 00765 list_set_focus(list); 00766 settings_list_reload(list); 00767 return; 00768 } 00769 else if (button == BUTTON_LOGOUT) 00770 { 00771 socket_close(&csocket); 00772 GameStatus = GAME_STATUS_INIT; 00773 } 00774 00775 popup_destroy_visible(); 00776 } 00777 00780 static int settings_popup_event_func(popup_struct *popup, SDL_Event *event) 00781 { 00782 list_struct *list; 00783 00784 if (setting_type == SETTING_TYPE_NONE) 00785 { 00786 if (GameStatus == GAME_STATUS_PLAY && button_event(&button_password, event)) 00787 { 00788 setting_type = SETTING_TYPE_PASSWORD; 00789 setting_password_confirmed = 0; 00790 text_input_open(64); 00791 return 1; 00792 } 00793 00794 if (event->type == SDL_KEYDOWN) 00795 { 00796 /* Move the selected button up and down. */ 00797 if (event->key.keysym.sym == SDLK_UP || event->key.keysym.sym == SDLK_DOWN) 00798 { 00799 int selected = button_selected, num_buttons; 00800 00801 selected += event->key.keysym.sym == SDLK_DOWN ? 1 : -1; 00802 num_buttons = (GameStatus == GAME_STATUS_PLAY ? BUTTON_NUM : BUTTON_LOGOUT) - 1; 00803 00804 if (selected < 0) 00805 { 00806 selected = num_buttons; 00807 } 00808 else if (selected > num_buttons) 00809 { 00810 selected = 0; 00811 } 00812 00813 button_selected = selected; 00814 return 1; 00815 } 00816 else if (event->key.keysym.sym == SDLK_RETURN || event->key.keysym.sym == SDLK_KP_ENTER) 00817 { 00818 settings_button_handle(button_selected); 00819 return 1; 00820 } 00821 } 00822 else if (event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEMOTION) 00823 { 00824 int x, y, width; 00825 size_t i; 00826 00827 y = popup->y + 60; 00828 00829 for (i = 0; i < BUTTON_NUM; i++) 00830 { 00831 if (GameStatus != GAME_STATUS_PLAY && (i == BUTTON_BACK || i == BUTTON_LOGOUT)) 00832 { 00833 continue; 00834 } 00835 00836 if (event->motion.y >= y && event->motion.y < y + FONT_HEIGHT(FONT_SERIF40)) 00837 { 00838 width = string_get_width(FONT_SERIF40, button_names[i], 0); 00839 x = popup->x + popup->surface->w / 2 - width / 2; 00840 00841 if (event->motion.x >= x && event->motion.x < x + width) 00842 { 00843 if (event->type == SDL_MOUSEMOTION) 00844 { 00845 button_selected = i; 00846 } 00847 else if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT) 00848 { 00849 settings_button_handle(i); 00850 } 00851 00852 break; 00853 } 00854 } 00855 00856 y += FONT_HEIGHT(FONT_SERIF40); 00857 } 00858 } 00859 } 00860 else if (setting_type == SETTING_TYPE_PASSWORD) 00861 { 00862 if (event->type == SDL_KEYDOWN) 00863 { 00864 if (event->key.keysym.sym == SDLK_RETURN || event->key.keysym.sym == SDLK_KP_ENTER || event->key.keysym.sym == SDLK_TAB) 00865 { 00866 if (!setting_password_confirmed) 00867 { 00868 if (!strcmp(text_input_string, cpl.password)) 00869 { 00870 setting_password_confirmed = 1; 00871 text_input_open(64); 00872 return 1; 00873 } 00874 else 00875 { 00876 draw_info(COLOR_RED, "The current password did not match."); 00877 } 00878 } 00879 else 00880 { 00881 if (text_input_string[0] == '\0') 00882 { 00883 draw_info(COLOR_WHITE, "Canceled password change."); 00884 } 00885 else 00886 { 00887 SockList sl; 00888 unsigned char sockbuf[MAX_BUF]; 00889 00890 sl.buf = sockbuf; 00891 sl.len = 0; 00892 SockList_AddString(&sl, "pc "); 00893 SockList_AddStringTerminated(&sl, cpl.password); 00894 SockList_AddStringTerminated(&sl, text_input_string); 00895 send_socklist(sl); 00896 00897 strncpy(cpl.password, text_input_string, sizeof(cpl.password) - 1); 00898 cpl.password[sizeof(cpl.password) - 1] = '\0'; 00899 } 00900 } 00901 } 00902 else if (event->key.keysym.sym != SDLK_ESCAPE) 00903 { 00904 text_input_handle(&event->key); 00905 return 1; 00906 } 00907 00908 popup_destroy_visible(); 00909 } 00910 } 00911 else if ((list = list_exists(LIST_SETTINGS))) 00912 { 00913 if (setting_type == SETTING_TYPE_KEYBINDINGS && (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP)) 00914 { 00915 if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_ESCAPE) 00916 { 00917 if (text_input_string_flag) 00918 { 00919 SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); 00920 text_input_string_flag = 0; 00921 return 1; 00922 } 00923 } 00924 else if (setting_keybind_step == KEYBIND_STEP_KEY) 00925 { 00926 if (event->type == SDL_KEYUP) 00927 { 00928 setting_keybind_key = event->key.keysym.sym; 00929 setting_keybind_mod = event->key.keysym.mod; 00930 setting_keybind_step = KEYBIND_STEP_DONE; 00931 } 00932 00933 return 1; 00934 } 00935 else if (event->key.keysym.sym == SDLK_KP_ENTER || event->key.keysym.sym == SDLK_RETURN || event->key.keysym.sym == SDLK_TAB) 00936 { 00937 if (setting_keybind_step == KEYBIND_STEP_COMMAND && event->type == SDL_KEYUP) 00938 { 00939 setting_keybind_step = KEYBIND_STEP_KEY; 00940 } 00941 else if (setting_keybind_step == KEYBIND_STEP_DONE && event->type == SDL_KEYDOWN) 00942 { 00943 setting_keybind_apply(list); 00944 } 00945 00946 return 1; 00947 } 00948 else if (text_input_string_flag && event->type == SDL_KEYDOWN) 00949 { 00950 if (setting_keybind_step == KEYBIND_STEP_COMMAND && text_input_handle(&event->key)) 00951 { 00952 return 1; 00953 } 00954 } 00955 else if (event->type == SDL_KEYDOWN && setting_keybind_action(event->key.keysym.sym, list)) 00956 { 00957 return 1; 00958 } 00959 } 00960 00961 /* Handle list events. */ 00962 if (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) 00963 { 00964 if (list_handle_keyboard(list, &event->key)) 00965 { 00966 return 1; 00967 } 00968 } 00969 else 00970 { 00971 if (list_handle_mouse(list, event->motion.x, event->motion.y, event)) 00972 { 00973 return 1; 00974 } 00975 } 00976 } 00977 00978 return -1; 00979 } 00980 00983 void settings_open() 00984 { 00985 popup_struct *popup; 00986 00987 /* Create the popup. */ 00988 popup = popup_create(BITMAP_POPUP); 00989 popup->draw_func = settings_popup_draw_func; 00990 popup->event_func = settings_popup_event_func; 00991 popup->destroy_callback_func = settings_popup_destroy_callback; 00992 popup->draw_func_post = settings_popup_draw_func_post; 00993 setting_type = SETTING_TYPE_NONE; 00994 00995 button_create(&button_password); 00996 00997 button_selected = GameStatus == GAME_STATUS_PLAY ? BUTTON_BACK : BUTTON_SETTINGS; 00998 }
1.7.4